workspace/projects/gamilit/docs/01-fase-alcance-inicial/EAI-001-fundamentos/historias-usuario/US-FUND-001-autenticacion-basica-jwt.md
rckrdmrd ea1879f4ad feat: Initial workspace structure with multi-level Git configuration
- Configure workspace Git repository with comprehensive .gitignore
- Add Odoo as submodule for ERP reference code
- Include documentation: SETUP.md, GIT-STRUCTURE.md
- Add gitignore templates for projects (backend, frontend, database)
- Structure supports independent repos per project/subproject level

Workspace includes:
- core/ - Reusable patterns, modules, orchestration system
- projects/ - Active projects (erp-suite, gamilit, trading-platform, etc.)
- knowledge-base/ - Reference code and patterns (includes Odoo submodule)
- devtools/ - Development tools and templates
- customers/ - Client implementations template

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-08 10:44:23 -06:00

11 KiB
Raw Permalink Blame History

US-FUND-001: Autenticación básica con JWT

Épica: EAI-001 - Fundamentos Sprint: Mes 1, Semana 1 Story Points: 8 SP Presupuesto: $2,900 MXN Prioridad: Alta (Alcance Inicial) Estado: Completada (Mes 1)


Descripción

Como estudiante o profesor, quiero poder registrarme, iniciar sesión y recuperar mi contraseña para acceder de forma segura a la plataforma GAMILIT.

Contexto del Alcance Inicial: En el MVP se implementó un sistema de autenticación básico con JWT que soporta dos roles fijos: estudiante y profesor. El sistema incluye funcionalidades esenciales de autenticación sin características avanzadas como 2FA o SSO, que serán agregadas en extensiones futuras.


Criterios de Aceptación

  • CA-01: El sistema permite registrar nuevos usuarios con email, contraseña y rol (estudiante/profesor)
  • CA-02: Al registrarse, se valida que el email sea único y tenga formato válido
  • CA-03: Las contraseñas se almacenan hasheadas con bcrypt (min. 10 rounds)
  • CA-04: El login genera un JWT token válido por 24 horas
  • CA-05: El JWT incluye el userId y rol en el payload
  • CA-06: Existe un endpoint de recuperación de contraseña que envía email con token temporal
  • CA-07: El token de recuperación expira en 1 hora
  • CA-08: El sistema permite cerrar sesión (invalidación de token en frontend)
  • CA-09: Las contraseñas deben tener mínimo 8 caracteres
  • CA-10: Se retorna mensaje de error apropiado para credenciales inválidas

Especificaciones Técnicas

Backend (NestJS)

Endpoints:

POST /api/auth/register (public self-service)
- Body: { email, password, first_name?, last_name? }
- Response: { user, accessToken }
- Note: role is assigned automatically as 'student'

POST /api/auth/login
- Body: { email, password }
- Response: { user, accessToken }

POST /api/auth/forgot-password
- Body: { email }
- Response: { message: "Email sent" }

POST /api/auth/reset-password
- Body: { token, newPassword }
- Response: { message: "Password updated" }

GET /api/auth/me
- Headers: Authorization: Bearer {token}
- Response: { user }

Servicios:

  • AuthService: Lógica de autenticación (register, login, validateUser)
  • JwtService: Generación y validación de tokens JWT
  • MailService: Envío de emails de recuperación

Entidades:

@Entity('users')
class User {
  id: string (UUID)
  email: string (unique)
  password: string (hashed)
  first_name: string  // snake_case for DB consistency
  last_name: string   // snake_case for DB consistency
  role: 'student' | 'teacher'
  createdAt: Date
  updatedAt: Date
}

@Entity('password_reset_tokens')
class PasswordResetToken {
  id: string (UUID)
  userId: string (FK to users)
  token: string
  expiresAt: Date
  used: boolean
}

Guards:

  • JwtAuthGuard: Protege rutas que requieren autenticación
  • RolesGuard: Valida roles específicos (estudiante/profesor)

Frontend (React + Vite)

Componentes:

  • LoginForm.tsx: Formulario de inicio de sesión
  • RegisterForm.tsx: Formulario de registro
  • ForgotPasswordForm.tsx: Solicitud de recuperación
  • ResetPasswordForm.tsx: Establecer nueva contraseña

Estado (Zustand):

