academia/docs/entregables/01-analisis/riesgos/AN-005-riesgos-tecnicos.md

12 KiB

AN-005: Análisis de Riesgos Técnicos

Proyecto: Sistema de Registro de Estudiantes - Inter Rapidísimo Rol: Líder Técnico Fecha: 2026-01-07


1. Resumen

Identificación y evaluación de riesgos técnicos que podrían impactar el desarrollo, calidad o entrega del sistema. Cada riesgo incluye probabilidad, impacto y estrategia de mitigación.


2. Matriz de Evaluación

Probabilidad / Impacto Bajo (1) Medio (2) Alto (3)
Alta (3) 3 6 9
Media (2) 2 4 6
Baja (1) 1 2 3

Clasificación:

  • Crítico: 6-9 (acción inmediata)
  • Moderado: 3-5 (plan de mitigación)
  • Bajo: 1-2 (monitorear)

3. Riesgos Identificados

RT-001: Complejidad de Validaciones Cruzadas

Atributo Valor
ID RT-001
Categoría Desarrollo
Probabilidad Alta (3)
Impacto Alto (3)
Score 9 - Crítico

Descripción: Las validaciones de negocio (máximo 3 materias + no repetir profesor) requieren consultas cruzadas entre entidades. Una implementación incorrecta puede generar condiciones de carrera o validaciones inconsistentes.

Escenarios de Riesgo:

  1. Dos inscripciones concurrentes del mismo estudiante
  2. Validación en frontend que no se replica en backend
  3. Race condition al verificar profesor duplicado

Estrategia de Mitigación:

Acción Responsable Plazo
Implementar validaciones en Domain Service (única fuente de verdad) Dev Senior Sprint 1
Usar transacciones con nivel de aislamiento Serializable Dev Senior Sprint 1
Tests de concurrencia con múltiples threads QA Sprint 1
Lock optimista con RowVersion en Enrollment Dev Sprint 1

Código de Mitigación:

// Transacción con locking
await using var transaction = await _context.Database
    .BeginTransactionAsync(IsolationLevel.Serializable);

var student = await _context.Students
    .Include(s => s.Enrollments)
    .ThenInclude(e => e.Subject)
    .FirstOrDefaultAsync(s => s.Id == command.StudentId);

// Validaciones en dominio
_enrollmentService.ValidateEnrollment(student, subject);

await _context.SaveChangesAsync();
await transaction.CommitAsync();

RT-002: Integración Frontend-Backend (GraphQL)

Atributo Valor
ID RT-002
Categoría Integración
Probabilidad Media (2)
Impacto Alto (3)
Score 6 - Crítico

Descripción: GraphQL introduce complejidad adicional en la integración. Errores en el esquema, types incorrectos o problemas de N+1 queries pueden afectar rendimiento y desarrollo.

Escenarios de Riesgo:

  1. Mismatch entre schema GraphQL y DTOs
  2. N+1 queries sin DataLoaders
  3. Errores de tipos en Apollo Angular
  4. Over-fetching o under-fetching de datos

Estrategia de Mitigación:

Acción Responsable Plazo
Generar tipos TypeScript desde schema (codegen) Dev Frontend Sprint 1
Implementar DataLoaders para todas las relaciones Dev Backend Sprint 1
Configurar GraphQL Voyager para visualizar schema Dev Sprint 1
Tests de integración GraphQL con Banana Cake Pop QA Sprint 1

Configuración DataLoader:

// DataLoader para evitar N+1
public class SubjectByIdDataLoader : BatchDataLoader<int, Subject>
{
    protected override async Task<IReadOnlyDictionary<int, Subject>> LoadBatchAsync(
        IReadOnlyList<int> keys, CancellationToken ct)
    {
        return await _context.Subjects
            .Where(s => keys.Contains(s.Id))
            .ToDictionaryAsync(s => s.Id, ct);
    }
}

RT-003: Manejo de Concurrencia

