Saltar a contenido

ADR 008: Módulo booking (dominio genérico)

Estado

Aceptado — 2026-06 · Diseño de ingeniería (sin implementación aún)

Relacionado con ADR 007, ADR 006 y ADR 004 (módulo en panel panel).

Contexto

El plugin booking existe como scaffold: fixtures en memoria, solo endpoints GET, conceptos residuales del prototipo histórico (court, cancha). No se replica el dominio del prototipo UnoSport Club.

El diseño objetivo es un modelo genérico multi-recurso: cualquier cosa reservable (espacio, persona, equipo) sin acoplar a deporte.

Decisión

Modelo de dominio

Entidad Rol
Resource Recurso reservable. type: space, person, equipment, … Atributos flexibles en JSON.
Slot Ventana temporal sobre un recurso: starts_at, ends_at, status (open, held, booked).
Booking Reserva confirmada: referencia a slot(s), client_ref, status, metadata.
AvailabilityQuery VO de consulta (rango de fechas, filtros por resource_type).

Leyenda: Modelo ERD del plugin Independiente booking. Estado: Diseño.

erDiagram
  Resource ||--o{ Slot : has
  Slot ||--o| Booking : reserves
  Booking }o--|| ClientRef : for
  Resource {
    uuid id
    string type
    string name
    json attributes
  }
  Slot {
    uuid id
    datetime starts_at
    datetime ends_at
    string status
  }
  Booking {
    uuid id
    string status
    string client_ref
  }

Tablas PostgreSQL (prefijo booking_)

Tabla Campos clave
booking_resources id, type, name, attributes (JSONB), created_at
booking_slots id, resource_id, starts_at, ends_at, status
booking_bookings id, slot_id, client_ref, status, metadata (JSONB), idempotency_key

Migraciones en plugins/booking/alembic/. Ver ADR 007.

API REST (/api/v1/booking/)

Método Ruta Uso
GET /resources Listar recursos (?type=)
GET /slots Disponibilidad en rango (?from=&to=&resource_id=)
POST /bookings Crear reserva; header Idempotency-Key
GET /bookings Listar (?status=&from=)
GET /bookings/{id} Detalle
PATCH /bookings/{id}/cancel Cancelar
GET /agenda Vista agenda agregada (solo lectura)

Errores vía ApiError:

Código HTTP
SLOT_UNAVAILABLE 409
BOOKING_NOT_FOUND 404
INVALID_RANGE 422
IDEMPOTENCY_REPLAY 200 (misma respuesta cacheada)

Leyenda: Flujo UI → API → PG para consulta y alta de reserva. Estado: Diseño.

sequenceDiagram
  participant UI as ModuleScreen
  participant API as FastAPI /api/v1/booking
  participant DB as PostgreSQL

  UI->>API: GET /api/v1/booking/slots?from&to
  API->>DB: query slots open
  API-->>UI: slots disponibles
  UI->>API: POST /api/v1/booking/bookings + Idempotency-Key
  API->>DB: transacción hold + confirm
  API-->>UI: booking creado

Leyenda: Secuencia de creación de reserva con idempotencia (ADR 009). Estado: Diseño.

UI CUS

  • Panel panel, módulo booking en plugins/booking/cortex_plugin_booking/ui/.
  • Renombrar en manifests/dashboards: courtresource; pantallas: Inicio, Agenda, Reservas, Recursos.
  • Widgets: api-table para listados, json-form para alta de reserva; sin páginas React nuevas.

Tools MCP (ADR 006)

Tool Descripción
booking.check_availability Equivalente a GET /slots
booking.create Equivalente a POST /bookings
booking.cancel Equivalente a PATCH /bookings/{id}/cancel
booking.list_agenda Equivalente a GET /agenda

Integración con otros plugins (futuro)

Plugin Contrato
clients client_ref resuelve contra GET /api/v1/clients/{id}
payments / pricing Evento booking.confirmed (hook/documentar; sin implementar en fase 1)

Leyenda: Plugin Independiente booking dentro del panel operativo; MCP reutiliza REST. Estado: Diseño.

flowchart TB
  subgraph panelOperativo [Panel panel]
    Shell[PanelShell]
    BKmod[booking module]
  end
  subgraph booking_api [cortex_plugin_booking]
    REST["/api/v1/booking/*"]
    MCP[McpToolRegistry]
    PG[(booking_* tables)]
  end
  Shell --> BKmod
  BKmod --> REST
  MCP --> REST
  REST --> PG

Leyenda: Integración panel CUS, API booking y persistencia. Estado: Diseño (scaffold sin PG).

Migración desde scaffold actual

  1. Implementar modelos + Alembic (ADR 007).
  2. Sustituir _STORE por repositorios async.
  3. Seed dev desde fixtures/ opcional.
  4. Actualizar JSON CUS con paths y columnas del modelo genérico.

Consecuencias

  • Positivas: dominio portable, desacoplado del prototipo, listo para MCP y multi-tenant real.
  • Negativas: breaking change respecto a fixtures actuales; tests deben migrar a PG (testcontainers o BD efímera).

Referencias