20 — Implementación — VOLTA
1. Resumen ejecutivo técnico
| Campo | Valor |
|---|
| App path | /Users/cristian/orca/volta-app/ |
| API | NestJS · puerto 3008 · prefijo /api |
| Web | Angular standalone · puerto 4200 |
| DB | Neon PostgreSQL · Prisma · delicate-mountain-11765167 |
| Auth | JWT Bearer · role COACH |
| Dominio | User, ClassRequest |
| Fecha | 2026-08-08 |
| GitHub | Criscode2022/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
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étodo | Ruta | Auth | Notas |
|---|
| POST | /api/requests | No | create público; status NEW; code VO- |
| GET | /api/requests | JWT | list createdAt desc |
| GET | /api/requests/stats/summary | JWT | total, open, byStatus |
| GET | /api/requests/:id | JWT | 404 si no existe |
| PATCH | /api/requests/:id/status | JWT | body { status } |
Prisma
Enums Role, RequestStatus, ClassType; modelos alineados a doc 05; migración init; seed 1 coach + 5 requests.
4. Frontend implementado
| Página | Responsabilidad |
|---|
| HomePage | marketing, hero, clases, horarios, footer |
| JoinPage | form create público |
| SuccessPage | confirmación + código |
| LoginPage | form → ApiService.login → navigate inbox |
| InboxPage | stats + list + empty/error + logout |
| RequestDetailPage | get + 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ón | Razón |
|---|
| Puerto API 3008 | Evitar colisión con otros daily apps |
| Soft auth en páginas | Simple L1; API sigue siendo autoridad |
| preferredDay/Slot String | Menos fricción timezone en L1 |
| Sin FK User–ClassRequest | Form anónimo |
| Código VO-MMDD-random | Referencia oral corta |
| Templates inline standalone | Velocidad daily; páginas autocontenidas |
| Stats endpoint propio | Evolución y menos lógica en cliente |
Ruta stats/summary antes de :id | Evitar captura de param |
6. Variables de entorno
| Variable | Servicio | Descripción |
|---|
DATABASE_URL | API | Neon connection string |
JWT_SECRET | API | Firma tokens |
PORT | API | opcional, 3008 |
Web: URL de API en ApiService (default localhost:3008).
7. Smoke de implementación (mínimo)
- Seed OK en consola (
VOLTA seed OK).
- Login coach 200.
- List length ≥ 1.
- Create request 201 + code.
- Patch CONTACTED/CONFIRMED 200.
- GET sin token 401.
- 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
| Doc | Evidencia en código |
|---|
| 05 data model | schema.prisma enums y models |
| 04 flows | routes + controller methods |
| 08 DS | tailwind colors + fontFamily |
| 09 content | strings en templates home/join/… |
| 00 paper | URLs 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.