Investigación y documentación

Documentación · VOLTA

22 archivos markdown del case de estudio (producto, UX research, IA, flujos, design system, handoff…).

En esta página Day brief — 2026-08-08 — ALS-2 0%

Day brief — 2026-08-08 — ALS-2

1. LOAD — restricciones del día

EjeDecisiónMotivo (diversidad)
ComplejidadNivel 1Tras SURCO (L2 agro multi-rol) se baja a L1 compacto: un rol autenticado + flujo público de solicitud. Craft no baja (D-P0-01).
SectorFitness comunitario / club de barrioNo usado en la serie (COMAL cocina, ATRIO museo, MERIDIANA clínica, SENDA mayores, FIRME legal, TROCHA logística, CORREA mascotas, SURCO agro).
Tipo de productoWeb club + solicitud de plaza + panel coach JWTCara pública + lead/request + inbox ops; no marketplace, no ERP, no flota.
AuthJWT coach (rol COACH)Directiva D-P1-05: panel no abierto; solicitud pública sin cuenta.
Craft mínimo≥ SURCO densificado en docs + PaperL1 = menos módulos, no menos profundidad.
Cierre§1.1 completo en una iteraciónDocs + Paper + app + Neon + smoke; sin “próximos pasos del L1 del día”.
Puerto API3008Evitar colisión con SURCO (3007) y anteriores.
IDAnti-patrónMitigación hoy
AP-thin-docsDocs de 1–2 líneasSuite 00–20 con tablas, AC y criterios de aceptación
AP-generic-uiUI “SaaS genérico” / “básica porque L1”Palette chalk × ink × lime; Syne + Work Sans
AP-no-authPanel sin loginJWT obligatorio en GET/PATCH requests
AP-marketplace-copyLógica de marketplace / checkoutNo catálogo de pagos, no ratings, no matching multi-proveedor
AP-fake-researchEstadísticas inventadas como primariasSolo hipótesis y supuestos etiquetados
AP-open-debtBacklog de features del L1 del díaVertical slice cerrado: home, join, success, login, inbox, detail
AP-canvas-chaosPaper sin bandas §§1 UX · §2 DS+Public · §3 Coach · §4 Mobile · §5 States
AP-agro-logistics-legalReutilizar dominio de días previosFitness club de barrio; ClassRequest + ClassType

Barra de calidad actual (ratchet)

  • Paper: bandas §1–§5, ≥8 artboards UX densos + DS + público + coach + mobile + states.
  • Angular alineado a tokens (chalk/ink/lime; no default Tailwind genérico).
  • API Nest + Prisma + Neon con seed demo usable (5 ClassRequest + coach).
  • Smoke: POST público request + login coach + list + patch status; ng build o serve OK.
  • Docs en español, profundidad tipo portfolio (no stubs).

2. BRIEF — concepto del día

CampoValor
NombreVOLTA
Eslogan”Tu plaza en la cancha.”
Una fraseWeb del club de barrio para apuntarse a clases y panel JWT del coach que gestiona solicitudes de plaza.
TipoWeb club + solicitud pública + inbox coach — Nivel 1
RolesPúblico (sin cuenta) · COACH (Nora Beltrán)
DominioUser (COACH) + ClassRequest (NEW | CONTACTED | CONFIRMED | CANCELLED) + ClassType HIIT | YOGA | BASKET | KIDS | OPEN
EstiloChalk #F7F7F2 × Ink #0B0B0B × Lime #C6F23A × muted #5C5C58 × border #E2E2DC
TipoSyne (display) + Work Sans (UI)
StackAngular + NestJS + Prisma + Neon + Tailwind + JWT
Paperhttps://app.paper.design/file/01KZG2VRQFF2QF0PRDB10D4AG7
Neondelicate-mountain-11765167 · API :3008 · Web :4200
App/Users/cristian/orca/volta-app/ · GitHub Criscode2022/volta-app (puede estar pendiente de push)

Por qué L1 fitness (y no otra cosa)

  1. Diversidad de sector: la serie no había tocado club deportivo / fitness comunitario.
  2. Complejidad L1 justa: un rol autenticado, entidad core con máquina de estados, form público y panel ops — vertical slice denso sin multi-rol ni multi-tenant.
  3. Diferenciación vs CORREA: CORREA es marketplace B2C con reservas; VOLTA es lead de plaza del propio club (no matching de terceros).
  4. Diferenciación vs SURCO: SURCO es tool multi-rol de finca; VOLTA es web de club + inbox de solicitudes.
  5. Metáfora de marca: volta = vuelta / vuelta a la cancha; promesa de hueco real en el grupo, no de “app fitness genérica”.

Must-have del día (alcance L1)

#EntregaCriterio done
1Home marketingHero real, clases, horarios teaser, CTA apuntarme, footer demo
2Formulario públicaPOST /api/requests sin auth; validación campos
3SuccessConfirmación + código VO-…
4Login JWT coachcoach@volta.club / password123
5Inbox + statsLista + summary; chips de estado
6Detalle + PATCH statusNEW → CONTACTED → CONFIRMED / CANCELLED
7Empty / errorSin solicitudes; fallo de red en inbox
8Paper §1–§5UX process + DS + público + coach + mobile + states
9Docs 00–20 + README + executivePortfolio ES, sin stubs

Explicitamente fuera de alcance (no son deuda del día)

  • Pagos / cuotas / Stripe
  • Calendario de plazas en tiempo real / aforo live
  • App nativa / wearables
  • Multi-coach / multi-sede / multi-tenant
  • Notificaciones email/SMS/WhatsApp automáticas
  • Marketplace de entrenadores externos
  • Perfil de socio completo / CRM pesado

3. Directivas activas aplicadas

IDAplicación en VOLTA
D-P0-01L1 no reduce craft ni profundidad de docs
D-P0-02Hi-fi con media real (assets/hero.jpg), microcopy club
D-P0-03Angular + Nest + Neon + Tailwind + repo app
D-P0-04Canvas Paper en bandas §1–§5 con labels
D-P0-05Hero fotorrealista en case y app
D-P0-06Cierre §1.1 sin backlog del alcance L1
D-P1-01≥8 artboards UX en Paper (stakeholders → datos)
D-P1-02Tokens chalk/ink/lime en Angular
D-P1-03apps/api + apps/web independientes
D-P1-05JWT en GET/PATCH requests coach
D-P1-06Smoke public POST + login + list + patch

4. Cuentas demo

RolNombreEmailPassword
COACHNora Beltráncoach@volta.clubpassword123

Seed de referencia: 5 ClassRequest con códigos VO-0808-0105 (HIIT NEW, YOGA CONTACTED, BASKET NEW, KIDS CONFIRMED, OPEN CANCELLED).

Supuestos (no investigación primaria)

  • Clubs de barrio coordinan listas de espera y plazas por WhatsApp y papel en el mostrador.
  • El coach necesita un inbox ordenado, no un ERP de socios.
  • El visitante quiere pedir plaza sin crear cuenta ni app.

5. Criterio de cierre del día

  • Brief de diversidad y anti-patrones documentado
  • Producto definido (no marketplace, no agro, no logistics)
  • Implementación runnable API :3008 / web :4200
  • Documentación portfolio 00–20 + presentation + README
  • Paper file enlazado y referenciado por bandas
  • Hipótesis vs investigación marcadas (sin stats falsas)

Estado del brief: listo para EXECUTE y entrega de caso.

00-paper-reference.md

Abrir documento

Referencia Paper — VOLTA

CampoValor
File ID01KZG2VRQFF2QF0PRDB10D4AG7
URLhttps://app.paper.design/file/01KZG2VRQFF2QF0PRDB10D4AG7
NombreVOLTA — Daily UX 2026-08-08
ProductoWeb club + solicitud de plaza + panel coach JWT (L1)
Artboards~22 (+ labels de banda)
Bandas§1 UX · §2 Design + Public · §3 Coach · §4 Mobile · §5 States
Idioma UIes-ES
Mediaassets/hero.jpg (cancha / club de barrio)

1. Mapa de canvas (bandas jerárquicas)

§BandaPropósitoArtboards clave
1UX PROCESSInvestigación y modelo de servicio (densidad visual)Cover, Stakeholders, Personas, JTBD, Journey, Blueprint, IA, Datos
2DESIGN + PUBLICSistema visual y cara públicaDesign System, Home, Join form, Success
3COACHFlujos autenticados desktop/tabletLogin, Inbox, Request detail
4MOBILEMóvil visitante y coach en vestuarioJoin / Inbox mobile
5STATESResiliencia UIEmpty inbox, Error red

Layout canvas (referencia): origen (0,0) · gaps ~80px · bandas Y orientativas: UX ~100 / Design ~2180 / Coach ~3980 / Mobile ~4880 / States ~5680.


2. Inventario de artboards

§1 — UX PROCESS

LabelNombreContenido
1-0§1 UX PROCESSEtiqueta de banda
2-0UX-00 CoverPortada VOLTA, eslogan, fecha 2026-08-08, L1 fitness, roles, dark ink + lime
3-0UX-01 StakeholdersMapa interés/influencia: socio potencial, coach, familia, sede, ayuntamiento (bajo)
4-0UX-02 PersonasMarc Solé (visitante) · Nora Beltrán (COACH) — goals, pains, quote
5-0UX-03 JTBDJob principal + funcional/emocional/social + MoSCoW / stories Must
6-0UX-04 Journey5 fases visitante: descubre → elige clase → pide plaza → espera contacto → confirma
7-0UX-05 BlueprintFrontstage web · backstage coach · sistemas · fallos red/estado
8-0UX-06 IASitemap público/auth; navegación y permisos
9-0UX-07 DatosERD: User, ClassRequest + enums Role, RequestStatus, ClassType

§2 — DESIGN + PUBLIC

LabelNombreContenido
A-0§2 DESIGN + PUBLICEtiqueta de banda
B-000 Design SystemColor chalk/ink/lime, tipo Syne+Work Sans, botones, badges estado, cards
C-001 HomeNav, hero + media, clases, horarios teaser, CTAs, footer demo
D-002 JoinForm solicitud: nombre, email, teléfono, tipo, día, franja, notas
E-003 SuccessConfirmación + código VO-… + próximos pasos

