# US-MGN001-001: Login con Email y Password

## Identificacion

| Campo | Valor |
|-------|-------|
| **ID** | US-MGN001-001 |
| **Modulo** | MGN-001 Auth |
| **Sprint** | Sprint 1 |
| **Prioridad** | P0 - Critica |
| **Story Points** | 8 |
| **Estado** | Ready |
| **Autor** | System |
| **Fecha** | 2025-12-05 |

---

## Historia de Usuario

**Como** usuario del sistema ERP
**Quiero** poder iniciar sesion con mi email y contraseña
**Para** acceder a las funcionalidades del sistema de forma segura

---

## Descripcion

El usuario necesita un mecanismo seguro para autenticarse en el sistema utilizando sus credenciales (email y contraseña). Al autenticarse exitosamente, recibira tokens JWT que le permitiran acceder a los recursos protegidos.

### Contexto

- Primera interaccion del usuario con el sistema
- Puerta de entrada a todas las funcionalidades
- Base de la seguridad del sistema

---

## Criterios de Aceptacion

### Escenario 1: Login exitoso

```gherkin
Given un usuario registrado con email "user@example.com"
  And password "SecurePass123!"
  And el usuario no esta bloqueado
  And el usuario esta activo
When el usuario envia sus credenciales al endpoint /api/v1/auth/login
Then el sistema responde con status 200
  And el body contiene "accessToken" de tipo string
  And el body contiene "refreshToken" de tipo string
  And el body contiene "user" con id, email, firstName, lastName, roles
  And se establece cookie httpOnly "refresh_token"
  And se registra el login en session_history
```

### Escenario 2: Login con email incorrecto

```gherkin
Given un email "noexiste@example.com" que no existe en el sistema
When el usuario intenta hacer login con ese email
Then el sistema responde con status 401
  And el mensaje es "Credenciales invalidas"
  And NO se revela que el email no existe
  And se registra el intento fallido en login_attempts
```

### Escenario 3: Login con password incorrecto

```gherkin
Given un usuario registrado con email "user@example.com"
  And el password correcto es "SecurePass123!"
When el usuario intenta hacer login con password "wrongpassword"
Then el sistema responde con status 401
  And el mensaje es "Credenciales invalidas"
  And se incrementa failed_login_attempts del usuario
  And se registra el intento fallido en login_attempts
```

### Escenario 4: Cuenta bloqueada por intentos fallidos

```gherkin
Given un usuario con email "user@example.com"
  And el usuario tiene 5 intentos fallidos de login
  And el campo locked_until es una fecha futura
When el usuario intenta hacer login con credenciales correctas
Then el sistema responde con status 423
  And el mensaje indica "Cuenta bloqueada"
  And se indica el tiempo restante de bloqueo
```

### Escenario 5: Cuenta inactiva

```gherkin
Given un usuario con email "inactive@example.com"
  And el campo is_active del usuario es false
When el usuario intenta hacer login
Then el sistema responde con status 403
  And el mensaje es "Cuenta inactiva"
```

### Escenario 6: Validacion de campos

```gherkin
Given un request al endpoint de login
When el email no es un email valido
Then el sistema responde con status 400
  And el mensaje indica "Email invalido"

When el password tiene menos de 8 caracteres
Then el sistema responde con status 400
  And el mensaje indica "Password debe tener minimo 8 caracteres"

When el email esta vacio
Then el sistema responde con status 400
  And el mensaje indica "Email es requerido"
```

### Escenario 7: Desbloqueo automatico

```gherkin
Given un usuario con cuenta bloqueada
  And el tiempo de bloqueo (30 minutos) ha pasado
When el usuario intenta hacer login con credenciales correctas
Then el sistema permite el login
  And resetea failed_login_attempts a 0
  And limpia locked_until
```

---

## Mockup / Wireframe

