COMAL · 05-data-model.md · 6 de 21

En esta página Diagrama ER simplificado 0%

05 — Modelo de datos · COMAL

Diagrama ER simplificado

User 1──* Membership
User 1──* Booking
User *──* Kitchen (via KitchenStaff for operators)
Kitchen 1──* Station
Kitchen 1──* KitchenEquipment
Kitchen 1──* KitchenCertification
Station 1──* SlotLock / AvailabilityRule
Booking *──1 Station
Booking 1──1 Payment
Booking 1──0..1 CheckIn
Booking 1──0..1 Review
Booking 1──0..* BookingEvent (audit)

Entidades principales

User

CampoTipoNotas
iduuid PK
emailcitext unique
password_hashtext nullnull si solo OAuth
nametext
phonetext nullE.164
role_defaultenumcook, operator, admin
localetextes-ES
created_at / updated_attimestamptz
deleted_attimestamptz nullsoft delete

Kitchen

CampoTipoNotas
iduuid PK
slugtext unique
nametext
descriptiontext
address_line / city / postal / countrytext
lat / lngnumericíndice geo
timezonetextEurope/Madrid
base_price_centsintpor hora
min_hoursintdefault 2
cancellation_policyjsonb
statusenumdraft, published, suspended
owner_user_iduuid FK

Station

CampoTipo
iduuid
kitchen_iduuid FK
nametext
capacity_notestext
is_activebool

Equipment (catálogo) + KitchenEquipment (M2M)

code, label_es, icon_key

Certification

type, issuer, valid_until, document_url, verification_status

Booking

CampoTipoNotas
iduuid
public_codetextCOM-XXXX human
cook_user_iduuid
station_iduuid
starts_at / ends_attimestamptzexclusion constraint
statusenumpending_payment, confirmed, checked_in, completed, cancelled, no_show
price_breakdownjsonb
total_centsint
currencychar(3)EUR
hold_expires_attimestamptz null
cancelled_attimestamptz null

Constraint: EXCLUDE USING gist (station_id WITH =, tstzrange(starts_at, ends_at) WITH &&) WHERE (status IN ('confirmed','checked_in','completed','pending_payment'))

Payment

provider, provider_ref, amount_cents, status, raw_events jsonb

CheckIn

booking_id, method (qr|pin|manual), pin_hash, checked_in_at, checked_in_by

Membership

user_id, plan (base|pro), stripe_subscription_id, status, current_period_end

Review

booking_id unique, rating 1–5, body, published

Audit / BookingEvent

booking_id, actor_id, type, payload, created_at

Índices recomendados

  • bookings (cook_user_id, starts_at desc)
  • bookings gist exclusion (arriba)
  • kitchens (city), kitchens gist geo
  • kitchens (status) where published

Privacidad y retención

DatoClasificaciónRetención
PII usuarioPersonalHasta borrado + 30 días backup
PagosSensible financieroSegún obligación fiscal (ES ~5–6 años refs)
Logs accesoTécnico12 meses
Certificados docsPartnerMientras kitchen activa + 1 año

Cifrado: TLS en tránsito; campo phone opcional encrypted at rest; documentos en bucket privado firmado.

Multitenancy

  • Lógico por kitchen_id para operadores
  • Admin COMAL cross-tenant
  • No shared DB por tenant en v1 (single DB, RLS por rol)

Eventos de dominio

UserRegistered KitchenPublished BookingHoldCreated BookingConfirmed PaymentCaptured BookingCancelled CheckInCompleted ReviewSubmitted MembershipStarted