§3 — COACH (desktop)

LabelNombreContenido
F-0§3 COACHEtiqueta de banda
G-004 LoginSplit dark/form; email/password; contexto panel coach
H-005 InboxLista + stats summary; badge COACH; filtros visuales por estado
I-006 DetailCódigo VO-…, contacto, clase, preferencias, chips estado, acciones

§4 — MOBILE

LabelNombreContenido
J-0§4 MOBILEEtiqueta de banda
K-007 Mobile Join / InboxVista ~390px; touch targets ≥44px

§5 — STATES

LabelNombreContenido
L-0§5 STATESEtiqueta de banda
M-008 EmptyInbox sin solicitudes; copy orientativo
N-009 ErrorFallo de carga / red; mensaje accionable + reintento

3. Checklist de densidad (anti thin-frames)

Criterio§1 UX§2 DS/Public§3–4 Coach§5 States
Jerarquía tipográfica visible
Microcopy real (no lorem)
Tokens de color aplicados
Datos de seed creíblesPersonasDemo emailsCódigos VO-…Empty realista
Media / iconografíaCoverHeroBadgesAlertas

4. Mapeo Paper → Angular

ArtboardRuta appComponente
C-0 Home/HomePage
D-0 Join/apuntarmeJoinPage
E-0 Success/okSuccessPage
G-0 Login/loginLoginPage
H-0 Inbox/inboxInboxPage
I-0 Detail/inbox/:idRequestDetailPage
K-0 Mobilemismas rutas, viewport estrechoresponsive
M-0 Empty/inbox (0 items)empty state en lista
N-0 Errorinbox / detallemensajes error en páginas

5. Tokens de diseño en Paper

TokenValorUso
Chalk / bg#F7F7F2Fondo de página
Surface#FFFFFFCards, header
Ink#0B0B0BPrimary dark, CTAs, texto fuerte
Lime#C6F23AAcento marca, highlights, CTAs lime
Lime soft#EAF8B8Fondos suaves / badges
Lime strong#A8D420Hover lime
Muted#5C5C58Texto secundario
Border#E2E2DCBordes de card y inputs
DisplaySyneH1–H2, logo wordmark
UIWork SansBody, labels, botones

Nota implementación: tailwind.config.js de la app usa los mismos hex de marca; primary mapea a ink para CTAs dark; lime para acentos.


6. Enlaces

01-project-definition.md

Abrir documento

01 — Definición de proyecto — VOLTA

1. Identidad

CampoValor
NombreVOLTA
SignificadoVuelta a la cancha: el hueco que te espera en el grupo del barrio
Eslogan”Tu plaza en la cancha.”
Una fraseWeb del club de barrio para pedir plaza en clases y panel del coach que gestiona esas solicitudes.
SectorFitness comunitario / club de barrio
TipoWeb club + solicitud pública + inbox coach JWT — Nivel 1
PlataformaWeb responsive (móvil-first visitante + desktop coach)
Mercado demoEspaña (club de barrio, Valencia en copy)
Idiomaes-ES
Fecha caso2026-08-08

2. Problema

Principal (hipótesis de diseño)

Los clubs de barrio gestionan listas de plaza por WhatsApp, notas en el mostrador y mensajes perdidos. El visitante no sabe si su mensaje llegó; el coach no tiene un inbox con estado (nuevo / contactado / confirmado).

Secundarios

ProblemaQuién lo sufreEfecto
“Apúntame al HIIT del jueves” en hilosVisitanteNo hay acuse ni código de referencia
Listas en papel / Excel localCoachDifícil priorizar contactos del día
Sin tipo de clase ni franja preferidaAmbosLlamadas de ida y vuelta
Sin máquina de estadosCoachSe pierde quién ya fue contactado

Supuestos (no investigación primaria propia)

  • S1: Clubs pequeños–medianos no necesitan un CRM enterprise; sí un inbox de solicitudes con estado.
  • S2: El visitante prefiere un form de 1 pantalla a crear cuenta o descargar app.
  • S3: El valor inmediato está en captura estructurada + pipeline de estado, no en aforo live ni pagos.

Hipótesis de producto

IDHipótesisSeñal de validación (futura)
H1Un form público con tipo de clase y franja reduce mensajes ambiguos↓ “¿a qué hora?” post-solicitud
H2Inbox con estados NEW→CONTACTED→CONFIRMED acelera el cierre de plazaMediana tiempo NEW→CONFIRMED
H3Códigos cortos VO-MMDD-XXX facilitan referencia oralUso del código en WhatsApp/llamada

No se afirman estadísticas de mercado inventadas. Todo lo anterior es razonamiento de diseño etiquetado.

3. Propuesta de valor

ParaValor
Visitante (Marc)Pide plaza en 1 minuto: clase, día y franja sin cuenta.
Coach (Nora)Ve solicitudes nuevas, marca contacto y confirma o cancela.
ClubCanal digital mínimo viable sin marketplace ni ERP de socios.

No es VOLTA

ExcluidoPor qué
Marketplace de entrenadores o clubsEso sería CORREA-like; no es el club propio
Tool de finca / logística / legalDominios de otros días de la serie
SaaS multi-sede con billingComplejidad L3/L4
App fitness con wearables / planes IAFuera del job “plaza en la cancha”

4. Objetivos

Negocio / caso de estudio

  • Demostrar vertical slice L1 fitness con JWT coach y dominio ClassRequest.
  • Portfolio coherente: Paper + docs + app runnable.

Usuario

RolObjetivo medible en demo
VisitanteEnviar solicitud en < 2 min; ver código en success
CoachMarcar CONTACTED / CONFIRMED en < 3 taps desde el inbox

No objetivos v1 (explícitos)

  • Pagos y cuotas mensuales
  • Aforo en tiempo real por clase
  • Chat in-app
  • Multi-coach con permisos granulares
  • Export contable

5. Roles y permisos (resumen)

AcciónPúblicoCOACH
Ver home / clases
POST solicitudSí (mismo form)
Login JWTNo (no cuenta socio)
Listar solicitudesNo (401)
Ver stats summaryNo
Ver detalleNo
Cambiar statusNo

6. Métricas (modelo, no instrumentadas en v1 salvo base)

TipoMétricaDefinición
North StarSolicitudes CONFIRMED / semanaPlazas realmente cerradas
Activación1ª solicitud públicaPOST create
Ops% NEW contactadas en 24 hNEW → CONTACTED
CalidadTasa error API en create/list4xx/5xx
UXTiempo form completeMediana en analytics futuro

7. Alcance funcional v1 (L1)

MóduloIncluido
Home públicaHero, clases, horarios teaser, CTAs
SolicitudForm + POST /api/requests
SuccessCódigo + mensaje
AuthPOST /api/auth/login → JWT
InboxGET list, GET stats, GET by id, PATCH status
UI estadosLoading implícito, empty, error de red
Seed1 coach, 5 solicitudes

8. Criterios de aceptación de producto

  1. Un visitante puede enviar una solicitud sin autenticación y recibir un código VO-….
  2. Sin token, GET/PATCH /api/requests* responden 401.
  3. Un coach puede iniciar sesión y ver el inbox ordenado (createdAt desc) con stats.
  4. El detalle permite transicionar estados NEW | CONTACTED | CONFIRMED | CANCELLED.
  5. La home comunica club de barrio y plaza, no marketplace ni gym chain genérico.
  6. Tipos de clase soportados: HIIT, YOGA, BASKET, KIDS, OPEN.

9. Stack y artefactos

CapaDetalle
FrontendAngular + Tailwind · puerto 4200
BackendNestJS · puerto 3008
DBNeon PostgreSQL · Prisma · project delicate-mountain-11765167
AuthJWT (passport/strategy en API)
DiseñoPaper 01KZG2VRQFF2QF0PRDB10D4AG7
Repo app/Users/cristian/orca/volta-app/ · GitHub Criscode2022/volta-app

10. Riesgos y mitigaciones

RiesgoImpactoMitigación v1
Spam en form públicoInbox ruidosoValidación server; honeypot futuro L1+
Expectativa de aforo liveDecepciónCopy “solicitud”; coach confirma
Confundir con ClassPassExpectativa marketplaceMarca club único, no multi-sede
PII en solicitudesPrivacidadSolo coach autenticado lista; doc 11

11. Glosario

TérminoDefinición en VOLTA
PlazaHueco en una clase o cancha abierta del club
SolicitudClassRequest con preferencias y estado
CoachUsuario autenticado que opera el inbox
Código VO-Identificador corto oral (VO-0808-01)
OPENTipo de clase “cancha abierta” / libre

02-ux-research-strategy.md

Abrir documento

02 — Estrategia de investigación UX — VOLTA

Importante: este documento contiene artefactos de diseño y razonamiento secundario.
No hay entrevistas de campo primarias ni estadísticas inventadas presentadas como dato medido.
Etiquetas: [COMPROBADO] en producto, [SUPUESTO], [HIPÓTESIS], [DECISIÓN DE DISEÑO].

1. Objetivos de investigación (del caso)

ObjetivoMétodo en este casoSalida
Entender actores del club de barrioModelado de stakeholders + personas§3–4
Definir job principalJTBD + stories Must§5
Mapear fricción de plazaJourney + service blueprint§6–7
Traducir a requisitos L1Matriz hallazgo → requisito → feature§8

2. Fuentes y límites

Fuentes admisibles (secundarias / operativas)

  • Conocimiento general de clubs deportivos de barrio y gestión informal de listas.
  • Analogía operativa con captación de leads + inbox ops (serie daily: paneles JWT, estados).
  • Restricciones ALS-2 de diversidad (sector fitness libre; no marketplace; no agro/legal/logistics).

Límites éticos de verdad

