27 KiB
TEST PLAN - MGN-001: Fundamentos
Módulo: MGN-001 - Fundamentos Sprint: Sprint 1-5 (Semanas 1-10) Story Points: 68 SP User Stories: 16 US Fecha: 2025-11-24 QA Owner: TBD Estado: Draft
1. RESUMEN DEL MÓDULO
1.1 Descripción
El módulo MGN-001 Fundamentos es la base crítica del ERP Genérico. Provee los servicios core de autenticación, autorización, gestión de usuarios, roles, permisos y multi-tenancy con aislamiento a nivel de schema.
Este es el módulo más crítico (P0) ya que todos los demás módulos dependen de él. Sin autenticación funcional, el sistema no puede operar.
1.2 Funcionalidades Principales
- Autenticación: Login con email/contraseña, JWT tokens, refresh tokens, logout
- Autorización: RBAC (Role-Based Access Control) con permisos granulares por modelo
- Gestión de Usuarios: CRUD usuarios, perfiles, cambio de contraseña, reset password
- Multi-Tenancy: Schema-level isolation, tenant context switching
- Gestión de Sesiones: Sesiones activas, logout, expiración automática
- Row Level Security: RLS policies en PostgreSQL, field-level security
- Registro de Usuarios: Signup/auto-registro con validación de email
- Gestión de Roles: CRUD roles, asignación de permisos CRUD por modelo
1.3 Dependencias
Módulos requeridos: Ninguno (es el primer módulo)
Datos maestros necesarios:
- Al menos 1 tenant seed con subdomain configurado
- Al menos 1 usuario administrador seed
- Roles base: admin, user, viewer
- Permisos base definidos en código
Servicios externos:
- PostgreSQL 16 con extensión pgcrypto
- Redis (para session storage y rate limiting)
- SMTP server (para reset password emails)
2. ALCANCE DEL TESTING
2.1 En Alcance
Funcionalidades a testear:
- ✅ Login con email y contraseña (happy path + error paths)
- ✅ Refresh token para renovar JWT
- ✅ Logout y cierre de sesión
- ✅ CRUD de roles y permisos
- ✅ Validación de permisos en runtime (guards/middleware)
- ✅ CRUD de usuarios
- ✅ Gestión de perfil propio y cambio de contraseña
- ✅ Reset de contraseña (forgot password flow)
- ✅ Signup/auto-registro de usuarios
- ✅ Creación y configuración de tenants
- ✅ Schema-level isolation (tenant no ve datos de otro tenant)
- ✅ Tenant context switching (multi-empresa)
- ✅ Gestión de sesiones activas
- ✅ RLS policies (Row Level Security)
- ✅ Field-level security (campos sensibles)
- ✅ Bloqueo de cuenta por intentos fallidos
- ✅ Rate limiting de endpoints de auth
Testing no funcional:
- ✅ Performance de login (<300ms p95)
- ✅ Security (OWASP Top 10, JWT validation, bcrypt)
- ✅ Tenant isolation (crítico)
- ✅ Concurrencia (múltiples logins simultáneos)
- ✅ Rate limiting (protección contra brute force)
2.2 Fuera de Alcance
Exclusiones explícitas:
- ❌ OAuth2/SAML (Fase 2 - no MVP)
- ❌ 2FA/MFA (Fase 2 - no MVP)
- ❌ CAPTCHA (Fase 2)
- ❌ Biometric authentication
- ❌ Login con redes sociales (Google, Facebook)
- ❌ LDAP/Active Directory integration
2.3 Assumptions
- PostgreSQL 16 está instalado y configurado correctamente
- Redis está disponible para session storage
- SMTP server está configurado para envío de emails
- Subdomain routing funciona correctamente (nginx/traefik)
- Environment variables están configuradas (JWT_SECRET, DATABASE_URL, etc.)
3. ESTRATEGIA DE TESTING
3.1 Tipos de Tests
Unit Tests
Coverage objetivo: >80% por archivo
Herramientas:
- Jest (backend)
- Vitest (frontend)
Total estimado: 96 unit tests
Backend (60 tests):
- AuthService: 20 tests
- login method (8 tests: success, invalid email, wrong password, user inactive, tenant inactive, locked account, rate limit, tenant isolation)
- validateUser method (5 tests)
- generateTokens method (3 tests)
- refreshToken method (4 tests)
- UsersService: 15 tests
- create, update, delete, findByEmail, changePassword
- RolesService: 10 tests
- CRUD roles, assign permissions
- PermissionsGuard: 8 tests
- @RequirePermissions decorator validation
- Utils/Helpers: 7 tests
- Password hashing, JWT signing/verification
Frontend (36 tests):
- LoginForm component: 8 tests
- Render form, submit with valid data, show errors, loading state
- useAuthStore (Zustand): 6 tests
- setUser, setTokens, logout, persist to localStorage
- authApi client: 8 tests
- login, refresh, logout API calls
- UserList component: 6 tests
- RoleList component: 6 tests
- ProtectedRoute component: 2 tests
Integration Tests
Coverage: Todos los endpoints API + componentes con API
Herramientas:
- Supertest (API testing)
- React Testing Library (component + API)
- TestContainers (PostgreSQL real instance)
Total estimado: 48 integration tests
Test suites:
-
Auth API (16 tests):
- POST /api/v1/auth/login (6 tests)
- POST /api/v1/auth/refresh (3 tests)
- POST /api/v1/auth/logout (2 tests)
- POST /api/v1/auth/forgot-password (3 tests)
- POST /api/v1/auth/reset-password (2 tests)
-
Users API (12 tests):
- GET /api/v1/users (2 tests)
- POST /api/v1/users (3 tests)
- PUT /api/v1/users/:id (3 tests)
- DELETE /api/v1/users/:id (2 tests)
- PATCH /api/v1/users/me/password (2 tests)
-
Roles API (8 tests):
- GET /api/v1/roles (2 tests)
- POST /api/v1/roles (3 tests)
- PUT /api/v1/roles/:id (2 tests)
- DELETE /api/v1/roles/:id (1 test)
-
Tenants API (6 tests):
- POST /api/v1/tenants (3 tests)
- PUT /api/v1/tenants/:id (2 tests)
- GET /api/v1/tenants/me (1 test)
-
Database + RLS (6 tests):
- Tenant isolation queries
- RLS policies enforcement
- Field-level security
E2E Tests
Coverage: Flujos críticos de usuario
Herramienta: Playwright
Total estimado: 16 E2E tests
User journeys:
-
Authentication Flow (6 tests):
- Login exitoso y redirect a dashboard
- Login con credenciales inválidas
- Logout y redirect a login page
- Reset password flow completo
- Cuenta bloqueada por intentos fallidos
- Tenant isolation (user de tenant A no accede a tenant B)
-
User Management Flow (4 tests):
- Admin crea usuario, asigna rol, usuario puede login
- Usuario cambia su propia contraseña
- Admin desactiva usuario, usuario no puede login
- Admin elimina usuario
-
Role Management Flow (3 tests):
- Admin crea rol con permisos, asigna a usuario, usuario accede solo a recursos permitidos
- Admin revoca permiso, usuario pierde acceso
- Usuario sin permiso recibe 403
-
Multi-Tenancy Flow (3 tests):
- Usuario accede a tenant A, crea registro, cambia a tenant B, no ve registro de tenant A
- Signup crea usuario en tenant correcto según subdomain
- Tenant context switch funciona correctamente
4. TEST CASES
4.1 Casos de Prueba Funcionales
TC-MGN-001-001: Login Exitoso con Credenciales Válidas
US: US-MGN-001-001-001 Prioridad: P0 Tipo: Functional Nivel: E2E
Precondiciones:
- Tenant "acme-corp" existe y está activo
- Usuario "admin@acme.com" existe con password "Admin123!" y está activo
Pasos:
- Navegar a https://acme-corp.erp.local/login
- Ingresar email: "admin@acme.com"
- Ingresar password: "Admin123!"
- Click en botón "Iniciar Sesión"
Resultado Esperado:
- JWT token es retornado y almacenado en localStorage
- Usuario es redirigido a /dashboard
- failed_login_attempts se resetea a 0
- Registro se crea en auth.login_history con success=true
Criterios de Aceptación Validados:
- AC-001: Usuario con credenciales válidas puede autenticarse
- AC-002: JWT token contiene user_id, tenant_id, roles, permissions
TC-MGN-001-002: Login Fallido por Contraseña Incorrecta
US: US-MGN-001-001-001 Prioridad: P0 Tipo: Functional Nivel: Integration
Precondiciones:
- Usuario "admin@acme.com" existe
Pasos:
- POST /api/v1/auth/login con body: { email: "admin@acme.com", password: "WrongPassword" }
Resultado Esperado:
- Status code: 401 Unauthorized
- Error message: "Credenciales inválidas"
- failed_login_attempts incrementa en 1
- Registro en auth.login_history con success=false
Criterios de Aceptación Validados:
- AC-003: Sistema incrementa contador de intentos fallidos
TC-MGN-001-003: Cuenta Bloqueada por Intentos Fallidos
US: US-MGN-001-001-001 Prioridad: P0 Tipo: Functional Nivel: Integration
Precondiciones:
- Usuario "admin@acme.com" tiene failed_login_attempts=5 y last_failed_login < 30 minutos
Pasos:
- POST /api/v1/auth/login con credenciales correctas
Resultado Esperado:
- Status code: 429 Too Many Requests
- Error message: "Cuenta bloqueada temporalmente. Intente en X minutos"
- No valida contraseña (retorna inmediatamente)
Criterios de Aceptación Validados:
- AC-004: Sistema bloquea cuenta después de 5 intentos fallidos por 30 minutos
TC-MGN-001-004: Tenant Isolation (Usuario no Accede a Otro Tenant)
US: US-MGN-001-004-002 Prioridad: P0 Tipo: Security Nivel: Integration
Precondiciones:
- Tenant A tiene usuario "user@tenant-a.com"
- Tenant B tiene 10 registros en tabla products
Pasos:
- Login como "user@tenant-a.com" desde subdomain tenant-a
- GET /api/v1/products (debería retornar productos de tenant A solamente)
- Intentar GET /api/v1/products con header X-Tenant-ID: tenant-b
Resultado Esperado:
- GET /api/v1/products retorna solo productos de tenant A
- Intentar acceder con otro tenant_id resulta en 403 Forbidden o ignora el header
- Queries SQL automáticamente filtran por tenant_id
Criterios de Aceptación Validados:
- AC-005: Usuarios de diferentes tenants están completamente aislados
- AC-006: RLS policies previenen acceso cross-tenant
TC-MGN-001-005: Usuario Inactivo No Puede Login
US: US-MGN-001-001-001 Prioridad: P0 Tipo: Functional Nivel: Integration
Precondiciones:
- Usuario "inactive@acme.com" tiene status='inactive'
Pasos:
- POST /api/v1/auth/login con credenciales correctas de usuario inactivo
Resultado Esperado:
- Status code: 403 Forbidden
- Error message: "Cuenta inactiva. Contacte al administrador"
- No se genera JWT token
Criterios de Aceptación Validados:
- AC-007: Usuario inactivo no puede autenticarse
TC-MGN-001-006: Refresh Token Renueva JWT
US: US-MGN-001-001-002 Prioridad: P0 Tipo: Functional Nivel: Integration
Precondiciones:
- Usuario autenticado con refresh token válido
Pasos:
- POST /api/v1/auth/refresh con body: { refreshToken: "valid_refresh_token" }
Resultado Esperado:
- Status code: 200 OK
- Nuevo accessToken es retornado
- Nuevo refreshToken es retornado (rotation)
- Refresh token anterior es invalidado
Criterios de Aceptación Validados:
- AC-008: Refresh token permite renovar JWT sin re-autenticación
TC-MGN-001-007: Admin Crea Rol con Permisos
US: US-MGN-001-002-001 Prioridad: P0 Tipo: Functional Nivel: E2E
Precondiciones:
- Usuario admin autenticado
Pasos:
- Navegar a /roles
- Click en "Crear Rol"
- Ingresar nombre: "Vendedor"
- Seleccionar permisos: products:read, sales:create, sales:read, sales:update
- Click en "Guardar"
Resultado Esperado:
- Rol "Vendedor" se crea en auth.roles
- Permisos se guardan en auth.role_permissions
- Rol aparece en lista de roles
- Notificación de éxito se muestra
Criterios de Aceptación Validados:
- AC-009: Admin puede crear roles personalizados
- AC-010: Permisos CRUD se asignan por modelo
TC-MGN-001-008: Usuario Sin Permiso Recibe 403
US: US-MGN-001-002-003 Prioridad: P0 Tipo: Functional Nivel: Integration
Precondiciones:
- Usuario "viewer@acme.com" tiene rol "Viewer" con solo permisos de lectura
Pasos:
- Login como "viewer@acme.com"
- POST /api/v1/products (intentar crear producto)
Resultado Esperado:
- Status code: 403 Forbidden
- Error message: "No tiene permiso para realizar esta acción"
- Producto no se crea
Criterios de Aceptación Validados:
- AC-011: Usuarios solo acceden a recursos según sus permisos
- AC-012: Guards validan permisos en runtime
TC-MGN-001-009: Reset Password Flow Completo
US: US-MGN-001-005-001 Prioridad: P0 Tipo: Functional Nivel: E2E
Precondiciones:
- Usuario "user@acme.com" existe
- SMTP server configurado
Pasos:
- Navegar a /login
- Click en "¿Olvidaste tu contraseña?"
- Ingresar email: "user@acme.com"
- Click en "Enviar"
- Abrir email recibido
- Click en link de reset password
- Ingresar nueva contraseña: "NewPass123!"
- Confirmar contraseña: "NewPass123!"
- Click en "Cambiar Contraseña"
- Login con nueva contraseña
Resultado Esperado:
- Email se envía a user@acme.com con token de reset
- Link de reset es válido por 1 hora
- Password se actualiza en BD (hasheado)
- Login con nueva contraseña es exitoso
- Token de reset se invalida después de uso
Criterios de Aceptación Validados:
- AC-013: Usuario puede resetear contraseña olvidada vía email
- AC-014: Token de reset expira en 1 hora
- AC-015: Token solo puede usarse una vez
TC-MGN-001-010: Signup Crea Usuario en Tenant Correcto
US: US-MGN-001-006-001 Prioridad: P1 Tipo: Functional Nivel: E2E
Precondiciones:
- Tenant "acme-corp" permite signup (allow_signup=true)
Pasos:
- Navegar a https://acme-corp.erp.local/signup
- Ingresar email: "newuser@example.com"
- Ingresar password: "Secure123!"
- Ingresar nombre: "Juan Pérez"
- Click en "Registrarse"
Resultado Esperado:
- Usuario se crea en tenant "acme-corp"
- Email de verificación se envía
- Usuario puede login después de verificar email
- Usuario se crea con rol "User" por defecto
Criterios de Aceptación Validados:
- AC-016: Signup crea usuario en tenant correcto según subdomain
- AC-017: Email de verificación se envía
- AC-018: Usuario tiene rol "User" por defecto
4.2 Casos de Prueba No Funcionales
TC-MGN-001-PERF-001: Performance del Endpoint POST /auth/login
Tipo: Performance Herramienta: k6
Objetivo: Response time <300ms (p95)
Escenario:
- 100 usuarios concurrentes
- 1000 login requests/min
- Duración: 5 minutos
- Mix: 90% credenciales válidas, 10% inválidas
Script k6:
import http from 'k6/http';
import { check } from 'k6';
export let options = {
vus: 100,
duration: '5m',
thresholds: {
http_req_duration: ['p(95)<300'],
http_req_failed: ['rate<0.01'],
},
};
export default function () {
const payload = JSON.stringify({
email: 'admin@acme.com',
password: 'Admin123!',
});
const res = http.post('https://api.erp.local/v1/auth/login', payload, {
headers: { 'Content-Type': 'application/json' },
});
check(res, {
'status is 200': (r) => r.status === 200,
'has token': (r) => JSON.parse(r.body).accessToken !== undefined,
});
}
Criterios de Éxito:
- p50: <100ms
- p95: <300ms
- p99: <500ms
- Error rate: <1%
- Throughput: >1000 req/min
TC-MGN-001-SEC-001: JWT Token Security Validation
Tipo: Security Herramienta: Manual + Jest
Objetivo: Validar seguridad de JWT tokens
Test cases:
- JWT firmado con algoritmo seguro (RS256 o HS256)
- JWT secret tiene mínimo 256 bits de entropía
- JWT tiene claim exp (expiration) configurado
- JWT no contiene información sensible (password, etc.)
- JWT no puede ser alterado sin invalidar firma
- Refresh token es diferente de access token
- Refresh token se almacena hasheado en BD
- Refresh token rotation implementado
Resultado Esperado:
- Todos los test cases pasan
- Security scan (Snyk, OWASP ZAP) no reporta vulnerabilidades críticas en auth
TC-MGN-001-SEC-002: Protection Against Brute Force Attacks
Tipo: Security Herramienta: Manual + k6
Objetivo: Validar rate limiting y bloqueo de cuenta
Test cases:
- Más de 10 login attempts en 1 minuto desde misma IP resulta en 429 (rate limit)
- 5 failed login attempts bloquea cuenta por 30 minutos
- CAPTCHA aparece después de 3 failed attempts (Fase 2)
- Logs de failed attempts se registran para detección de ataques
Resultado Esperado:
- Rate limiting funciona correctamente
- Cuenta se bloquea después de 5 intentos
- Logs permiten identificar patrones de ataque
TC-MGN-001-SEC-003: RLS Policy Enforcement
Tipo: Security Herramienta: Integration test + Manual DB queries
Objetivo: Validar que RLS policies previenen acceso cross-tenant
Test cases:
- SELECT sin filtro tenant_id retorna solo datos del tenant actual
- INSERT sin tenant_id falla o usa tenant_id del contexto
- UPDATE de registro de otro tenant falla
- DELETE de registro de otro tenant falla
- RLS bypass solo funciona con service role
Script SQL:
-- Como usuario de tenant A
SET app.tenant_id = 'tenant-a';
SELECT * FROM products; -- Solo productos de tenant A
-- Intentar acceder a tenant B
SET app.tenant_id = 'tenant-b';
SELECT * FROM products; -- Debería fallar o retornar vacío
Resultado Esperado:
- RLS policies previenen acceso cross-tenant en 100% de casos
- Service role puede bypass RLS para migraciones/backups
- Performance de queries con RLS es aceptable (<10% overhead)
5. DATOS DE PRUEBA
5.1 Test Data Requirements
Tenants (3):
{
"tenant-a": {
"subdomain": "tenant-a",
"name": "Acme Corp",
"status": "active",
"plan": "enterprise",
"allow_signup": true
},
"tenant-b": {
"subdomain": "tenant-b",
"name": "Beta Inc",
"status": "active",
"plan": "pro",
"allow_signup": false
},
"tenant-c": {
"subdomain": "tenant-c",
"name": "Gamma LLC",
"status": "inactive",
"plan": "trial",
"allow_signup": false
}
}
Usuarios por Tenant (10):
{
"admin@tenant-a.com": {
"password": "Admin123!",
"role": "admin",
"status": "active",
"tenant_id": "tenant-a"
},
"contador@tenant-a.com": {
"password": "Contador123!",
"role": "accountant",
"status": "active",
"tenant_id": "tenant-a"
},
"vendedor@tenant-a.com": {
"password": "Vendedor123!",
"role": "sales",
"status": "active",
"tenant_id": "tenant-a"
},
"viewer@tenant-a.com": {
"password": "Viewer123!",
"role": "viewer",
"status": "active",
"tenant_id": "tenant-a"
},
"inactive@tenant-a.com": {
"password": "Inactive123!",
"role": "user",
"status": "inactive",
"tenant_id": "tenant-a"
}
}
Roles Base (5):
- admin: Todos los permisos
- accountant: Permisos de módulo financiero
- sales: Permisos de ventas, productos, clientes
- user: Permisos básicos de lectura
- viewer: Solo lectura, sin escritura
Permisos (ejemplos):
- users:create, users:read, users:update, users:delete
- roles:create, roles:read, roles:update, roles:delete
- products:create, products:read, products:update, products:delete
5.2 Data Setup
Script de seed:
npm run seed:test
Contenido de seed script:
// test/seeds/auth.seed.ts
export async function seedAuthData(prisma: PrismaClient) {
// 1. Crear tenants
const tenants = await createTenants(prisma);
// 2. Crear roles
const roles = await createRoles(prisma, tenants);
// 3. Crear permisos
const permissions = await createPermissions(prisma);
// 4. Asignar permisos a roles
await assignPermissionsToRoles(prisma, roles, permissions);
// 5. Crear usuarios
await createUsers(prisma, tenants, roles);
console.log('✅ Auth test data seeded successfully');
}
6. AMBIENTE DE TESTING
6.1 Configuración
Base de datos: PostgreSQL 16 (test DB)
- Database:
erp_test - Schema:
auth,public - Extensions:
pgcrypto,uuid-ossp - RLS enabled en todas las tablas
Backend: NestJS
- Port: 3000
- Mode: test
- JWT_SECRET: test_secret_key_256bits
- DATABASE_URL: postgresql://test:test@localhost:5432/erp_test
Frontend: React + Vite
- Port: 5173
- API_URL: http://localhost:3000/api/v1
- Mode: test
Redis: Session storage
- Port: 6379
- DB: 1 (test database)
SMTP: Mailhog (test email server)
- Port: 1025 (SMTP)
- Port: 8025 (Web UI)
6.2 URLs
- API: http://localhost:3000/api/v1
- Frontend: http://localhost:5173
- Swagger: http://localhost:3000/api/docs
- Mailhog UI: http://localhost:8025
6.3 Environment Variables
# Database
DATABASE_URL=postgresql://test:test@localhost:5432/erp_test
# JWT
JWT_SECRET=test_secret_key_must_be_at_least_256_bits_long
JWT_EXPIRES_IN=8h
REFRESH_TOKEN_EXPIRES_IN=30d
# Redis
REDIS_URL=redis://localhost:6379/1
# Email
SMTP_HOST=localhost
SMTP_PORT=1025
SMTP_USER=test
SMTP_PASSWORD=test
# App
APP_ENV=test
APP_URL=http://localhost:5173
7. SCHEDULE
7.1 Timeline
| Sprint | Actividad | Duración | Responsable | Fecha Estimada |
|---|---|---|---|---|
| Sprint 1 | RF-001, RF-002 (Login, RBAC) | 2 sem | Dev + QA | Semana 2 |
| Sprint 2 | RF-003, RF-005, RF-007 (Users, Reset, Sessions) | 2 sem | Dev + QA | Semana 4 |
| Sprint 3 | RF-004 (Multi-tenancy) | 2 sem | Dev + QA | Semana 6 |
| Sprint 4 | RF-006 (Signup) | 2 sem | Dev + QA | Semana 8 |
| Sprint 5 | RF-008 (RLS) | 2 sem | Dev + QA | Semana 10 |
7.2 Actividades por Sprint
Sprint 1 (Login + RBAC):
- Día 1-3: Desarrollo de US-001-001-001, US-001-001-002, US-001-002-001, US-001-002-002
- Día 4-5: Code review + Integration tests
- Día 6-7: QA testing + E2E tests (TC-001 a TC-003)
- Día 8: Bug fixing
- Día 9: Regression testing
- Día 10: Sprint review + retrospective
Sprint 2 (Users + Sessions):
- Similar estructura, enfocado en US-001-003-001, US-001-003-002, US-001-005-001, etc.
8. ENTRY/EXIT CRITERIA
Entry Criteria
- User Stories del sprint escritas y aprobadas (DoR)
- Test cases escritos en este Test Plan
- Ambiente de QA configurado (DB, Redis, SMTP)
- Test data seed scripts creados
- Código implementado y mergeado a develop
- Unit tests escritos y pasando (>80%)
- Integration tests escritos y pasando
- Code review completado
Exit Criteria
- Todos los test cases ejecutados (160 tests)
- Unit test coverage >80% en módulo MGN-001
- Integration tests 100% pasando (48 tests)
- E2E tests críticos 100% pasando (16 tests)
- Bugs P0/P1 resueltos (100%)
- Bugs P2 documentados en backlog
- Performance tests pasando (p95 <300ms)
- Security tests pasando (JWT, RLS, rate limiting)
- Tenant isolation verificado (100% casos)
- Criterios de aceptación validados por PO
- Documentación Swagger actualizada
- Sprint review completado
9. DEFECT MANAGEMENT
9.1 Severidad de Bugs
P0 - Blocker:
- Sistema de autenticación no funciona (nadie puede login)
- Tenant isolation roto (usuarios ven datos de otros tenants)
- JWT tokens no se generan o son inválidos
- RLS policies no funcionan
- SLA: Fix en 24 horas
P1 - Critical:
- Refresh token no funciona (usuarios deben re-autenticarse cada 8h)
- Reset password no envía email
- Bloqueo de cuenta no funciona (vulnerability)
- Rate limiting no funciona
- SLA: Fix en 3 días
P2 - Major:
- UI de login tiene issues (pero login funciona)
- Mensajes de error no son claros
- Performance de login es lenta (>500ms)
- SLA: Fix en 1 sprint
P3 - Minor:
- Typos en mensajes
- Estilos CSS incorrectos
- Logs no tienen suficiente detalle
- SLA: Backlog (no bloqueante)
9.2 Bug Report Template
**Bug ID:** BUG-MGN-001-001
**Title:** Login falla con credenciales válidas en tenant-b
**Severity:** P0
**Found in:** Sprint 1
**Environment:** QA
**Module:** MGN-001 - Fundamentos
**Steps to Reproduce:**
1. Navegar a https://tenant-b.erp.local/login
2. Ingresar email: "admin@tenant-b.com"
3. Ingresar password: "Admin123!"
4. Click en "Iniciar Sesión"
**Expected Result:**
- JWT token retornado
- Redirect a /dashboard
**Actual Result:**
- Error 500 Internal Server Error
- Log: "tenant_id not found in context"
**Screenshots/Logs:**
[Attach screenshot + server logs]
**Root Cause:**
Tenant context middleware no se ejecuta antes de AuthController
**Assigned to:** Developer 1
**Status:** In Progress
**Fixed in:** PR #123
**Verified by:** QA Engineer
**Closed date:** 2025-11-25
10. RIESGOS ESPECÍFICOS DEL MÓDULO
| Riesgo | Probabilidad | Impacto | Mitigación |
|---|---|---|---|
| Tenant isolation roto | Media | Crítico | Test suite dedicada con 10+ test cases. Manual audit de RLS policies. Penetration testing. |
| JWT secret expuesto en logs | Baja | Crítico | Code review strict. Secrets en env vars, nunca en código. Logging sanitizado. |
| Bcrypt cost factor muy alto | Alta | Alto | Benchmarking de login performance. Cost factor 12 es óptimo (300-500ms). |
| Refresh token leakage | Media | Alto | Almacenar hasheado en BD. Rotation implementado. HttpOnly cookies. |
| Rate limiting bypass | Media | Alto | Rate limit por IP + por user_id. Redis cluster para HA. Monitoring de spikes. |
| RLS policies tienen bugs | Media | Crítico | Extensive testing con queries adversariales. DBA review. PostgreSQL audit logs. |
| Password reset tokens no expiran | Baja | Alto | Expiration en 1 hora implementado. Test case específico (TC-009). |
| Session hijacking | Media | Alto | JWT con short expiry (8h). Refresh token rotation. Device fingerprinting (Fase 2). |
11. MÉTRICAS
11.1 Test Execution Metrics
Total test cases: 160
- Unit: 96
- Integration: 48
- E2E: 16
Executed: 0/160 (0%) Passed: 0/160 (0%) Failed: 0/160 (0%) Blocked: 0/160 (0%) Pass rate: 0% (objetivo: >95%)
11.2 Defect Metrics
Total bugs found: 0
- P0: 0
- P1: 0
- P2: 0
- P3: 0
Defect density: 0 bugs/100 LOC (objetivo: <1)
11.3 Coverage Metrics
Unit test coverage: 0% (objetivo: >80%)
- Backend: 0%
- Frontend: 0%
API coverage: 0/20 endpoints (objetivo: 100%)
E2E coverage: 0/16 journeys (objetivo: 100%)
12. SIGN-OFF
12.1 Test Completion
- All planned tests executed (160/160)
- Exit criteria met
- Test report generated
- Defects documented
- Lessons learned captured
12.2 Approvals
QA Engineer: Nombre: _______________ Firma: _______________ Fecha: _______________
Tech Lead: Nombre: _______________ Firma: _______________ Fecha: _______________
Product Owner: Nombre: _______________ Firma: _______________ Fecha: _______________
13. REFERENCIAS
User Stories:
- US-MGN-001-001-001: Login con Email y Contraseña
- US-MGN-001-001-002: Renovar Token JWT
- US-MGN-001-002-001: Crear y Gestionar Roles
- Ver todas las US de MGN-001
Especificaciones Técnicas:
Referencias:
Versión: 1.0 Última actualización: 2025-11-24 Estado: Draft - Pendiente de aprobación Próxima revisión: Sprint 1 Kickoff