interface AuthStore {
  user: User | null
  token: string | null
  isAuthenticated: boolean
  login: (email, password) => Promise<void>
  register: (data) => Promise<void>
  logout: () => void
  forgotPassword: (email) => Promise<void>
  resetPassword: (token, newPassword) => Promise<void>
}

Rutas:

  • /login - Página de inicio de sesión
  • /register - Página de registro
  • /forgot-password - Solicitar recuperación
  • /reset-password/:token - Restablecer contraseña

Almacenamiento:

  • Token JWT guardado en localStorage
  • Auto-login si existe token válido al cargar la app

Seguridad

  • Contraseñas hasheadas con bcrypt (10 rounds)
  • JWT firmado con secret key (desde ENV)
  • Tokens de recuperación de un solo uso
  • Validación de email en backend y frontend
  • Rate limiting en endpoints de auth (10 req/min)

Dependencias

Antes:

  • Ninguna (primera historia del proyecto)

Después:

  • US-FUND-002 (Perfiles de usuario - requiere autenticación)
  • US-FUND-003 (Dashboard - requiere autenticación)
  • US-FUND-005 (Sistema de sesiones - extiende esta funcionalidad)

Definición de Hecho (DoD)

  • Código implementado y revisado
  • Tests unitarios para AuthService (>80% coverage)
  • Tests E2E para flujos de autenticación
  • Validación de seguridad (password hashing, JWT signing)
  • Documentación de API en Swagger
  • Probado en ambiente de desarrollo
  • Sin warnings de seguridad en audit

Notas del Alcance Inicial

  • Solo 2 roles básicos: estudiante y profesor
  • JWT simple sin refresh tokens (agregado en US-FUND-005)
  • Recuperación de contraseña por email (requiere configuración SMTP)
  • Sin autenticación social (Google, Facebook)
  • Sin autenticación de dos factores (2FA)
  • ⚠️ Extensión futura: EXT-001-Admin (roles adicionales: admin, superadmin)
  • ⚠️ Extensión futura: EXT-002-Security (2FA, SSO, OAuth)

Tareas de Implementación

Backend (Estimado: 16h, Real: 17h)

Total Backend: 17h (~4.25 SP)

  • Tarea B.1: Configuración JWT y entidades base - Estimado: 4h, Real: 4.5h

    • Subtarea B.1.1: Instalar dependencias (@nestjs/jwt, @nestjs/passport, bcrypt) - 0.5h
    • Subtarea B.1.2: Crear entidad User con campos de autenticación - 1h
    • Subtarea B.1.3: Crear entidad PasswordResetToken - 0.5h
    • Subtarea B.1.4: Generar migración de base de datos - 0.5h
    • Subtarea B.1.5: Configurar JwtModule con variables de entorno - 1h
    • Subtarea B.1.6: Crear JwtStrategy para validación de tokens - 1h
  • Tarea B.2: Implementación de AuthService - Estimado: 5h, Real: 5.5h

    • Subtarea B.2.1: Método register con hash de contraseña (bcrypt 10 rounds) - 2h
    • Subtarea B.2.2: Método login con validación de credenciales - 1.5h
    • Subtarea B.2.3: Método validateUser para JWT strategy - 1h
    • Subtarea B.2.4: Generación de tokens JWT con payload (userId, role) - 1h
  • Tarea B.3: Endpoints de autenticación - Estimado: 4h, Real: 4h

    • Subtarea B.3.1: POST /auth/register con validación de DTO - 1.5h
    • Subtarea B.3.2: POST /auth/login con manejo de errores - 1h
    • Subtarea B.3.3: GET /auth/me con JWT guard - 1h
    • Subtarea B.3.4: Documentación Swagger de endpoints - 0.5h
  • Tarea B.4: Sistema de recuperación de contraseña - Estimado: 3h, Real: 3h

    • Subtarea B.4.1: MailService para envío de emails - 1h
    • Subtarea B.4.2: POST /auth/forgot-password con generación de token - 1h
    • Subtarea B.4.3: POST /auth/reset-password con validación de token - 1h

Frontend (Estimado: 8h, Real: 9h)