ProhibidoPermitido
“El 68% de clubs usa solo WhatsApp” sin fuente[SUPUESTO] la coordinación informal es frecuente en clubs pequeños”
Citas de usuarios ficticios como entrevistas realesQuotes de persona etiquetadas como constructo de diseño
NPS inventadoHipótesis H1–H3 con métrica futura

3. Stakeholders

StakeholderInfluenciaInterésNecesidad principal
Socio potencial / visitanteBaja formalMuy altaPedir plaza sin fricción
Coach del club (COACH)AltaMuy altaInbox ordenado y estados
Familia (inscripción KIDS)MediaAltaDatos de contacto claros
Junta / dueño del clubAlta adopciónMediaMenos caos operativo
Ayuntamiento / instalacionesBaja en v1BajaFuera de producto
Apps marketplace fitnessCompetenciaNo copiar modelo multi-proveedor

Mapa de poder (resumen)

  • Decisor de adopción: coach / responsable del club.
  • Usuario frecuente captura: visitante (form) y coach (inbox diario).
  • Riesgo de rechazo: si el form pide más que un WhatsApp sin devolver acuse ni claridad de estado.

4. Personas

P1 — Marc Solé · Visitante / socio potencial

CampoDetalle
Edad / contexto~28 años; quiere HIIT o cancha por la tarde tras el trabajo
DigitalAlta; móvil-first; odia crear cuentas para “solo preguntar”
GoalsSaber que su plaza está pedida; recibir contacto del club
PainsMensajes sin respuesta; no sabe a quién escribir; horarios confusos
Quote de diseño“Dime la clase, el día y que alguien me conteste.”
Seed demomarc@example.com · solicitud HIIT VO-0808-01

Escenario: Entra en la web del club, elige HIIT 19:00, envía y guarda el código VO-.

P2 — Nora Beltrán · COACH

CampoDetalle
Edad / contexto~35 años; coach y cara del club de barrio
DigitalMedia–alta; usa móvil entre clases y desktop en la oficina
GoalsVer nuevas solicitudes, contactar, confirmar o cancelar plazas
PainsWhatsApp mezclado con personal; no sabe quién ya fue llamado
Quote de diseño“Si está en NEW, es mío. Si está CONFIRMED, hay plaza.”
Email democoach@volta.club

Escenario: Login → inbox → Marc NEW → CONTACTED → tras llamada CONFIRMED.

Anti-persona

QuiénPor qué no es target v1
Cadena de gimnasios multi-ciudad con CRM y billingNecesita multi-sede, cuotas, aforo live → L3/L4
Marketplace de coaches freelancersProducto tipo CORREA, no club propio

5. JTBD y user stories

Job principal (visitante)

Cuando quiero un hueco en una clase o cancha del club,
quiero enviar mis datos y preferencias en un solo paso,
para que el coach me contacte sin perder el mensaje en WhatsApp.

Job principal (coach)

Cuando llegan pedidos de plaza,
quiero verlos con estado y tipo de clase,
para contactar y confirmar sin Excel ni papel.

Jobs secundarios

JobRol
Ver cuántas abiertas (NEW+CONTACTED) hayCOACH
Referir una solicitud por código cortoAmbos
Cancelar si no hay hueco o no contestaCOACH

Stories Must (v1)

IDStoryAC
US1Como visitante, quiero un form con tipo de clase, día y franjaPOST 201 + redirect success
US2Como visitante, quiero un código de referenciacode visible en /ok
US3Como coach, quiero entrar con email/passwordJWT + redirect /inbox
US4Como coach, quiero listar solicitudes y statsGET list + summary
US5Como coach, quiero cambiar estadoPATCH status

MoSCoW (v1)

PrioridadÍtems
MustHome, join, success, login, inbox, detail, status, empty/error
ShouldLabels ES de ClassType y status; badges de color
CouldFiltro por status en UI; copy teléfono click-to-call
Won’tPagos, aforo live, multi-coach, notificaciones push

6. Journey (visitante → coach)

FaseActorAcciónTouchpointEmoción [HIPÓTESIS]
1 DescubrirMarcEntra a webHome heroCuriosidad
2 ElegirMarcMira clasesSección #clasesInterés
3 PedirMarcRellena form/apuntarmeEsperanza
4 AcuseMarcVe código/okAlivio
5 ContactoNoraVe NEW, llamaInbox + detalleControl
6 CierreNoraCONFIRMEDPATCHSatisfacción operativa

Momentos de verdad

  1. Form sin cuenta — si pide login, abandono alto [HIPÓTESIS].
  2. Código VO- — prueba social de “ha llegado”.
  3. Estado en inbox — evita re-contactar a quien ya está confirmado.

7. Service blueprint (resumen)

CapaElementos
Frontstage visitanteHome, form, success
Frontstage coachLogin, inbox, detail, botones estado
BackstageCoach llama/WhatsApp externo (fuera de app)
SistemasNest API, Prisma, Neon, JWT, Angular
SoportesSeed demo, Paper, docs
Fallos401 sin token; 404 id; red caída → UI error

8. Matriz hallazgo → requisito → feature

HallazgoTipoRequisitoFeature v1
Mensajes ambiguos sin clase/hora[SUPUESTO]Capturar ClassType + day + slotForm join
Sin acuse al visitante[HIPÓTESIS]Devolver códigoSuccess + code
Coach no sabe estado[SUPUESTO]Máquina de estadosRequestStatus
Panel abierto = riesgo PII[DECISIÓN]Auth JWTLogin + guards API
L1 compacto[DECISIÓN]Un rol COACHSin multi-rol

9. Preguntas abiertas (no bloquean v1)

IDPreguntaCómo se resolvería después
Q1¿Aforo real por franja?Integración calendario L2+
Q2¿Email automático al coach?Hook post-create L1+
Q3¿RGPD consent explícito en form?Checkbox + política L1+

10. Síntesis

VOLTA se diseña como canal de plaza del club, no como marketplace fitness.
La investigación del caso es constructiva y etiquetada: personas, JTBD y journey son artefactos de diseño; las métricas de validación quedan para uso real futuro.

03-information-architecture.md

Abrir documento

03 — Arquitectura de información — VOLTA

1. Principios de IA

PrincipioAplicación
Plaza primeroCTA dominante “Apuntarme” / “Quiero una plaza” en home
Público vs coachForm abierto; inbox solo autenticado
Pocos nivelesPúblico (3) + Coach (3) — profundidad máx. 2 clicks a detalle
Lenguaje de dominioPlaza, clase, franja, solicitud — no “ticket”, “lead CRM”, “order”
Código visibleVO-… en success e inbox para referencia oral

2. Sitemap

