05 — Modelo de datos — VOLTA
1. Visión general
Dominio mínimo de club L1:
| Entidad | Propósito |
|---|---|
| User | Identidad coach (rol COACH) |
| ClassRequest | Solicitud de plaza con preferencias y estado |
Base: PostgreSQL (Neon) · ORM: Prisma · IDs: cuid().
2. Enums
Role
| Valor | Descripción |
|---|---|
COACH | Operador del inbox; único rol autenticado v1 |
RequestStatus
| Valor | Descripción |
|---|---|
NEW | Recién creada por el form público |
CONTACTED | Coach ha iniciado contacto |
CONFIRMED | Plaza confirmada |
CANCELLED | Anulada |
ClassType
| Valor | Descripción |
|---|---|
HIIT | Entrenamiento alta intensidad |
YOGA | Yoga / movilidad |
BASKET | Baloncesto / cancha |
KIDS | Clase infantil |
OPEN | Cancha 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
| Campo | Tipo | Constraints |
|---|---|---|
| id | String | PK, cuid |
| String | unique | |
| passwordHash | String | bcrypt |
| name | String | |
| role | Role | default COACH |
| createdAt | DateTime | default now |
| updatedAt | DateTime | updatedAt |
ClassRequest
| Campo | Tipo | Constraints |
|---|---|---|
| id | String | PK, cuid |
| code | String | unique, formato VO-MMDD-XXX |
| fullName | String | |
| String | ||
| phone | String? | opcional |
| classType | ClassType | enum |
| preferredDay | String | fecha preferida (ISO date string) |
| preferredSlot | String | franja / hora preferida |
| notes | String | default "" |
| status | RequestStatus | default NEW |
| createdAt / updatedAt | DateTime |
5. Reglas de integridad y negocio
| Regla | Implementación |
|---|---|
| Create público | POST /api/requests sin guard |
| List/detail/status | JwtAuthGuard → 401 sin token |
| Código único | code unique; generación VO-MMDD- + random 100–999 |
| Status default | NEW al crear |
| Password | Nunca en claro; solo passwordHash |
| Notas | Coalesce a "" si omitidas |
| Orden listado | createdAt desc |
6. Contratos API (resumen)
POST /api/requests (público)
Body
| Campo | Tipo | Req |
|---|---|---|
| fullName | string | sí |
| string | sí | |
| phone | string | no |
| classType | ClassType | sí |
| preferredDay | string | sí |
| preferredSlot | string | sí |
| notes | string | no |
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)
| Entidad | Datos |
|---|---|
| COACH | Nora Beltrán · coach@volta.club · password123 |
| VO-0808-01 | Marc Solé · HIIT · NEW · 19:00 |
| VO-0808-02 | Laia Puig · YOGA · CONTACTED · 10:00 |
| VO-0808-03 | Eric Font · BASKET · NEW · 18:00 |
| VO-0808-04 | Sofía Rami · KIDS · CONFIRMED · 17:00 |
| VO-0808-05 | Pol 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)
| Cambio | Nivel |
|---|---|
| FK coachId en ClassRequest (asignación) | L2 |
| Tabla Class / Schedule con aforo | L2–L3 |
| User MEMBER con historial | L2 |
| Soft delete / auditoría | L2 |