Total Frontend: 9h (~2.25 SP)

  • Tarea F.1: Componentes de autenticación - Estimado: 5h, Real: 5.5h

    • Subtarea F.1.1: Componente LoginForm con validación - 1.5h
    • Subtarea F.1.2: Componente RegisterForm con validación - 1.5h
    • Subtarea F.1.3: Componente ForgotPasswordForm - 1h
    • Subtarea F.1.4: Componente ResetPasswordForm - 1h
    • Subtarea F.1.5: Páginas de rutas (/login, /register, etc.) - 0.5h
  • Tarea F.2: Estado de autenticación con Zustand - Estimado: 3h, Real: 3.5h

    • Subtarea F.2.1: Crear AuthStore con interface - 1h
    • Subtarea F.2.2: Implementar métodos login/register/logout - 1.5h
    • Subtarea F.2.3: Persistencia de token en localStorage - 0.5h
    • Subtarea F.2.4: Hook useAuth para acceso al store - 0.5h

Testing (Estimado: 6h, Real: 5.5h)

Total Testing: 5.5h (~1.4 SP)

  • Tarea T.1: Tests unitarios backend - Estimado: 3h, Real: 2.5h

    • Subtarea T.1.1: Tests de AuthService (hash, JWT, validación) - 1.5h
    • Subtarea T.1.2: Tests de MailService - 0.5h
    • Subtarea T.1.3: Tests de guards (JwtAuthGuard) - 0.5h
  • Tarea T.2: Tests E2E - Estimado: 2h, Real: 2h

    • Subtarea T.2.1: Tests de endpoints de auth (register, login) - 1h
    • Subtarea T.2.2: Tests de recuperación de contraseña - 0.5h
    • Subtarea T.2.3: Tests de protección de rutas (401) - 0.5h
  • Tarea T.3: Tests frontend - Estimado: 1h, Real: 1h

    • Subtarea T.3.1: Tests de componentes de formularios - 0.5h
    • Subtarea T.3.2: Tests de AuthStore - 0.5h

Deployment (Estimado: 2h, Real: 2h)

Total Deployment: 2h (~0.5 SP)

  • Tarea D.1: Configuración de ambiente - Estimado: 1h, Real: 1h

    • Subtarea D.1.1: Variables de entorno JWT_SECRET - 0.25h
    • Subtarea D.1.2: Configuración SMTP para emails - 0.5h
    • Subtarea D.1.3: Secrets management en .env - 0.25h
  • Tarea D.2: Deploy y validación - Estimado: 1h, Real: 1h

    • Subtarea D.2.1: Deploy a staging - 0.5h
    • Subtarea D.2.2: Smoke tests de autenticación - 0.25h
    • Subtarea D.2.3: Validación de seguridad (bcrypt, JWT) - 0.25h

Resumen de Horas

Categoría Estimado Real Variación
Backend 16h 17h +6.25%
Frontend 8h 9h +12.5%
Testing 6h 5.5h -8.3%
Deployment 2h 2h 0%
TOTAL 32h 33.5h +4.7%

Validación: 8 SP × 4h/SP = 32 horas estimadas


Cronograma Real

Sprint: Sprint 1-2 (05-16 Agosto 2024) Fecha Inicio Real: 05 Agosto 2024 Fecha Fin Real: 08 Agosto 2024 Estado: Completada Notas: La implementación tomó 0.5 días adicionales debido a la configuración del servicio de email SMTP que requirió troubleshooting. El sistema de autenticación quedó robusto con todas las validaciones de seguridad implementadas.


Testing

Tests Unitarios

describe('AuthService', () => {
  it('should hash password on register')
  it('should generate JWT on successful login')
  it('should throw error for invalid credentials')
  it('should create password reset token')
  it('should validate reset token expiry')
})

Tests E2E

describe('Auth API', () => {
  it('POST /auth/register - success')
  it('POST /auth/register - duplicate email')
  it('POST /auth/login - success')
  it('POST /auth/login - invalid credentials')
  it('GET /auth/me - with valid token')
  it('GET /auth/me - without token (401)')
})

Estimación

Desglose de Esfuerzo (8 SP = ~3 días):

  • Backend setup + JWT config: 1 día
  • Endpoints de auth: 1 día
  • Frontend forms + store: 0.5 días
  • Password reset flow: 0.5 días
  • Testing: 0.5 días
  • Ajustes y documentación: 0.5 días

Riesgos:

  • Configuración de email service puede requerir tiempo adicional
  • Validaciones de seguridad requieren atención especial

Creado: 2025-11-02 Actualizado: 2025-11-02 Responsable: Equipo Backend + Frontend