VOLTA · 05-data-model.md · 7 de 22

En esta página 1. Visión general 0%

05 — Modelo de datos — VOLTA

1. Visión general

Dominio mínimo de club L1:

EntidadPropósito
UserIdentidad coach (rol COACH)
ClassRequestSolicitud de plaza con preferencias y estado

Base: PostgreSQL (Neon) · ORM: Prisma · IDs: cuid().

2. Enums

Role

ValorDescripción
COACHOperador del inbox; único rol autenticado v1

RequestStatus

ValorDescripción
NEWRecién creada por el form público
CONTACTEDCoach ha iniciado contacto
CONFIRMEDPlaza confirmada
CANCELLEDAnulada

ClassType

ValorDescripción
HIITEntrenamiento alta intensidad
YOGAYoga / movilidad
BASKETBaloncesto / cancha
KIDSClase infantil
OPENCancha abierta / libre

3. Diagrama ER (texto)

User
  id, email, passwordHash, name, role(COACH)
  createdAt, updatedAt

ClassRequest
  id, code (unique)
  fullName, email, phone?
  classType, preferredDay, preferredSlot, notes
  status (default NEW)
  createdAt, updatedAt

No hay FK entre ClassRequest y User en v1: el form es anónimo (sin cuenta). El coach opera sobre el conjunto global de solicitudes.

4. Tablas / modelos Prisma

User

CampoTipoConstraints
idStringPK, cuid
emailStringunique
passwordHashStringbcrypt
nameString
roleRoledefault COACH
createdAtDateTimedefault now
updatedAtDateTimeupdatedAt

ClassRequest

CampoTipoConstraints
idStringPK, cuid
codeStringunique, formato VO-MMDD-XXX
fullNameString
emailString
phoneString?opcional
classTypeClassTypeenum
preferredDayStringfecha preferida (ISO date string)
preferredSlotStringfranja / hora preferida
notesStringdefault ""
statusRequestStatusdefault NEW
createdAt / updatedAtDateTime

5. Reglas de integridad y negocio

ReglaImplementación
Create públicoPOST /api/requests sin guard
List/detail/statusJwtAuthGuard → 401 sin token
Código únicocode unique; generación VO-MMDD- + random 100–999
Status defaultNEW al crear
PasswordNunca en claro; solo passwordHash
NotasCoalesce a "" si omitidas
Orden listadocreatedAt desc

6. Contratos API (resumen)

POST /api/requests (público)

Body

CampoTipoReq
fullNamestring
emailstring
phonestringno
classTypeClassType
preferredDaystring
preferredSlotstring
notesstringno

Response 201: ClassRequest completo.

POST /api/auth/login

Body: { email, password }
Response 200: { accessToken, user: { id, email, name, role } }

GET /api/requests (JWT)

Array ClassRequest ordenado por createdAt desc.

GET /api/requests/stats/summary (JWT)

{
  "total": 5,
  "open": 3,
  "byStatus": {
    "NEW": 2,
    "CONTACTED": 1,
    "CONFIRMED": 1,
    "CANCELLED": 1
  }
}

open = NEW + CONTACTED.

GET /api/requests/:id (JWT)

ClassRequest o 404.

PATCH /api/requests/:id/status (JWT)

Body: { status: RequestStatus }
Response: ClassRequest actualizado.

7. Seed de referencia (2026-08-08)

EntidadDatos
COACHNora Beltrán · coach@volta.club · password123
VO-0808-01Marc Solé · HIIT · NEW · 19:00
VO-0808-02Laia Puig · YOGA · CONTACTED · 10:00
VO-0808-03Eric Font · BASKET · NEW · 18:00
VO-0808-04Sofía Rami · KIDS · CONFIRMED · 17:00
VO-0808-05Pol Serra · OPEN · CANCELLED · 20:00

El sufijo de fecha del código de seed es representativo del día del caso; la generación runtime usa la fecha del servidor.

8. Evolución posible (no implementada)

CambioNivel
FK coachId en ClassRequest (asignación)L2
Tabla Class / Schedule con aforoL2–L3
User MEMBER con historialL2
Soft delete / auditoríaL2