```
+------------------------------------------------------------------+
|                         ERP SUITE                                 |
|                                                                   |
|                  ╔═══════════════════════════╗                   |
|                  ║      INICIAR SESION       ║                   |
|                  ╚═══════════════════════════╝                   |
|                                                                   |
|                  Correo electronico                              |
|                  +---------------------------+                   |
|                  | user@example.com          |                   |
|                  +---------------------------+                   |
|                                                                   |
|                  Contraseña                                       |
|                  +---------------------------+                   |
|                  | ••••••••••••             |  [👁]              |
|                  +---------------------------+                   |
|                                                                   |
|                  [ ] Recordar sesion                             |
|                                                                   |
|                  [===== INICIAR SESION =====]                   |
|                                                                   |
|                  ¿Olvidaste tu contraseña?                       |
|                                                                   |
+------------------------------------------------------------------+

Estados de UI:
┌─────────────────────────────────────────────────────────────────┐
│ Estado: Loading                                                  │
│ - Boton deshabilitado                                           │
│ - Spinner visible en boton                                      │
│ - Campos deshabilitados                                         │
└─────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────┐
│ Estado: Error                                                    │
│ - Toast rojo con mensaje de error                               │
│ - Campos con borde rojo si invalidos                            │
│ - Texto de ayuda debajo del campo                               │
└─────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────┐
│ Estado: Bloqueado                                                │
│ - Mensaje: "Cuenta bloqueada. Intenta en XX minutos"            │
│ - Enlace a "¿Necesitas ayuda?"                                  │
└─────────────────────────────────────────────────────────────────┘
```

---

## Notas Tecnicas

### API

```typescript
// Request
POST /api/v1/auth/login
Content-Type: application/json
X-Tenant-Id: optional-if-single-tenant

{
  "email": "user@example.com",
  "password": "SecurePass123!"
}

// Response 200
{
  "accessToken": "eyJhbGciOiJSUzI1NiIs...",
  "refreshToken": "eyJhbGciOiJSUzI1NiIs...",
  "tokenType": "Bearer",
  "expiresIn": 900,
  "user": {
    "id": "uuid",
    "email": "user@example.com",
    "firstName": "John",
    "lastName": "Doe",
    "roles": ["admin"]
  }
}

// Set-Cookie: refresh_token=...; HttpOnly; Secure; SameSite=Strict; Max-Age=604800
```

### Validaciones

| Campo | Regla | Mensaje Error |
|-------|-------|---------------|
| email | Required, IsEmail | "Email es requerido" / "Email invalido" |
| password | Required, MinLength(8), MaxLength(128) | "Password es requerido" / "Password debe tener minimo 8 caracteres" |

### Seguridad

- Bcrypt con salt rounds = 12
- Rate limiting: 10 requests/minuto por IP
- No revelar si email existe
- Tokens firmados con RS256

---

## Definicion de Done

- [ ] Endpoint POST /api/v1/auth/login implementado
- [ ] Validaciones de DTO funcionando
- [ ] Login exitoso retorna tokens JWT
- [ ] Login fallido registra intento
- [ ] Bloqueo despues de 5 intentos
- [ ] Desbloqueo automatico despues de 30 min
- [ ] Cookie httpOnly para refresh token
- [ ] Registro en session_history
- [ ] Tests unitarios (>80% coverage)
- [ ] Tests e2e pasando
- [ ] Documentacion Swagger actualizada
- [ ] Code review aprobado

---

## Dependencias

### Requiere

| Item | Descripcion |
|------|-------------|
| Tabla users | Con campos email, password_hash, is_active |
| Tabla login_attempts | Para registro de intentos |
| Tabla session_history | Para auditoria |
| TokenService | Para generar tokens JWT |

### Bloquea

| Item | Descripcion |
|------|-------------|
| US-MGN001-002 | Logout (necesita sesion) |
| US-MGN001-003 | Refresh token (necesita login) |
| Todas las features | Requieren autenticacion |

---

## Estimacion

| Tarea | Horas |
|-------|-------|
| Backend: AuthService.login() | 4h |
| Backend: Validaciones y errores | 2h |
| Backend: Tests unitarios | 3h |
| Frontend: LoginPage | 4h |
| Frontend: authStore | 2h |
| Frontend: Tests | 2h |
| **Total** | **17h** |

---

## Referencias

- [RF-AUTH-001](../../01-requerimientos/RF-auth/RF-AUTH-001.md) - Requerimiento funcional
- [DDL-SPEC-core_auth](../../02-modelado/database-design/DDL-SPEC-core_auth.md) - Esquema BD
- [ET-auth-backend](../../02-modelado/especificaciones-tecnicas/ET-auth-backend.md) - Spec tecnica

---

## Historial

| Version | Fecha | Autor | Cambios |
|---------|-------|-------|---------|
| 1.0 | 2025-12-05 | System | Creacion inicial |