Atributo Valor
ID RT-003
Categoría Arquitectura
Probabilidad Media (2)
Impacto Alto (3)
Score 6 - Crítico

Descripción: Múltiples usuarios podrían intentar inscribirse en la misma materia simultáneamente, generando conflictos o violaciones de reglas de negocio.

Escenarios de Riesgo:

  1. Dos estudiantes inscriben la última plaza disponible
  2. Estudiante inscribe 4ta materia por request concurrente
  3. Datos obsoletos en UI mientras otro usuario modifica

Estrategia de Mitigación:

Acción Responsable Plazo
Implementar Optimistic Concurrency (RowVersion) Dev Backend Sprint 1
Revalidar en backend siempre (no confiar en frontend) Dev Backend Sprint 1
Mostrar toast de "datos actualizados" en conflictos Dev Frontend Sprint 2
Tests de stress con k6 QA Sprint 2

Implementación:

// Entidad con concurrencia optimista
public class Student
{
    [Timestamp]
    public byte[] RowVersion { get; set; }
}

// Manejo de conflicto
catch (DbUpdateConcurrencyException)
{
    return Result.Failure("CONCURRENT_MODIFICATION");
}

RT-004: Rendimiento de Consultas Anidadas

Atributo Valor
ID RT-004
Categoría Rendimiento
Probabilidad Media (2)
Impacto Medio (2)
Score 4 - Moderado

Descripción: Consultas GraphQL anidadas (estudiantes → inscripciones → materias → profesores) pueden generar queries pesadas si no se optimizan.

Escenarios de Riesgo:

  1. Query de todos los estudiantes con todas sus relaciones
  2. Timeouts en consultas sin límite de profundidad
  3. Consumo excesivo de memoria en serialización

Estrategia de Mitigación:

Acción Responsable Plazo
Configurar límite de profundidad en HotChocolate (max 5) Dev Backend Sprint 1
Implementar paginación en queries de listas Dev Backend Sprint 1
Indexar campos de búsqueda (Email, ProfessorId) DBA Sprint 1
Query complexity analyzer Dev Backend Sprint 2

Configuración:

services.AddGraphQLServer()
    .SetMaxAllowedExecutionDepth(5)
    .SetPagingOptions(new PagingOptions
    {
        MaxPageSize = 50,
        DefaultPageSize = 20
    });

RT-005: Curva de Aprendizaje del Stack

Atributo Valor
ID RT-005
Categoría Equipo
Probabilidad Alta (3)
Impacto Bajo (1)
Score 3 - Moderado

Descripción: El stack incluye tecnologías relativamente nuevas (HotChocolate, Angular Signals, Apollo Angular) que pueden requerir tiempo de aprendizaje.

Tecnologías con Curva:

  • HotChocolate (GraphQL .NET)
  • Mapster (alternativa a AutoMapper)
  • Angular Signals
  • Apollo Angular

Estrategia de Mitigación:

Acción Responsable Plazo
Documentar patrones y ejemplos en wiki Tech Lead Sprint 1
Code reviews detallados en PRs Senior Dev Continuo
Spike técnico para DataLoaders Dev Backend Sprint 1
Usar generador de código Apollo Dev Frontend Sprint 1

RT-006: Seguridad en GraphQL

Atributo Valor
ID RT-006
Categoría Seguridad
Probabilidad Baja (1)
Impacto Alto (3)
Score 3 - Moderado

Descripción: GraphQL expone un endpoint flexible que puede ser abusado con queries maliciosas (deeply nested, introspection en prod, DoS).

Escenarios de Riesgo:

  1. Query extremadamente anidada consume recursos
  2. Introspection expone schema sensible
  3. Mutation masiva sin rate limiting

Estrategia de Mitigación:

Acción Responsable Plazo
Deshabilitar introspection en producción DevOps Deploy
Configurar query complexity limits Dev Backend Sprint 1
Rate limiting por IP (10 req/s) DevOps Sprint 2
Persisted queries en producción Dev Backend Sprint 3

