04 — Flujos de usuario — VOLTA
Convenciones
- Actor: Guest | COACH
- Éxito: resultado observable
- Errores: UI + código HTTP cuando aplica
F1 — Descubrimiento (Guest)
Home (/) → anclas #clases / #horarios
→ CTA "Quiero una plaza" | "Apuntarme"
→ /apuntarme
→ (nav) "Coach" → /login
| Paso | Acción | Sistema |
|---|
| 1 | Lee valor, clases y horarios teaser | Render estático |
| 2 | Click CTA plaza | Router → /apuntarme |
| 3 | Opcional: coach entra al panel | Router → /login |
Éxito: form de plaza o login visible.
F2 — Solicitar plaza (Guest, público)
/apuntarme → validación cliente
→ POST /api/requests { fullName, email, phone?, classType, preferredDay, preferredSlot, notes? }
→ 201 ClassRequest { code, ... }
→ /ok (state o query con code)
| Campo | Validación cliente (mín.) | API |
|---|
| fullName | required, min 2 | @MinLength(2) |
| email | required, email | @IsEmail() |
| phone | optional | @IsOptional() |
| classType | enum HIIT…OPEN | @IsEnum(ClassType) |
| preferredDay | required (date string) | @MinLength(4) |
| preferredSlot | required | @MinLength(2) |
| notes | optional | default "" |
Éxito: registro status=NEW, código VO-MMDD-XXX, pantalla success.
Errores:
| Caso | Comportamiento |
|---|
| Validación DTO | 400 + mensaje form |
| Red caída | Error de red en UI form |
| Email mal formado | 400 |
No hay cuenta de socio en v1.
F3 — Success (Guest)
/ok → muestra copy de confirmación + code
→ CTA volver home o "seguir explorando"
| Paso | Acción | Sistema |
|---|
| 1 | Lee acuse | UI |
| 2 | Copia mental del código | — |
| 3 | Espera contacto del club | Fuera de app (WhatsApp/llamada) |
F4 — Login JWT (COACH)
/login → POST /api/auth/login { email, password }
→ 200 { accessToken, user } → localStorage → /inbox
→ 401 → mensaje error en form
| Campo | Validación cliente | API |
|---|
| email | required, email | @IsEmail() |
| password | required, min 6 | @MinLength(6) |
Éxito: token guardado; user role=COACH, nombre Nora Beltrán.
Errores:
| Caso | Comportamiento |
|---|
| Credenciales inválidas | 401 + mensaje |
| Red caída | Error de red en UI |
| Token caducado en inbox | 401 en GET → re-login |
F5 — Inbox + stats (COACH)
/inbox (token en cliente)
→ GET /api/requests
→ GET /api/requests/stats/summary
→ Render cards + métricas
| Caso | Comportamiento |
|---|
| Lista con items | Cards: code, nombre, classType, status, preferencias |
| Lista vacía | Empty state (sin CTA público desde inbox) |
| Fallo red / 401 | Error + reintentar / re-login |
| Stats | total, open (NEW+CONTACTED), byStatus |
F6 — Detalle y cambio de estado (COACH)
/inbox/:id
→ GET /api/requests/:id
→ UI: datos contacto + preferencias + notas
→ PATCH /api/requests/:id/status { status }
→ 200 ClassRequest actualizado
Transiciones permitidas (modelo v1)
Cualquier status del enum puede asignarse vía PATCH (máquina simple L1):
| Desde | Hacia típico | Intención |
|---|
| NEW | CONTACTED | Coach inició contacto |
| CONTACTED | CONFIRMED | Plaza cerrada |
| CONTACTED | CANCELLED | No contesta / sin hueco |
| NEW | CANCELLED | Spam / error |
| CONFIRMED | CANCELLED | Baja posterior |
| * | * | Corrección operativa |
Éxito: badge de estado actualizado; lista refleja al volver.
Errores: 404 id inexistente; 401 sin token; 400 status inválido.
F7 — Logout (COACH)
Click "Salir" → limpia localStorage (token + user) → /login
Matriz de errores global
| Código | Cuándo | UI |
|---|
| 400 | DTO inválido | Mensaje campo / genérico |
| 401 | Sin/mal token | Re-login |
| 404 | id no existe | Mensaje detalle |
| 5xx / network | API caída | Empty error + retry |
Flujos fuera de alcance v1
- Registro de socio
- Recuperación de password
- Notificación email automática al coach
- Filtros multi-criterio en inbox
- Asignación multi-coach