erp-core/docs/06-test-plans/TEST-PLAN-MGN-001-fundamentos.md

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

  1. Autenticación: Login con email/contraseña, JWT tokens, refresh tokens, logout
  2. Autorización: RBAC (Role-Based Access Control) con permisos granulares por modelo
  3. Gestión de Usuarios: CRUD usuarios, perfiles, cambio de contraseña, reset password
  4. Multi-Tenancy: Schema-level isolation, tenant context switching
  5. Gestión de Sesiones: Sesiones activas, logout, expiración automática
  6. Row Level Security: RLS policies en PostgreSQL, field-level security
  7. Registro de Usuarios: Signup/auto-registro con validación de email
  8. 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:

  1. 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)
  2. 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)
  3. 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)
  4. Tenants API (6 tests):

    • POST /api/v1/tenants (3 tests)
    • PUT /api/v1/tenants/:id (2 tests)
    • GET /api/v1/tenants/me (1 test)
  5. 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:

  1. 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)
  2. 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
  3. 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
  4. 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:

  1. Navegar a https://acme-corp.erp.local/login
  2. Ingresar email: "admin@acme.com"
  3. Ingresar password: "Admin123!"
  4. 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:

  1. 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:

  1. 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:

  1. Login como "user@tenant-a.com" desde subdomain tenant-a
  2. GET /api/v1/products (debería retornar productos de tenant A solamente)
  3. 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:

  1. 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:

  1. 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:

  1. Navegar a /roles
  2. Click en "Crear Rol"
  3. Ingresar nombre: "Vendedor"
  4. Seleccionar permisos: products:read, sales:create, sales:read, sales:update
  5. 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:

  1. Login como "viewer@acme.com"
  2. 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:

  1. Navegar a /login
  2. Click en "¿Olvidaste tu contraseña?"
  3. Ingresar email: "user@acme.com"
  4. Click en "Enviar"
  5. Abrir email recibido
  6. Click en link de reset password
  7. Ingresar nueva contraseña: "NewPass123!"
  8. Confirmar contraseña: "NewPass123!"
  9. Click en "Cambiar Contraseña"
  10. 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:

  1. Navegar a https://acme-corp.erp.local/signup
  2. Ingresar email: "newuser@example.com"
  3. Ingresar password: "Secure123!"
  4. Ingresar nombre: "Juan Pérez"
  5. 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:

  1. JWT firmado con algoritmo seguro (RS256 o HS256)
  2. JWT secret tiene mínimo 256 bits de entropía
  3. JWT tiene claim exp (expiration) configurado
  4. JWT no contiene información sensible (password, etc.)
  5. JWT no puede ser alterado sin invalidar firma
  6. Refresh token es diferente de access token
  7. Refresh token se almacena hasheado en BD
  8. 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:

  1. Más de 10 login attempts en 1 minuto desde misma IP resulta en 429 (rate limit)
  2. 5 failed login attempts bloquea cuenta por 30 minutos
  3. CAPTCHA aparece después de 3 failed attempts (Fase 2)
  4. 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:

  1. SELECT sin filtro tenant_id retorna solo datos del tenant actual
  2. INSERT sin tenant_id falla o usa tenant_id del contexto
  3. UPDATE de registro de otro tenant falla
  4. DELETE de registro de otro tenant falla
  5. 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

Redis: Session storage

  • Port: 6379
  • DB: 1 (test database)

SMTP: Mailhog (test email server)

  • Port: 1025 (SMTP)
  • Port: 8025 (Web UI)

6.2 URLs

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:

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