Configuración:

services.AddGraphQLServer()
    .AddMaxComplexityRule(100)  // Límite de complejidad
    .AddMaxExecutionDepthRule(5)
    .ModifyOptions(o =>
    {
        // Deshabilitar introspection en prod
        if (!env.IsDevelopment())
            o.EnableSchemaIntrospection = false;
    });

RT-007: Migración y Seeding de Datos

Atributo Valor
ID RT-007
Categoría Base de Datos
Probabilidad Baja (1)
Impacto Medio (2)
Score 2 - Bajo

Descripción: Los datos iniciales (5 profesores, 10 materias) deben estar correctamente relacionados. Errores en seeding pueden romper reglas de negocio.

Escenarios de Riesgo:

  1. Profesor asignado a más de 2 materias
  2. IDs inconsistentes entre migraciones
  3. Datos duplicados en re-ejecución de seed

Estrategia de Mitigación:

Acción Responsable Plazo
Seeding idempotente (verificar existencia) Dev Backend Sprint 1
Validación post-seed en tests QA Sprint 1
Script de verificación de integridad DBA Sprint 1

RT-008: Testing de Reglas de Negocio

Atributo Valor
ID RT-008
Categoría Calidad
Probabilidad Media (2)
Impacto Medio (2)
Score 4 - Moderado

Descripción: Las reglas de negocio complejas requieren cobertura exhaustiva de tests. Casos edge pueden quedar sin probar.

Casos Edge Críticos:

  1. Inscribir materia 3 cuando ya tiene 2 del mismo "tipo"
  2. Cancelar inscripción y re-inscribir rápidamente
  3. Estudiante con 3 materias intenta cambiar una

Estrategia de Mitigación:

Acción Responsable Plazo
Property-based testing para combinaciones QA Sprint 1
Matriz de casos de prueba exhaustiva QA Sprint 1
Mutation testing (Stryker) QA Sprint 2

4. Matriz de Riesgos Consolidada

ID Riesgo Prob Impacto Score Prioridad
RT-001 Validaciones cruzadas 3 3 9 1
RT-002 Integración GraphQL 2 3 6 2
RT-003 Concurrencia 2 3 6 3
RT-004 Rendimiento queries 2 2 4 4
RT-005 Curva aprendizaje 3 1 3 5
RT-006 Seguridad GraphQL 1 3 3 6
RT-008 Testing reglas 2 2 4 7
RT-007 Seeding datos 1 2 2 8

5. Plan de Contingencia

Si RT-001 se materializa (validaciones fallan):

  1. Rollback a versión anterior
  2. Fix inmediato en Domain Service
  3. Agregar tests de regresión
  4. Re-deploy con verificación manual

Si RT-002 se materializa (integración falla):

  1. Fallback a REST API simple
  2. Schema manual sin codegen
  3. Simplificar queries GraphQL

Si RT-003 se materializa (race conditions):

  1. Lock pesimista temporal
  2. Queue de inscripciones
  3. Revisión manual de conflictos

6. Indicadores de Monitoreo

Riesgo Indicador Umbral de Alerta
RT-001 Inscripciones fallidas por validación > 5%
RT-002 Errores GraphQL 500 > 1%
RT-003 DbUpdateConcurrencyException > 10/hora
RT-004 Query time P95 > 500ms
RT-006 Requests bloqueados por rate limit > 100/hora

7. Revisión de Riesgos

Fecha Revisor Acción
Sprint 1 Review Tech Lead Evaluar RT-001, RT-002
Sprint 2 Review Tech Lead Evaluar RT-003, RT-004
Pre-deploy QA Lead Validar mitigaciones

8. Aprobación

Rol Nombre Fecha Firma
Líder Técnico Sistema 2026-01-07
Arquitecto Pendiente - -
Project Manager Pendiente - -