/                          Home (público)
/apuntarme                 Formulario de plaza (público)
/ok                        Success post-solicitud (público)
/login                     Login JWT coach
/inbox                     Lista + stats (auth COACH)
/inbox/:id                 Detalle + estado (auth COACH)
/**                        → redirect /

Árbol por audiencia

AudienciaNodos relevantes
VisitanteHome → Apuntarme → Ok
CoachLogin → Inbox → Detail
AmbosHome (coach link en nav)

3. Navegación

Pública

ElementoDestinoNotas
Wordmark VOLTA/Display Syne, extrabold
Clases#clasesAncla home
Horarios#horariosAncla home
Coach/loginEntrada panel
Apuntarme/apuntarmePrimary CTA (ink × lime text)

Coach (autenticado)

ElementoDestinoVisibilidad
Wordmark / Inbox/inboxCOACH
Badge rolCOACH
Nombre usuarioCOACH
Salirlimpia token → /loginCOACH
Card solicitud/inbox/:idCOACH
Volver (detalle)/inboxCOACH

No hay menú lateral multi-sección en v1 (evita IA de CRM).

4. Inventario de contenido

PantallaContenidos
HomeEyebrow “CLUB DE BARRIO · VALENCIA”, H1 eslogan, lead, CTAs, 3 stats teaser, hero img, grid clases, horarios, footer demo
JoinTítulo, campos form, submit, link atrás
SuccessMensaje OK, código, siguiente paso (te contactamos)
LoginTítulo panel coach, email, password, submit, error
InboxStats (total, open, byStatus), lista cards, empty, error
DetailMeta código/tipo, contacto, preferencias, notas, acciones estado

5. Taxonomía y etiquetas

RequestStatus

Status APILabel UISemántica
NEWNuevaAcaba de llegar; sin contacto
CONTACTEDContactadaCoach ha hablado / escrito
CONFIRMEDConfirmadaPlaza cerrada
CANCELLEDCanceladaSin hueco / desiste / no contesta

Orden de lista: por createdAt descendente (más reciente primero).

ClassType

APILabel UI sugeridoNotas
HIITHIITAlta intensidad
YOGAYogaSuave / movilidad
BASKETBasketCancha / equipo
KIDSKidsInfantil
OPENCancha abiertaLibre / OPEN

6. Modelo mental vs UI

Modelo mental del usuarioRepresentación
“Apuntarme al grupo”Form /apuntarme
“Me dieron un número de referencia”code VO-
“Lista del día de gente nueva”Inbox + badge NEW
“Ya le llamé”Status CONTACTED
“Tiene plaza”Status CONFIRMED

7. Rutas API alineadas a IA

UIAPI
Submit joinPOST /api/requests
LoginPOST /api/auth/login
Inbox listGET /api/requests
StatsGET /api/requests/stats/summary
DetailGET /api/requests/:id
Cambiar estadoPATCH /api/requests/:id/status

8. Decisiones de IA descartadas

IdeaPor qué no en L1
Área de socio con historialMulti-sesión y cuenta pública
Calendario semanal interactivoAforo live = L2+
Chat coach–socio in-appFuera job mínimo
Nested nav “CRM → Leads → …”Sobre-arquitectura

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
PasoAcciónSistema
1Lee valor, clases y horarios teaserRender estático
2Click CTA plazaRouter → /apuntarme
3Opcional: coach entra al panelRouter → /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)
CampoValidación cliente (mín.)API
fullNamerequired, min 2@MinLength(2)
emailrequired, email@IsEmail()
phoneoptional@IsOptional()
classTypeenum HIIT…OPEN@IsEnum(ClassType)
preferredDayrequired (date string)@MinLength(4)
preferredSlotrequired@MinLength(2)
notesoptionaldefault ""

Éxito: registro status=NEW, código VO-MMDD-XXX, pantalla success.
Errores:

CasoComportamiento
Validación DTO400 + mensaje form
Red caídaError de red en UI form
Email mal formado400

No hay cuenta de socio en v1.


F3 — Success (Guest)

/ok → muestra copy de confirmación + code
    → CTA volver home o "seguir explorando"
PasoAcciónSistema
1Lee acuseUI
2Copia mental del código
3Espera contacto del clubFuera 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
CampoValidación clienteAPI
emailrequired, email@IsEmail()
passwordrequired, min 6@MinLength(6)

Éxito: token guardado; user role=COACH, nombre Nora Beltrán.
Errores:

CasoComportamiento
Credenciales inválidas401 + mensaje
Red caídaError de red en UI
Token caducado en inbox401 en GET → re-login

F5 — Inbox + stats (COACH)

/inbox (token en cliente)
  → GET /api/requests
  → GET /api/requests/stats/summary
  → Render cards + métricas
CasoComportamiento
Lista con itemsCards: code, nombre, classType, status, preferencias
Lista vacíaEmpty state (sin CTA público desde inbox)
Fallo red / 401Error + reintentar / re-login
Statstotal, 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):

DesdeHacia típicoIntención
NEWCONTACTEDCoach inició contacto
CONTACTEDCONFIRMEDPlaza cerrada
CONTACTEDCANCELLEDNo contesta / sin hueco
NEWCANCELLEDSpam / error
CONFIRMEDCANCELLEDBaja 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ódigoCuándoUI
400DTO inválidoMensaje campo / genérico
401Sin/mal tokenRe-login
404id no existeMensaje detalle
5xx / networkAPI caídaEmpty 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

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

06 — Stack tecnológico — VOLTA

1. Visión

CapaTecnologíaNotas
FrontendAngular (standalone components)Puerto 4200
EstilosTailwind CSSTokens chalk/ink/lime
BackendNestJS (TypeScript)Puerto 3008, prefijo /api
ORMPrismaschema + migrate + seed
DBNeon PostgreSQL serverlessproject delicate-mountain-11765167
AuthJWT (passport strategy)Bearer header
DiseñoPaperfile 01KZG2VRQFF2QF0PRDB10D4AG7
Repo/Users/cristian/orca/volta-app/GitHub Criscode2022/volta-app

Stack fijo del cron: no se sustituye por React/Next/Firebase salvo excepción documentada.

2. Estructura monorepo app

volta-app/
├── apps/
│   ├── api/          # NestJS + Prisma
│   │   ├── prisma/
│   │   │   ├── schema.prisma
│   │   │   ├── seed.ts
│   │   │   └── migrations/
│   │   └── src/
│   │       ├── auth/
│   │       ├── requests/
│   │       ├── prisma/
│   │       └── main.ts
│   └── web/          # Angular + Tailwind
│       └── src/app/
│           ├── pages/
│           ├── core/api.service.ts
│           └── app.routes.ts
├── package.json      # scripts api / web
└── README.md

Regla D-P1-03: apps/api y apps/web independientes (npm install --prefix), sin workspaces npm que rompan Angular CLI.

3. Backend

PiezaDetalle
FrameworkNestJS modules: Auth, Requests, Prisma
Validaciónclass-validator DTOs
Hashbcrypt passwords
CORSHabilitado para dev web :4200
Puerto3008 (env PORT opcional)
Prefijo global/api

Módulos

MóduloResponsabilidad
AuthModulelogin, JWT sign, strategy
RequestsModuleCRUD-lite solicitudes
PrismaModulePrismaService global

4. Frontend

PiezaDetalle
AngularStandalone pages, RouterLink, HttpClient
Estado authlocalStorage keys volta_token, volta_user
API basehttp://localhost:3008/api en ApiService
FuentesSyne + Work Sans (link Google Fonts / index)
Mediaassets/hero.jpg

Rutas web

PathComponente
/HomePage
/apuntarmeJoinPage
/okSuccessPage
/loginLoginPage
/inboxInboxPage
/inbox/:idRequestDetailPage

5. Base de datos

CampoValor
ProviderPostgreSQL
HostingNeon
Projectdelicate-mountain-11765167
MigracionesPrisma migrate (init)
Seedprisma/seed.ts → 1 coach + 5 requests

6. Seguridad técnica (resumen)

ControlImplementación
Passwordbcrypt hash
API coachJwtAuthGuard en GET/PATCH
Form públicosolo POST create
SecretJWT_SECRET en env API
PIIno exponer list en endpoints públicos

Detalle en 11-privacy-security.md.

7. Scripts típicos

cd /Users/cristian/orca/volta-app
npm install --prefix apps/api
npm install --prefix apps/web
# apps/api/.env → DATABASE_URL + JWT_SECRET
npm --prefix apps/api run prisma:migrate
npm --prefix apps/api run prisma:seed
npm run api    # :3008
npm run web    # :4200

8. Decisiones técnicas

DecisiónRazón
Puerto API 3008No colisionar con SURCO 3007 y anteriores
preferredDay/Slot como StringL1 simple; evita timezone complexity
Sin FK coach–requestForm anónimo; asignación multi-coach = L2
Soft auth en AngularAPI es autoridad; guards formales = L1+
Stats endpoint propioEvita recalcular en cliente

9. Dependencias clave (orientativo)

CapaPaquetes
API@nestjs/*, @prisma/client, bcrypt, passport-jwt, class-validator
Web@angular/*, tailwindcss, RxJS

10. Despliegue (recomendado, no obligatorio del día)

ServicioOpción
WebVercel / Netlify / static host
APIRailway / Fly / Render
DBNeon (ya provisionada)

Variables: DATABASE_URL, JWT_SECRET, PORT, y en web la URL pública de API.

07-creative-direction.md

Abrir documento

07 — Dirección creativa — VOLTA

1. Concepto de marca

CampoValor
NombreVOLTA
Eslogan”Tu plaza en la cancha.”
TerritorioClub de barrio, energía real, sin greña de gym chain
PromesaUn hueco en el grupo — claro, cercano, sin fricción digital innecesaria
TonoDirecto, deportivo, vecinal; cero jerga corporativa “wellness SaaS”

Metáfora

Volta evoca la vuelta a la cancha, el regreso al grupo, el ciclo del entrenamiento semanal. Visualmente: tiza (chalk) de pizarra de vestuario × tinta negra de dorsal × lima neón de línea de campo.

2. Personalidad (arquetipos)

EjePosición
Formal ↔ InformalInformal profesional
Suave ↔ EnérgicoEnérgico contenido
Lujo ↔ BarrioBarrio con craft
Genérico fitness ↔ LocalLocal, Valencia en copy

3. Sistema visual

Color

RolHexEmoción
Chalk bg#F7F7F2Pizarra limpia, aire
Ink#0B0B0BDorsal, decisión, fuerza
Lime#C6F23ASeñal de campo, energía
Muted#5C5C58Texto secundario
Border#E2E2DCSeparación suave
Surface#FFFFFFCards, legibilidad

Regla: el lime es acento, no relleno masivo. CTAs principales pueden ser ink (texto lime) o lime (texto ink) según jerarquía.

Tipografía

UsoFamiliaCarácter
DisplaySyneGeométrica, deportiva, wordmark
UI / bodyWork SansLegible, humana, forms

Forma

  • Radios grandes (rounded-2xl, pills rounded-full) → amable sin “bubble tea app”.
  • Bordes 1px #E2E2DC → estructura de vestuario limpio.
  • Hero con foto real de cancha/club — no ilustración stock abstracta.

4. Moodboard verbal

No
Cancha de barrio, sudor real, luz de polideportivoLuxury spa fitness, mármol rosa
Lime como spray de líneaGradientes púrpura genéricos
Syne bold en titularesInter/Roboto por defecto sin intención
Microcopy “plaza”, “cancha”, “coach”“Optimiza tu wellness journey”
Dark ink sections para contrasteTodo gris flat SaaS

5. Fotografía y media

AssetUso
assets/hero.jpgHome hero, posible cover Paper
Alt textDescriptivo: “Cancha de un club deportivo de barrio”

[DECISIÓN DE DISEÑO]: media fotorrealista obligatoria (D-P0-05); no placeholders grises.

6. Voz en UI (preview; detalle en doc 09)

ContextoEjemplo
Hero“Tu plaza en la cancha.”
CTA“Quiero una plaza” / “Apuntarme”
Success“Solicitud enviada” + código VO-
Coach empty“No hay solicitudes todavía.”
Error“No se pudo cargar el inbox. Reintenta.”

7. Diferenciación en la serie ALS-2

ProyectoPaleta / tonoVOLTA se diferencia por…
SURCOBone/leaf agroEnergía urbana lime, no rural
CORREAMarketplace petClub único, no matching
TROCHAOps logísticaEmoción de cancha, no flota
MERIDIANAClínicaInformal deportivo, no sanitario

8. Criterios de aceptación creativa

  1. Un scroll de home se reconoce como club de barrio, no como template Tailwind.
  2. Syne aparece en logo y H1; Work Sans en body/forms.
  3. Lime presente en CTAs o highlights sin saturar fondos.
  4. Hero real; sin lorem en artboards Paper ni app.
  5. Panel coach mantiene mismos tokens (no “admin theme” gris aparte).

08-design-system.md

Abrir documento

08 — Design system — VOLTA

1. Fundamentos

CapaValor
Nombre DSVOLTA UI (L1 vertical slice)
PrincipioEnergía de cancha + claridad operativa del inbox
PlataformasWeb responsive 360–1280+
ImplementaciónTailwind tokens + componentes de página (no lib publicada)

2. Color tokens

Marca (fuente de verdad del caso)

TokenHexUso
color.bg.chalk#F7F7F2Background app/marketing
color.surface#FFFFFFCards, header
color.ink#0B0B0BTexto fuerte, CTAs dark
color.ink.muted#5C5C58Secundario
color.lime#C6F23AAcento, highlights, CTA lime
color.lime.soft#EAF8B8Badges soft, fondos suaves
color.lime.strong#A8D420Hover lime
color.border#E2E2DCBordes
color.dangeraprox red-700Errores de form / red

Mapeo Tailwind app

ClaseValor implementado
bg-bg#F7F7F2
bg-surface#FFFFFF
text-ink / ink-muted#0B0B0B / #5C5C58
primary / primary-soft / primary-strong#0B0B0B / #EFEFEA / #000000
lime / lime-soft / lime-strong#C6F23A / #EAF8B8 / #A8D420
border-border#E2E2DC

3. Tipografía

TokenFamiliaFallback
font.displaySynesystem-ui, sans-serif
font.sansWork Sanssystem-ui, sans-serif
EstiloSpec
Display xlSyne 36–60/800, leading ~1.05
TitleSyne 28–32/700–800
BodyWork Sans 16/400–500, leading relaxed
LabelWork Sans 11–12/700 uppercase o tracking wide
ButtonWork Sans 14/700

4. Espaciado y radio

TokenValor
page padding x16–24px
section y40–56px
card padding16–24px
gap grid12–16px
radius.card16–20px (rounded-2xl)
radius.pill9999px (rounded-full)
header height~72px

5. Componentes

5.1 Botones

VarianteEstiloUso
Primary darkbg ink, text lime, pillNav “Apuntarme”
Primary limebg lime, text ink, pillHero CTA principal
Secondaryborder border, bg surface, pill“Ver clases”
Ghost/texttext muted, hover inkEnlaces nav, salir

Estados: default · hover (strong) · disabled (opacidad) · focus visible ring.

5.2 Badges de estado

StatusLabelEstilo sugerido
NEWNuevalime soft / ink
CONTACTEDContactadaprimary soft / muted
CONFIRMEDConfirmadalime o soft positivo
CANCELLEDCanceladamuted / borde dashed opcional

Regla a11y: no codificar solo con color; siempre texto del label.

5.3 Badges de ClassType

TipoLabelNotas
HIITHIITtracking bold
YOGAYoga
BASKETBasket
KIDSKids
OPENCancha abierta

5.4 Cards de solicitud (inbox)

Estructura:

  1. Meta: code · classType (xs bold, muted o lime)
  2. Nombre completo (lg semibold)
  3. Día preferido · franja
  4. Email / teléfono
  5. Badge status (trailing)

5.5 Stats summary

MétricaFuente
Totalstats.total
Abiertasstats.open (NEW+CONTACTED)
Por estadostats.byStatus.*

Layout: grid 2–4 cards compactas sobre la lista.

5.6 Form fields

ElementoSpec
LabelWork Sans 12–14/600
Inputborder border, rounded-xl, bg surface, focus ring ink/lime
Select ClassTypemismos tokens
Errortext danger, bajo el campo
Submitfull-width en móvil, pill

5.7 Header

ZonaContenido
PúblicaLogo · nav · CTA Apuntarme
CoachLogo · badge COACH · nombre · Salir

6. Layout patterns

PatternUso
Marketing splitHome: copy + hero image 2 col
Dark bandSección clases sobre ink
App shell simpleInbox full-width max-w-6xl
Detail stackMeta → contacto → preferencias → acciones

7. Iconografía

L1: preferir tipografía y badges; iconos mínimos si se usan (stroke 1.5–2, ink). No librería obligatoria.

8. Motion

InteracciónSpec
Hover CTAcolor strong, 150ms
Page transitionsrouter default (sin lib motion)
Feedback submitdisabled + label “Enviando…” opcional

9. Do / Don’t

DoDon’t
Lime como acentoFondos enteros lime sin contraste
Syne solo displaySyne en párrafos largos
Datos seed reales en mockupsLorem ipsum
Empty/error con copyPantallas en blanco

09-content-guide.md

Abrir documento

09 — Guía de contenido — VOLTA

1. Voz y tono

AtributoDescripción
DirectoFrases cortas; verbo en imperativo en CTAs
Vecinal“club de barrio”, “cancha”, “plaza” — no “ecosistema fitness”
RespetuosoTrato de tú; sin paternalismo “tú puedes con todo”
Operativo en coachLabels de estado claros; cero motivacional vacío

Registro

ContextoRegistro
Marketing homeEnérgico, cercano
FormularioNeutro, claro, labels explícitos
SuccessConfirmatorio, tranquilizador
Panel coachTécnico-ligero, denso en datos
ErroresHonestos, accionables

2. Glosario de producto (copy)

UsarEvitar
PlazaSlot genérico sin contexto
SolicitudTicket / lead (salvo docs técnicas)
CoachAdmin / backoffice
Cancha abiertaOPEN crudo en UI visitante (sí en API)
ApuntarmeSign up / registrarse (implica cuenta)
Contactada“En progreso” ambiguo

3. Microcopy por pantalla

Home

ElementoCopy
EyebrowCLUB DE BARRIO · VALENCIA
H1Tu plaza en la cancha.
LeadEntrenamientos en grupo, cancha abierta y monitores del barrio. Reserva tu hueco sin cadenas de WhatsApp ni listas en el mostrador.
CTA primaryQuiero una plaza
CTA secondaryVer clases
Stat 1CLASES · 5 tipos
Stat 2RESPUESTA · < 24 h [HIPÓTESIS de promesa de servicio, no KPI medido]
Stat 3PANEL · Coach JWT
Clases introHipótesis de oferta del club (contenido de producto, no catálogo real verificado).
Footer demoCredenciales coach demo si se documentan

Join (/apuntarme)

ElementoCopy
TítuloPide tu plaza
SubTe contactamos para confirmar el hueco.
fullNameNombre completo
emailEmail
phoneTeléfono (opcional)
classTypeTipo de clase
preferredDayDía preferido
preferredSlotFranja preferida
notesNotas (opcional)
SubmitEnviar solicitud
Error genéricoNo se pudo enviar. Revisa los datos e inténtalo.

Success (/ok)

ElementoCopy
TítuloSolicitud enviada
BodyHemos recibido tu petición. Guarda tu código de referencia.
Code labelTu código
NextEl coach del club te contactará para confirmar.
CTAVolver al inicio

Login

ElementoCopy
TítuloPanel coach
SubEntra para gestionar solicitudes de plaza.
emailEmail
passwordContraseña
SubmitEntrar
ErrorNo se pudo entrar. Revisa email y contraseña.

Inbox

ElementoCopy
TítuloSolicitudes
Stats labelsTotal · Abiertas · Nueva · Contactada · Confirmada · Cancelada
EmptyNo hay solicitudes todavía.
ErrorNo se pudo cargar el inbox. Reintenta.
SalirSalir

Detail

ElementoCopy
Volver← Inbox
AccionesMarcar contactada · Confirmar plaza · Cancelar
Notas vacíasSin notas

4. Labels de enums (UI)

APILabel ES
NEWNueva
CONTACTEDContactada
CONFIRMEDConfirmada
CANCELLEDCancelada
HIITHIIT
YOGAYoga
BASKETBasket
KIDSKids
OPENCancha abierta

5. Principios de redacción

  1. Una idea por frase en marketing.
  2. Verbos de acción en botones (no “OK” / “Submit”).
  3. Errores con siguiente paso (“Reintenta”, “Revisa…”).
  4. No inventar stats de mercado; si hay promesa de servicio, etiquetarla como hipótesis de producto.
  5. Español peninsular neutro (es-ES); sin anglicismos innecesarios salvo HIIT, JWT en footer técnico.

6. Contenido de demo / seed (nombres)

CódigoNombreClaseEstado
VO-0808-01Marc SoléHIITNueva
VO-0808-02Laia PuigYogaContactada
VO-0808-03Eric FontBasketNueva
VO-0808-04Sofía RamiKidsConfirmada
VO-0808-05Pol SerraCancha abiertaCancelada

Coach: Nora Beltrán · coach@volta.club

7. Accesibilidad de copy

  • Badges con texto, no solo color.
  • Alt de hero descriptivo.
  • Placeholders no sustituyen labels.
  • Errores asociados al campo cuando sea posible.

10-accessibility.md

Abrir documento

10 — Accesibilidad — VOLTA

1. Objetivo

Orientar la UI a WCAG 2.2 AA en lo razonable para un vertical slice L1.
No se afirma auditoría formal certificada; se listan requisitos y checks manuales.

2. Principios aplicados

PrincipioAplicación VOLTA
PerceptibleContraste ink/chalk; lime solo con texto ink o como acento
OperableTargets ≥44px en CTAs y acciones de estado; teclado en forms
ComprensibleLabels ES; errores claros; estados con texto
RobustoHTML semántico en templates Angular; focus visible

3. Color y contraste

ParUsoNota
Ink #0B0B0B sobre chalk #F7F7F2BodyAlto contraste
Ink sobre whiteCardsAlto contraste
Lime #C6F23A + ink textCTA limePreferir texto ink sobre lime
Lime text sobre ink bgNav CTA / dark bandVerificar en UI real
Muted #5C5C58 sobre chalkSecundarioEvitar muted sobre muted

Prohibido: transmitir estado solo con color (badges llevan label).

4. Tipografía y legibilidad

ReglaSpec
Body mínimo16px
Line-height body≥ 1.5 relajado
DisplaySyne; no párrafos largos en display
ZoomLayout usable al 200% (responsive)

5. Teclado y foco

FlujoRequisito
Join formTab order lógico; submit con Enter
LoginIgual
Inbox cardsClick + teclado si son links/botones
Detail actionsBotones focusables, no solo divs
Focus ringVisible (ring ink o lime)

6. Formularios

Controla11y
LabelsVisible, asociado al control
RequiredIndicado en UI + validación
ErrorsMensaje textual bajo campo o form
Phone optionalMarcado “(opcional)”
Select ClassTypeOpciones con labels legibles

7. Imágenes y media

AssetRegla
hero.jpgalt descriptivo no vacío
Decorativealt vacío solo si puramente decorativo

8. Auth y áreas coach

TemaNota
LogoutControl con nombre accesible “Salir”
Errores 401Mensaje no solo cambio de color
Empty/errorHeading o texto de estado legible por SR

9. Checklist de verificación manual (QA)

#CheckOK?
A1Contraste H1 y body en home
A2CTA lime con texto legible
A3Form join usable solo teclado
A4Badges status con texto
A5Alt hero presente
A6Error login anunciable
A7Targets touch ≥44px en móvil
A8No hay texto en imagen como única info

10. Deuda a11y aceptada L1

ÍtemClasificación
Auditoría axe automatizada en CIL1+
Live regions formales ARIA en todos los asyncL1+
Skip linkNice-to-have
i18n multi-idiomaFuera

11. Criterio de aceptación

La demo es usable con teclado en form y login; contraste principal cumple intención AA; estados no dependen solo del color.

11-privacy-security.md

Abrir documento

11 — Privacidad y seguridad — VOLTA

1. Contexto

VOLTA trata datos de contacto y preferencias de clase de visitantes (PII ligera) y credenciales del coach.
Alcance L1 demo: no es un DPIA formal; documenta decisiones de diseño y controles implementados.

2. Datos tratados

DatoEntidadSensibilidadBase demo
Nombre completoClassRequestPIIConsentimiento implícito al enviar form [DECISIÓN demo]
EmailClassRequest / UserPIIIgual
TeléfonoClassRequestPIIOpcional
Preferencias clase/día/franjaClassRequestBajaNecesarias al servicio
NotasClassRequestVariableTexto libre del visitante
PasswordUserSecretoSolo hash bcrypt
JWTClienteSesiónlocalStorage (demo)

3. Superficies de exposición

SuperficieRiesgoControl v1
POST /api/requestsSpam / PII entradaValidación DTO; rate-limit futuro
GET /api/requestsFiltración lista PIIJwtAuthGuard obligatorio
GET /api/requests/:idPII individualJWT
PATCH statusAbuso de estadoJWT
LoginFuerza brutabcrypt; rate-limit futuro
localStorage tokenXSS robo sesiónApp trusted demo; CSP futuro

4. Controles de seguridad implementados

ControlEstado
Passwords hasheados bcrypt
JWT firmado con JWT_SECRET
Rutas coach protegidas
Create público solo POST
Password en respuestasNo (nunca)
HTTPS en producciónRecomendado (Neon + host)
CORS restringido prodConfigurar al desplegar

5. Autorización

ActorPuede
AnónimoPOST request; ver páginas públicas
COACH autenticadoListar, ver detalle, cambiar status
Sin rol MEMBERNo existe en v1

6. Privacidad (RGPD — orientación)

PrincipioAplicación v1
MinimizaciónCampos justos para contactar y preferir clase
Limitación finalidadGestión de plazas del club
ConservaciónDemo seed; política de borrado no automatizada
Derechos ARCO/RGPDProceso manual fuera de app
TransparenciaMejorable: enlace política L1+
Consentimiento kidsNotas “hija 8 años” en seed = ejemplo; en prod se requeriría base legal parental [HIPÓTESIS legal]

No se afirma cumplimiento RGPD certificado. Es un mapa de riesgos para el case.

7. Amenazas y mitigaciones

AmenazaImpactoMitigación
Enumeración de inbox sin authAltoGuard JWT
Spam de solicitudesMedioValidación; captcha L1+
Token en localStorageMedioDemo; HttpOnly cookie L2
Secret débil JWTAltoEnv no commitear
Notas con datos sensiblesMedioCopy: evitar datos médicos
Credenciales demo públicasBajo (demo)Documentadas a propósito

8. Logging y secretos

Regla
No loguear passwords ni tokens completos
DATABASE_URL y JWT_SECRET solo en .env
Seed password solo en docs de demo

9. Checklist de seguridad demo

#Check
S1GET /api/requests sin header → 401
S2PATCH sin header → 401
S3Login password incorrecto → 401
S4Password no en JSON de user
S5.env no en git

10. Evolución recomendada (no deuda L1)

  • Rate limiting + captcha en POST público
  • Consent checkbox + política de privacidad
  • Rotación JWT / refresh
  • Soft-delete y retención configurable
  • Audit log de cambios de status

12 — Analytics y métricas — VOLTA

1. Objetivo

Definir el modelo de medición del producto.
En v1 L1 la instrumentación puede ser mínima o nula en código; las métricas guían producto y roadmap.

No se reportan dashboards con números inventados como si fueran producción.

2. North Star

MétricaDefiniciónPor qué
Plazas confirmadas / semanaCount ClassRequest con status CONFIRMED creadas o confirmadas en la ventanaMide cierre real del job del club

3. Árbol de métricas

NivelMétricaDefinición
InputVisitas homePage view /
Activación visitanteSolicitudes enviadasPOST /api/requests 2xx
Calidad captura% forms con phonephone non-null / total
OpsTiempo NEW → CONTACTEDMediana hours
OpsTiempo NEW → CONFIRMEDMediana hours
Ops% open (NEW+CONTACTED)open / total
SaludError rate API5xx / total
CoachLogins / díaPOST login 200

4. Eventos propuestos (schema)

EventoPropsTrigger
home_viewedEnter /
join_startedEnter /apuntarme
join_submittedclassTypeSubmit form
join_succeededcode, classType201
join_failedreason4xx/5xx/network
success_viewedcode/ok
coach_login_succeeded200 login
coach_login_failed401
inbox_viewedtotal, openload inbox
request_openedid, statusdetail
status_changedid, from, toPATCH 200

5. Funnels

Funnel visitante

home_viewed → join_started → join_submitted → join_succeeded → (offline) contact → CONFIRMED
PasoFricción esperada [HIPÓTESIS]
Home → JoinCTA claro reduce drop
Join → SuccessValidación y red
Success → CONFIRMEDOps del coach (fuera de web)

Funnel coach

login → inbox_viewed → request_opened → status_changed(CONTACTED|CONFIRMED)

6. Segmentos

SegmentoCómo
Por ClassTypeprop en eventos create/status
Por statusbyStatus snapshot
Mobile vs desktopUA / viewport (futuro)

7. Implementación v1 vs futura

Piezav1 L1Futuro
Logs API NestOpcional consoleStructured logs
Product analyticsNo obligatorioPlausible / PostHog
Stats in-appGET summary+ series temporales
A/B CTA copyNoL2

8. KPIs de éxito del case (demo)

KPI demoCriterio
Seed visible≥5 requests en inbox tras seed
Create E2E1 request nueva aparece en list
Status E2EPATCH refleja badge
AuthSin token no hay list

9. Ética de medición

  • No trackear notas libres con PII hacia terceros sin base legal.
  • No inventar “conversión 37%” en el portfolio.
  • Separar métrica modelo vs dato medido.

13 — Plan de QA y pruebas — VOLTA

1. Alcance

Validar el vertical slice L1: form público, success, login coach, inbox, detalle, estados, empty/error, seed Neon.

2. Entorno

VariableValor
APIhttp://localhost:3008
Webhttp://localhost:4200
DBNeon delicate-mountain-11765167
Coachcoach@volta.club / password123

3. Smoke tests (obligatorios)

IDCasoPasosEsperado
S1Seedprisma:seedLog VOLTA seed OK
S2Login OKPOST /api/auth/login200 + accessToken
S3Login KOpassword mal401
S4Create publicPOST /api/requests body válido201 + code VO-… + status NEW
S5List sin tokenGET /api/requests401
S6List con tokenAuthorization Bearer200 array ≥1
S7StatsGET /api/requests/stats/summarytotal/open/byStatus
S8DetailGET /api/requests/:id200
S9Patch statusPATCH { "status": "CONTACTED" }200 status actualizado
S10Web homeabrir /hero + CTA
S11Web join E2Eform → successcódigo visible
S12Web inboxlogin → /inboxcards seed

4. Casos funcionales ampliados

Público

IDCasoEsperado
P1Email inválido en join400 / error UI
P2classType fuera de enum400
P3notes omitidasnotes ""
P4phone omitidonull/ausente OK

Coach

IDCasoEsperado
C1Token basura401 en list
C2id inexistente404
C3status inválido400
C4Transición NEW→CONFIRMED200
C5Logout limpia sesiónlist falla o redirect login

UI estados

IDCasoEsperado
U1Inbox vacío (DB clean sin seed)empty copy
U2API paradaerror + reintentar
U3Responsive 390px joinusables CTAs

5. Regresión visual (manual)

PantallaCheck
HomeSyne H1, lime CTA, hero no roto
Joinlabels, select tipos
Successcódigo monospaced o bold
Loginsplit/form legible
Inboxbadges status + stats
Detailacciones de estado

6. Seguridad smoke

Ver 11-privacy-security.md checks S1–S5.

7. Accesibilidad smoke

Ver 10-accessibility.md A1–A8.

8. Criterios de salida (release demo)

  • S1–S12 OK
  • Sin 500 en flujos felices
  • Docs de case enlazadas
  • Paper referenciado

9. Automatización futura

CapaToolPrioridad
API e2esupertest / Playwright APIP1 L1+
UI e2ePlaywrightP1 L1+
a11yaxeP2
CIGitHub ActionsP2

10. Datos de prueba recomendados

Además del seed:

NombreClaseNotas
Test UserOPEN“prueba QA”
Ana KidsKIDSteléfono relleno

14 — Handoff de desarrollo — VOLTA

1. Fuentes de verdad

ArtefactoUbicación
Case docs/Users/cristian/orca/ux-projects/2026-08-08-volta/docs/
Paperhttps://app.paper.design/file/01KZG2VRQFF2QF0PRDB10D4AG7
App/Users/cristian/orca/volta-app/
Schemaapps/api/prisma/schema.prisma
Seedapps/api/prisma/seed.ts
Tokensapps/web/tailwind.config.js
Rutas webapps/web/src/app/app.routes.ts
API clientapps/web/src/app/core/api.service.ts

2. Setup local (checklist)

  1. Node LTS instalado.
  2. Clonar/usar volta-app.
  3. Copiar apps/api/.env.example.env con DATABASE_URL (Neon) y JWT_SECRET.
  4. npm install --prefix apps/api && npm install --prefix apps/web.
  5. Migrar y seed.
  6. npm run api (:3008) y npm run web (:4200).
  7. Smoke S2, S4, S6, S11, S12 (doc 13).

3. Contratos que no romper

ContratoDetalle
Prefijo API/api
Login body{ email, password }
Login response{ accessToken, user }
Create request fieldsfullName, email, phone?, classType, preferredDay, preferredSlot, notes?
Status patch{ status: RequestStatus }
Stats shape{ total, open, byStatus }
Token storage keysvolta_token, volta_user

Cambios de contrato → actualizar docs 04, 05, 20 y Paper si afecta UI.

4. Mapa pantalla → API → modelo

PantallaMétodosModelo
JoinPOST requestsClassRequest
Success— (resultado create)code
LoginPOST auth/loginUser
InboxGET requests, GET statsClassRequest[]
DetailGET :id, PATCH statusClassRequest

5. Tokens UI a respetar

TokenHex
bg#F7F7F2
ink#0B0B0B
lime#C6F23A
muted#5C5C58
border#E2E2DC
fontsSyne + Work Sans

No sustituir por tema default de Angular Material sin brief de diseño.

6. Convenciones de código

ÁreaConvención
AngularStandalone components por página
NestModule por dominio (auth, requests)
PrismaEnums en schema; no strings sueltos de status
IDscuid
CódigosVO-MMDD-XXX

7. Definition of Done (feature)

  • API + validación DTO
  • UI con tokens y microcopy ES
  • Empty/error si aplica lista
  • Doc actualizada si cambia dominio
  • Smoke manual del flujo
  • Sin secretos en git

8. Ambientes

EnvAPIWebDB
Local:3008:4200Neon dev branch
Prod (futuro)host APIhost webNeon main

9. Contacto de dominio (roles ficticios demo)

RolPersona
Product/UX caseSerie ALS-2 daily
Coach demoNora Beltrán

10. Riesgos de implementación

RiesgoMitigación
CORS en prodWhitelist origen web
API URL hardcodeEnvironment Angular L1+
Orden rutas Nest stats vs :idstats/summary declarado antes de :id [COMPROBADO en controller]

15 — Roadmap — VOLTA

1. Principio

El L1 del día está cerrado. Este roadmap no es deuda del alcance 2026-08-08; son opciones de evolución con subida de complejidad o polish.

2. Hecho (L1 — 2026-08-08)

ÁreaEntrega
ProductoWeb club + solicitud + inbox coach
DominioUser COACH + ClassRequest + enums
AuthJWT login
APIPOST public + GET/PATCH JWT + stats
WebHome, join, success, login, inbox, detail
DataNeon + Prisma + seed
DiseñoPaper §1–§5 + tokens chalk/ink/lime
DocsSuite 00–20 + README + executive

3. L1+ (misma complejidad, mejoras)

IDÍtemValor
L1+01canActivate guards Angular en /inboxUX auth
L1+02Filtros por status en inboxOps
L1+03Toast éxito create/statusFeedback
L1+04Captcha / rate limit POSTAnti-spam
L1+05Checkbox privacidad en formRGPD
L1+06Playwright smoke S1–S12CI
L1+07Skeleton loading inboxPolish
L1+08click-to-call / mailto en detailOps coach
L1+09Environment-based API URLDeploy
L1+10Página 404 amigableIA

4. L2 (nuevo brief)

IDÍtemDependencia
L2-01Calendario semanal de clasesSchedule model
L2-02Aforo por franjacapacity field
L2-03Multi-coach + asignacióncoachId FK
L2-04Email al coach al crearprovider email
L2-05Área “mi solicitud” por códigolookup público acotado
L2-06Notas internas coachcampo staffNotes
L2-07Export CSV semanareporting

5. L3+ (explícitamente mayor)

IDÍtem
L3-01Multi-sede / multi-tenant
L3-02Pagos y cuotas
L3-03App nativa / push
L3-04Marketplace de clubs
L3-05Wearables / planes IA

6. No-roadmap (fuera de VOLTA)

IdeaRazón
Agro / parcelasSURCO
Flota GPSTROCHA
Expedientes legalesFIRME
Matching pet servicesCORREA

7. Priorización sugerida si hay continuidad

  1. L1+01 guards + L1+06 e2e
  2. L1+02 filtros + L1+08 contact shortcuts
  3. L1+04 anti-spam si hay tráfico real
  4. Evaluar L2 calendario solo con uso coach real

8. Métricas que desbloquean L2

SeñalUmbral ejemplo [HIPÓTESIS]
Solicitudes / semana> 20 sostenidas
% NEW sin CONTACTED > 48 h> 30% → priorizar ops tools
Coach pide aforoEntrevistas / feedback real

16-interaction-specs.md

Abrir documento

16 — Especificaciones de interacción — VOLTA

1. Convenciones

TokenValor
Duración hover~150ms ease
Focusring 2px ink o lime
Disabledopacity 0.5, cursor not-allowed
Touch min44×44 px

2. Home

ElementoInteracción
Nav anchorsSmooth scroll opcional a #clases / #horarios
CTA “Quiero una plaza”Navigate /apuntarme
CTA “Ver clases”Scroll #clases
CTA “Apuntarme” headerNavigate /apuntarme
“Coach”Navigate /login
Hero imageEstática; no lightbox v1
Cards de claseInformativas; CTA global a join

Estados: solo estáticos (marketing).

3. Join form

PasoComportamiento
Input focusBorder/ring énfasis
ValidaciónOn submit (mínimo L1); campos required bloquean
Submit loadingBotón disabled + “Enviando…” opcional
Success pathNavigate /ok con code en state/query
Error pathBanner/texto error; form permanece
CampoInput type / control
fullNametext
emailemail
phonetel
classTypeselect enum
preferredDaydate o text date
preferredSlottext o select horas
notestextarea

4. Success

ElementoInteracción
CódigoSeleccionable; copy-to-clipboard L1+ opcional
CTA homeNavigate /
RefreshDebe seguir mostrando mensaje (state o re-fetch no aplica)

5. Login

PasoComportamiento
SubmitPOST login
SuccessGuardar token/user → /inbox
ErrorMensaje bajo form; password no se limpia necesariamente
EnterSubmit form

6. Inbox

ElementoInteracción
LoadParallel GET list + stats
Card clickNavigate /inbox/:id
Pull refreshN/A web; botón reintentar en error
EmptyMensaje centrado; sin CTA create (create es público)
ErrorMensaje + control reintentar (re-fetch)
SalirClear storage → /login

Stats chips

Solo lectura en v1; click no filtra (filtro = L1+).

7. Request detail

ElementoInteracción
Volver/inbox
Botones estadoPATCH inmediato; optimistic opcional; al 200 actualizar badge
Loading patchDisable botones de acción
Error patchToast/texto; estado UI no miente
Email/telmailto: / tel: si se implementa (recomendado)

Mapa de acciones sugerido

BotónTarget statusVisible si
Marcar contactadaCONTACTEDstatus ≠ CONTACTED (o siempre)
Confirmar plazaCONFIRMEDstatus ≠ CONFIRMED
CancelarCANCELLEDstatus ≠ CANCELLED

[DECISIÓN DE DISEÑO]: L1 puede mostrar las tres acciones siempre; el PATCH acepta el enum completo.

8. Responsive

BreakpointComportamiento
< mdNav colapsada; CTA header visible; grids 1 col
≥ mdNav links; home 2 col; inbox stats en fila

9. Feedback y errores (copy interactivo)

SituaciónFeedback
Join OKNavegación success (no solo alert)
Join failInline error
Login failInline error
Inbox failPanel error
Status OKBadge actualiza

10. Accesibilidad de interacción

  • No usar solo hover para info crítica.
  • Botones reales (button / a), no div clickable sin role.
  • Mantener orden de tab natural en form y detail.

17-prototype-map.md

Abrir documento

17 — Mapa de prototipo — VOLTA

1. Qué es “prototipo” en este case

CapaRol
PaperHi-fi visual + UX process; no clicable nativo vía MCP
Angular appPrototipo interactivo real (flujos E2E)
DocsFlujos, IA, specs

2. Paper → rutas

BandaArtboardRuta / estado
§2Home/
§2Join/apuntarme
§2Success/ok
§3Login/login
§3Inbox/inbox
§3Detail/inbox/:id
§4Mobilemismas rutas, viewport 390
§5Empty/inbox sin rows
§5ErrorAPI down / error flag

Ver inventario completo: 00-paper-reference.md.

3. Flujos clicables en app

[Home] --Apuntarme--> [Join] --submit--> [Success] --inicio--> [Home]
[Home] --Coach------> [Login] --OK-----> [Inbox] --card--> [Detail] --status--> [Detail]
[Inbox] --Salir-----> [Login]

4. Datos del prototipo

FuenteUso
Seed NeonInbox realista
POST createSuccess con code nuevo
JWTBarrera coach

5. Limitaciones del prototipo v1

LimitaciónNota
Paper no enlaza hotspotsUsar app para demo interactiva
Sin email real al coachContacto offline
Sin aforoConfirmación manual
Token en localStorageDemo

6. Guión de demo (3 minutos)

  1. Home — eslogan, clases, promesa.
  2. Apuntarme — HIIT, día, 19:00, enviar.
  3. Success — mostrar VO-….
  4. Login coach@volta.club / password123.
  5. Inbox — stats + lista seed + nueva.
  6. Detail Marc o la nueva — CONTACTED → CONFIRMED.
  7. (Opcional) empty/error si se demuestran estados.

7. Assets de prototipo

AssetPath
Hero case2026-08-08-volta/assets/hero.jpg
Hero appvolta-app/apps/web/src/assets/hero.jpg (o public)

8. Criterio “prototype complete”

  • Todos los must-have de flujo implementados en Angular
  • Paper referencia bandas §1–§5
  • Seed coherente con personas
  • Microcopy ES sin lorem

18-completeness-audit.md

Abrir documento

18 — Auditoría de completitud — VOLTA (2026-08-08)

1. Alcance auditado

Vertical slice L1: web club de barrio + solicitud pública de plaza + panel coach JWT, con docs, Paper, Angular+Nest+Prisma+Neon.

2. Checklist CRON / ALS-2

RequisitoEstadoEvidencia
Diversidad sector/tipo/nivelOKFitness L1; no marketplace; no agro/legal/logistics
Day brief + anti-patronesOKdocs/00-day-brief.md
Paper bandas §1–§5OKfile 01KZG2VRQFF2QF0PRDB10D4AG7
Docs 00–20OKsuite en docs/
JWT coachOKRole COACH
API + seed + NeonOKdelicate-mountain-11765167, port 3008
Web Angular tokensOKSyne/Work Sans, chalk/ink/lime
Smoke public+coachOKplan doc 13
Cierre sin deuda del L1OKroadmap solo L1+/L2+
Hipótesis no fake statsOKetiquetas en doc 02

3. Cobertura funcional

Feature briefImplementadoUIAPIDocs
Home01,09
Join publicPOST requests04,05
Success04
LoginPOST login04,06
Inbox + statsGET + summary05
Detail + statusGET + PATCH04
Empty16
Error red16
Seed demoseed05

4. Cobertura Paper

BandaInventarioNotas
§1 UXCover→Datosstakeholders, personas, JTBD, journey, blueprint, IA, datos
§2 DS+PublicDS, Home, Join, Successtokens + cara pública
§3 CoachLogin, Inbox, Detailpanel JWT
§4 MobileJoin/Inbox mobile~390px
§5 StatesEmpty, Errorresiliencia

5. Rúbrica de calidad (auto SCORE orientativo)

EjeScore 1–5Comentario
Diversidad5Sector fitness nuevo en la serie
Craft visual4–5Palette lime/ink + Syne + hero
Densidad UX docs5Suite portfolio completa
Completitud código L14–5Vertical slice runnable
Authz5Guard en list/detail/status
Verdad investigación5Sin stats falsas

6. Huecos aceptados (no regresiones de cierre)

HuecoClasificación
Pagos / aforo liveFuera L1
e2e automatizadoPreferible L1+
Route guards formales AngularL1+
Notificaciones emailFuera L1
Multi-coachL2

7. Veredicto

COMPLETO para entrega de caso 2026-08-08 con documentación portfolio y app alineada al brief.
Cualquier ampliación multi-sede/pagos/marketplace requiere nuevo brief de diversidad, no parche silencioso.

19-backlog-completo.md

Abrir documento

19 — Backlog completo — VOLTA

Inventario de ítems. Los del alcance L1 del día están Done.
El resto es opcional / siguiente nivel, no deuda oculta del cierre §1.1.

1. Done — L1 (2026-08-08)

IDÍtemCapa
D01Definición producto VOLTADocs
D02Day brief diversidad fitness L1Docs
D03Personas Marc / NoraDocs + Paper
D04JTBD + stories MustDocs + Paper
D05IA y flujosDocs
D06Modelo User/ClassRequestPrisma
D07Auth JWT login coachAPI + Web
D08POST solicitud públicaAPI + Web
D09Success + código VO-Web
D10List requests + statsAPI + Web
D11Detail + patch statusAPI + Web
D12Empty + error UIWeb
D13Home marketing multi-secciónWeb
D14Seed demo + NeonData
D15Design tokens chalk/ink/limeWeb + Paper
D16Paper referencia §1–§5Docs + Paper
D17Suite docs 00–20Docs
D18README run 3008/4200Docs

2. Backlog L1+ (misma complejidad, mejoras)

IDÍtemPrioridadNotas
B01canActivate guards AngularP1UX auth
B02Filtros por status en inboxP2Query opcional API
B03Captcha / rate limit POSTP1anti-spam
B04Confirm dialog cancelP2
B05Toast de éxitoP3
B06Playwright smoke S1–S12P1CI
B07Skeleton loadingP3
B08mailto/tel en detailP2ops
B09Checkbox privacidadP1RGPD
B10Página 404 amigableP3
B11API URL por environmentP1deploy

3. Backlog L2 (requiere brief nuevo)

IDÍtemDependencia
C01Calendario clases + aforoSchedule
C02Multi-coach asignaciónFK coachId
C03Email transaccionalprovider
C04Lookup público por códigoauthz acotada
C05Notas internas coachschema
C06Export CSVreporting
C07Roles ADMINpermisos

4. Backlog L3+ (explícito)

IDÍtem
E01Multi-sede tenant
E02Pagos cuotas
E03Push / app nativa
E04Marketplace multi-club

5. Explicitamente no-backlog

IdeaRazón
Marketplace de coachesFuera de VOLTA club único
ERP socios completoComplejidad otra producto
Agro / legal / logisticsOtros cases de la serie

6. Orden de ataque recomendado (si hay continuidad)

  1. B01 guards + B06 e2e + B11 env
  2. B08 contact shortcuts + B02 filtros
  3. B03 + B09 si hay tráfico real
  4. Evaluar brief L2 calendario

7. Trazabilidad

OrigenÍtems
Day brief must-haveD01–D18
Doc 15 roadmap nextB01–B11
Doc 15 laterC01–C07, E01–E04

20-implementation.md

Abrir documento

20 — Implementación — VOLTA

1. Resumen ejecutivo técnico

CampoValor
App path/Users/cristian/orca/volta-app/
APINestJS · puerto 3008 · prefijo /api
WebAngular standalone · puerto 4200
DBNeon PostgreSQL · Prisma · delicate-mountain-11765167
AuthJWT Bearer · role COACH
DominioUser, ClassRequest
Fecha2026-08-08
GitHubCriscode2022/volta-app (puede estar pendiente de push)

2. Cómo arrancar

cd /Users/cristian/orca/volta-app
npm install --prefix apps/api
npm install --prefix apps/web
# Configurar apps/api/.env con DATABASE_URL y JWT_SECRET
npm --prefix apps/api run prisma:migrate   # o script documentado en README app
npm --prefix apps/api run prisma:seed
npm run api   # http://localhost:3008
npm run web   # http://localhost:4200

Credenciales

RolEmailPassword
COACHcoach@volta.clubpassword123

3. Módulos API implementados

Auth

  • POST /api/auth/login
  • Valida email/password; compara bcrypt; emite JWT con sub, email, role.
  • JwtStrategy + JwtAuthGuard protegen requests de lectura/escritura coach.

Requests

MétodoRutaAuthNotas
POST/api/requestsNocreate público; status NEW; code VO-
GET/api/requestsJWTlist createdAt desc
GET/api/requests/stats/summaryJWTtotal, open, byStatus
GET/api/requests/:idJWT404 si no existe
PATCH/api/requests/:id/statusJWTbody { status }

Prisma

Enums Role, RequestStatus, ClassType; modelos alineados a doc 05; migración init; seed 1 coach + 5 requests.

4. Frontend implementado

PáginaResponsabilidad
HomePagemarketing, hero, clases, horarios, footer
JoinPageform create público
SuccessPageconfirmación + código
LoginPageform → ApiService.login → navigate inbox
InboxPagestats + list + empty/error + logout
RequestDetailPageget + patch status

ApiService centraliza base URL http://localhost:3008/api, token storage (volta_token, volta_user), métodos HTTP tipados (ClassRequest, stats, User).

5. Decisiones de implementación

DecisiónRazón
Puerto API 3008Evitar colisión con otros daily apps
Soft auth en páginasSimple L1; API sigue siendo autoridad
preferredDay/Slot StringMenos fricción timezone en L1
Sin FK User–ClassRequestForm anónimo
Código VO-MMDD-randomReferencia oral corta
Templates inline standaloneVelocidad daily; páginas autocontenidas
Stats endpoint propioEvolución y menos lógica en cliente
Ruta stats/summary antes de :idEvitar captura de param

6. Variables de entorno

VariableServicioDescripción
DATABASE_URLAPINeon connection string
JWT_SECRETAPIFirma tokens
PORTAPIopcional, 3008

Web: URL de API en ApiService (default localhost:3008).

7. Smoke de implementación (mínimo)

  1. Seed OK en consola (VOLTA seed OK).
  2. Login coach 200.
  3. List length ≥ 1.
  4. Create request 201 + code.
  5. Patch CONTACTED/CONFIRMED 200.
  6. GET sin token 401.
  7. Web muestra badges y home con Syne/lime.

8. Estructura de ficheros clave

volta-app/
├── apps/api/
│   ├── prisma/schema.prisma
│   ├── prisma/seed.ts
│   └── src/
│       ├── main.ts
│       ├── app.module.ts
│       ├── auth/
│       │   ├── auth.controller.ts
│       │   ├── auth.service.ts
│       │   ├── jwt.strategy.ts
│       │   └── jwt-auth.guard.ts
│       ├── requests/
│       │   ├── requests.controller.ts
│       │   └── requests.service.ts
│       └── prisma/
├── apps/web/
│   ├── tailwind.config.js
│   └── src/app/
│       ├── app.routes.ts
│       ├── core/api.service.ts
│       └── pages/
│           ├── home/
│           ├── join/
│           ├── success/
│           ├── login/
│           ├── inbox/
│           └── request-detail/
└── package.json

9. Alineación case ↔ app

DocEvidencia en código
05 data modelschema.prisma enums y models
04 flowsroutes + controller methods
08 DStailwind colors + fontFamily
09 contentstrings en templates home/join/…
00 paperURLs en README case

10. Notas de cierre técnico

  • Vertical slice L1 runnable local con Neon.
  • No quedan features must-have del brief sin implementar.
  • Mejoras (guards Angular, e2e, rate limit) viven en backlog L1+, no como deuda de cierre del día.