From c86f92d2bb62e0523affc3a2d2c14e235af29a49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Eduardo=20Garc=C3=ADa=20M=C3=A1rquez?= Date: Fri, 9 Jan 2026 08:25:42 -0500 Subject: [PATCH] refactor: rename CLAUDE.md to DEV-GUIDE.md and update references - Rename CLAUDE.md to DEV-GUIDE.md for clearer purpose - Update all documentation references to new filename - Standardize QA report authorship --- CLAUDE.md => DEV-GUIDE.md | 4 ++-- docs/CODE_REVIEW_CHECKLIST.md | 2 +- docs/DEFECTOS_QA.md | 2 +- docs/PLAN_ACTIVIDADES.md | 2 +- .../03-configuracion/DV-001-configuracion-repositorio.md | 2 +- docs/qa/QA-REPORT-2026-01-09-AUTOMATED-TESTS.md | 4 ++-- docs/qa/QA-REPORT-STUDENT-ACTIVATION-FLOW.md | 6 +++--- index.html | 8 ++++---- 8 files changed, 15 insertions(+), 15 deletions(-) rename CLAUDE.md => DEV-GUIDE.md (99%) diff --git a/CLAUDE.md b/DEV-GUIDE.md similarity index 99% rename from CLAUDE.md rename to DEV-GUIDE.md index f9fbcab..f5e11b6 100644 --- a/CLAUDE.md +++ b/DEV-GUIDE.md @@ -1,6 +1,6 @@ -# CLAUDE.md +# DEV-GUIDE.md -Este archivo proporciona orientación a Claude Code (claude.ai/code) para trabajar con el código de este repositorio. +Guía de desarrollo y convenciones del proyecto. ## Contexto diff --git a/docs/CODE_REVIEW_CHECKLIST.md b/docs/CODE_REVIEW_CHECKLIST.md index 7e9b3b9..7e258d7 100644 --- a/docs/CODE_REVIEW_CHECKLIST.md +++ b/docs/CODE_REVIEW_CHECKLIST.md @@ -96,7 +96,7 @@ | Documento | Estado | |-----------|--------| | README.md | ✅ | -| CLAUDE.md | ✅ | +| DEV-GUIDE.md | ✅ | | OWASP_CHECKLIST.md | ✅ | | GraphQL Schema | ✅ (Banana Cake Pop) | diff --git a/docs/DEFECTOS_QA.md b/docs/DEFECTOS_QA.md index 48f615b..12a68b8 100644 --- a/docs/DEFECTOS_QA.md +++ b/docs/DEFECTOS_QA.md @@ -1,7 +1,7 @@ # Reporte de Pruebas Manuales QA **Fecha:** 2026-01-08 -**Tester:** Claude Code +**Tester:** QA Team **Ambiente:** Desarrollo Local (localhost:4200 / localhost:5000) --- diff --git a/docs/PLAN_ACTIVIDADES.md b/docs/PLAN_ACTIVIDADES.md index d6ae00d..9c02b1d 100644 --- a/docs/PLAN_ACTIVIDADES.md +++ b/docs/PLAN_ACTIVIDADES.md @@ -51,7 +51,7 @@ | # | Actividad | Detalle | Rol | Proceso | |---|-----------|---------|-----|---------| -| 3.1 | Inicialización del repositorio | Crear estructura de carpetas, .gitignore, README, CLAUDE.md con convenciones del proyecto | DevOps | DV | +| 3.1 | Inicialización del repositorio | Crear estructura de carpetas, .gitignore, README, DEV-GUIDE.md con convenciones del proyecto | DevOps | DV | | 3.2 | Configuración solución .NET | Crear solución con 4 proyectos (Domain, Application, Infrastructure, GraphQL), referencias entre proyectos | Backend Dev | DV | | 3.3 | Configuración proyecto Angular | ng new con standalone, configurar ESLint, Prettier, paths aliases, Apollo Angular para GraphQL | Frontend Dev | DV | | 3.4 | Configuración de base de datos | Docker compose para SQL Server, scripts de inicialización, connection strings por ambiente | DevOps/DBA | DV | diff --git a/docs/entregables/03-configuracion/DV-001-configuracion-repositorio.md b/docs/entregables/03-configuracion/DV-001-configuracion-repositorio.md index d1317ae..2a4c2a1 100644 --- a/docs/entregables/03-configuracion/DV-001-configuracion-repositorio.md +++ b/docs/entregables/03-configuracion/DV-001-configuracion-repositorio.md @@ -34,7 +34,7 @@ │ └── migrations/ ├── deploy/ │ └── docker/ -├── CLAUDE.md +├── DEV-GUIDE.md ├── README.md └── .gitignore ``` diff --git a/docs/qa/QA-REPORT-2026-01-09-AUTOMATED-TESTS.md b/docs/qa/QA-REPORT-2026-01-09-AUTOMATED-TESTS.md index e6a43b8..80298cc 100644 --- a/docs/qa/QA-REPORT-2026-01-09-AUTOMATED-TESTS.md +++ b/docs/qa/QA-REPORT-2026-01-09-AUTOMATED-TESTS.md @@ -2,7 +2,7 @@ **Fecha:** 2026-01-09 **Versión:** 1.0 -**Ejecutor:** Claude AI + Playwright +**Ejecutor:** Playwright Automation **Ambiente:** Desarrollo Local (localhost:4200 / localhost:5000) --- @@ -224,6 +224,6 @@ npx playwright test activation.spec.ts --- **Firma Digital:** -QA Engineer: Claude AI +QA Engineer: QA Team Fecha: 2026-01-09T07:45:00Z Herramienta: Playwright + xUnit + NSubstitute diff --git a/docs/qa/QA-REPORT-STUDENT-ACTIVATION-FLOW.md b/docs/qa/QA-REPORT-STUDENT-ACTIVATION-FLOW.md index 9735038..4f7cc37 100644 --- a/docs/qa/QA-REPORT-STUDENT-ACTIVATION-FLOW.md +++ b/docs/qa/QA-REPORT-STUDENT-ACTIVATION-FLOW.md @@ -1,7 +1,7 @@ # QA Report: Student Activation Flow **Fecha:** 2026-01-09 -**Tester:** Claude AI (QA Automation) +**Tester:** QA Automation Team **Ambiente:** localhost:4200 (Frontend) / localhost:5000 (Backend) **Navegador:** Chromium (Playwright MCP) **Version:** 1.0.0 @@ -270,6 +270,6 @@ El sistema esta **listo para produccion** en cuanto a este flujo. --- **Firma Digital:** -QA Engineer: Claude AI +QA Engineer: QA Team Fecha: 2026-01-09T06:30:00Z -Herramienta: Playwright MCP + Claude Code +Herramienta: Playwright MCP + QA Team diff --git a/index.html b/index.html index 60f29f5..e1fc2d8 100644 --- a/index.html +++ b/index.html @@ -1301,7 +1301,7 @@ "DI-008 Manejo de Errores": `# DI-008: Estrategia de Manejo de Errores\n\n**Proyecto:** Sistema de Registro de Estudiantes\n**Fecha:** 2026-01-07\n\n---\n\n## 1. Clasificación de Errores\n\n| Tipo | Origen | Manejo | HTTP Code (equiv) |\n|------|--------|--------|-------------------|\n| **Validación** | FluentValidation | Payload.errors | 400 |\n| **Dominio** | Domain Exceptions | Payload.errors | 422 |\n| **Not Found** | Repository | Payload.errors | 404 |\n| **Conflicto** | Concurrencia | Payload.errors | 409 |\n| **Sistema** | Excepciones no manejadas | Error GraphQL | 500 |\n\n---\n\n## 2. Excepciones de Dominio\n\n\`\`\`csharp\n// Base\npublic abstract class DomainException : Exception\n{\n public string Code { get; }\n protected DomainException(string code, string message) : base(message)\n => Code = code;\n}\n\n// Específicas\npublic class MaxEnrollmentsExceededException : DomainException\n{\n public MaxEnrollmentsExceededException()\n : base("MAX_ENROLLMENTS", "Máximo 3 materias permitidas") { }\n}\n\npublic class SameProfessorConstraintException : DomainException\n{\n public SameProfessorConstraintException(string professorName)\n : base("SAME_PROFESSOR", \$"Ya tienes una materia con {professorName}") { }\n}\n\npublic class DuplicateEmailException : DomainException\n{\n public DuplicateEmailException()\n : base("DUPLICATE_EMAIL", "Este email ya está registrado") { }\n}\n\npublic class StudentNotFoundException : DomainException\n{\n public StudentNotFoundException(int id)\n : base("NOT_FOUND", \$"Estudiante {id} no encontrado") { }\n}\n\`\`\`\n\n---\n\n## 3. Patrón Result\n\n\`\`\`csharp\npublic class Result\n{\n public bool IsSuccess { get; }\n public IEnumerable Errors { get; }\n\n protected Result(bool success, IEnumerable? errors = null)\n {\n IsSuccess = success;\n Errors = errors ?? Array.Empty();\n }\n\n public static Result Success() => new(true);\n public static Result Failure(params string[] errors) => new(false, errors);\n}\n\npublic class Result : Result\n{\n public T? Value { get; }\n\n private Result(T value) : base(true) => Value = value;\n private Result(IEnumerable errors) : base(false, errors) { }\n\n public static Result Success(T value) => new(value);\n public static new Result Failure(params string[] errors) => new(errors);\n}\n\`\`\`\n\n---\n\n## 4. Handler con Manejo de Errores\n\n\`\`\`csharp\npublic class EnrollStudentHandler\n{\n public async Task Handle(EnrollInput input)\n {\n try\n {\n var student = await _studentRepo.GetByIdWithEnrollmentsAsync(input.StudentId);\n if (student is null)\n return new EnrollmentPayload(null, ["Estudiante no encontrado"]);\n\n var subject = await _subjectRepo.GetByIdAsync(input.SubjectId);\n if (subject is null)\n return new EnrollmentPayload(null, ["Materia no encontrada"]);\n\n // Validación de dominio\n student.Enroll(subject, _enrollmentPolicy);\n\n await _unitOfWork.SaveChangesAsync();\n\n var dto = student.Enrollments.Last().Adapt();\n return new EnrollmentPayload(dto, null);\n }\n catch (DomainException ex)\n {\n return new EnrollmentPayload(null, [ex.Message]);\n }\n }\n}\n\`\`\`\n\n---\n\n## 5. Error Filter GraphQL (HotChocolate)\n\n\`\`\`csharp\npublic class ErrorFilter : IErrorFilter\n{\n public IError OnError(IError error)\n {\n return error.Exception switch\n {\n DomainException ex => error\n .WithMessage(ex.Message)\n .WithCode(ex.Code),\n\n ValidationException ex => error\n .WithMessage("Errores de validación")\n .WithCode("VALIDATION_ERROR")\n .SetExtension("errors", ex.Errors.Select(e => e.ErrorMessage)),\n\n DbUpdateConcurrencyException => error\n .WithMessage("Los datos fueron modificados por otro usuario")\n .WithCode("CONCURRENCY_ERROR"),\n\n _ => error\n .WithMessage("Error interno del servidor")\n .WithCode("INTERNAL_ERROR")\n };\n }\n}\n\`\`\`\n\n---\n\n## 6. Manejo en Frontend\n\n### Service\n\n\`\`\`typescript\n@Injectable({ providedIn: 'root' })\nexport class ErrorHandlerService {\n private snackBar = inject(MatSnackBar);\n\n handleGraphQLErrors(errors: string[] | undefined): void {\n if (errors?.length) {\n this.snackBar.open(errors[0], 'Cerrar', {\n duration: 5000,\n panelClass: 'error-snackbar'\n });\n }\n }\n\n handleApolloError(error: ApolloError): void {\n const message = error.graphQLErrors[0]?.message ?? 'Error de conexión';\n this.snackBar.open(message, 'Cerrar', { duration: 5000 });\n }\n}\n\`\`\`\n\n### Componente\n\n\`\`\`typescript\nenrollStudent(subjectId: number) {\n this.enrollmentService.enroll({\n studentId: this.studentId(),\n subjectId\n }).subscribe({\n next: ({ data }) => {\n if (data?.enrollStudent.errors?.length) {\n this.errorHandler.handleGraphQLErrors(data.enrollStudent.errors);\n } else {\n this.snackBar.open('Inscripción exitosa', 'OK');\n }\n },\n error: (err) => this.errorHandler.handleApolloError(err)\n });\n}\n\`\`\`\n\n---\n\n## 7. Códigos de Error Estándar\n\n| Código | Mensaje | Acción UI |\n|--------|---------|-----------|\n| \`VALIDATION_ERROR\` | Errores de validación | Mostrar en campos |\n| \`MAX_ENROLLMENTS\` | Máximo 3 materias | Toast + deshabilitar |\n| \`SAME_PROFESSOR\` | Ya tienes materia con X | Toast + deshabilitar |\n| \`DUPLICATE_EMAIL\` | Email ya registrado | Error en campo |\n| \`NOT_FOUND\` | Recurso no encontrado | Redirect + toast |\n| \`CONCURRENCY_ERROR\` | Datos modificados | Refetch + toast |\n| \`INTERNAL_ERROR\` | Error del servidor | Toast genérico |\n\n---\n\n## 8. Logging de Errores\n\n\`\`\`csharp\npublic class LoggingBehavior : IPipelineBehavior\n{\n private readonly ILogger> _logger;\n\n public async Task Handle(TRequest request, ...)\n {\n try\n {\n return await next();\n }\n catch (Exception ex) when (ex is not DomainException)\n {\n _logger.LogError(ex, "Error procesando {Request}", typeof(TRequest).Name);\n throw;\n }\n }\n}\n\`\`\`\n\n**Regla:** NO loguear datos sensibles (email, contraseñas).\n`, }, "Configuración": { - "DV-001 Configuración Repositorio": `# DV-001: Configuración del Repositorio\n\n**Proyecto:** Sistema de Registro de Estudiantes\n**Fecha:** 2026-01-07\n\n---\n\n## 1. Estructura de Carpetas\n\n\`\`\`\n/\n├── src/\n│ ├── backend/\n│ │ ├── Domain/\n│ │ ├── Application/\n│ │ ├── Adapters/\n│ │ │ ├── Driving/Api/\n│ │ │ └── Driven/Persistence/\n│ │ └── Host/\n│ └── frontend/\n│ └── src/app/\n│ ├── core/\n│ ├── shared/\n│ └── features/\n├── tests/\n│ ├── Domain.Tests/\n│ ├── Application.Tests/\n│ ├── Adapters.Tests/\n│ └── e2e/\n├── docs/\n│ └── entregables/\n├── database/\n│ ├── scripts/\n│ └── migrations/\n├── deploy/\n│ └── docker/\n├── CLAUDE.md\n├── README.md\n└── .gitignore\n\`\`\`\n\n---\n\n## 2. .gitignore\n\n\`\`\`gitignore\n# .NET\nbin/\nobj/\n*.user\n*.suo\n.vs/\n*.csproj.user\n\n# Angular\nnode_modules/\ndist/\n.angular/\n.nx/\n\n# IDE\n.idea/\n.vscode/\n*.swp\n\n# Logs\n*.log\nlogs/\n\n# Environment\n.env\n.env.*\n!.env.example\nappsettings.*.json\n!appsettings.json\n!appsettings.Development.json.example\n\n# Database\n*.mdf\n*.ldf\n\n# OS\n.DS_Store\nThumbs.db\n\n# Test\ncoverage/\nTestResults/\n\n# Build\npublish/\n\`\`\`\n\n---\n\n## 3. Comandos de Inicialización\n\n\`\`\`bash\n# Crear repositorio\ngit init\ngit add .\ngit commit -m "chore: initial project structure"\n\n# Crear rama de desarrollo\ngit checkout -b develop\n\n# Estructura de ramas\n# main → producción\n# develop → integración\n# feature/ → nuevas funcionalidades\n# fix/ → correcciones\n\`\`\`\n\n---\n\n## 4. Convenciones de Commits\n\n\`\`\`\n(): \n\nTipos:\n- feat: Nueva funcionalidad\n- fix: Corrección de bug\n- refactor: Refactorización\n- test: Tests\n- docs: Documentación\n- chore: Tareas de mantenimiento\n\nEjemplos:\nfeat(students): add create student mutation\nfix(enrollment): validate professor constraint\ntest(domain): add enrollment policy tests\n\`\`\`\n`, + "DV-001 Configuración Repositorio": `# DV-001: Configuración del Repositorio\n\n**Proyecto:** Sistema de Registro de Estudiantes\n**Fecha:** 2026-01-07\n\n---\n\n## 1. Estructura de Carpetas\n\n\`\`\`\n/\n├── src/\n│ ├── backend/\n│ │ ├── Domain/\n│ │ ├── Application/\n│ │ ├── Adapters/\n│ │ │ ├── Driving/Api/\n│ │ │ └── Driven/Persistence/\n│ │ └── Host/\n│ └── frontend/\n│ └── src/app/\n│ ├── core/\n│ ├── shared/\n│ └── features/\n├── tests/\n│ ├── Domain.Tests/\n│ ├── Application.Tests/\n│ ├── Adapters.Tests/\n│ └── e2e/\n├── docs/\n│ └── entregables/\n├── database/\n│ ├── scripts/\n│ └── migrations/\n├── deploy/\n│ └── docker/\n├── DEV-GUIDE.md\n├── README.md\n└── .gitignore\n\`\`\`\n\n---\n\n## 2. .gitignore\n\n\`\`\`gitignore\n# .NET\nbin/\nobj/\n*.user\n*.suo\n.vs/\n*.csproj.user\n\n# Angular\nnode_modules/\ndist/\n.angular/\n.nx/\n\n# IDE\n.idea/\n.vscode/\n*.swp\n\n# Logs\n*.log\nlogs/\n\n# Environment\n.env\n.env.*\n!.env.example\nappsettings.*.json\n!appsettings.json\n!appsettings.Development.json.example\n\n# Database\n*.mdf\n*.ldf\n\n# OS\n.DS_Store\nThumbs.db\n\n# Test\ncoverage/\nTestResults/\n\n# Build\npublish/\n\`\`\`\n\n---\n\n## 3. Comandos de Inicialización\n\n\`\`\`bash\n# Crear repositorio\ngit init\ngit add .\ngit commit -m "chore: initial project structure"\n\n# Crear rama de desarrollo\ngit checkout -b develop\n\n# Estructura de ramas\n# main → producción\n# develop → integración\n# feature/ → nuevas funcionalidades\n# fix/ → correcciones\n\`\`\`\n\n---\n\n## 4. Convenciones de Commits\n\n\`\`\`\n(): \n\nTipos:\n- feat: Nueva funcionalidad\n- fix: Corrección de bug\n- refactor: Refactorización\n- test: Tests\n- docs: Documentación\n- chore: Tareas de mantenimiento\n\nEjemplos:\nfeat(students): add create student mutation\nfix(enrollment): validate professor constraint\ntest(domain): add enrollment policy tests\n\`\`\`\n`, "DV-002 Configuración .NET": `# DV-002: Configuración Solución .NET 10\n\n**Proyecto:** Sistema de Registro de Estudiantes\n**Fecha:** 2026-01-07\n\n---\n\n## 1. Crear Solución y Proyectos\n\n\`\`\`bash\ncd src/backend\n\n# Crear solución\ndotnet new sln -n StudentEnrollment\n\n# Crear proyectos\ndotnet new classlib -n Domain -f net10.0\ndotnet new classlib -n Application -f net10.0\ndotnet new classlib -n Adapters.Driving.Api -f net10.0\ndotnet new classlib -n Adapters.Driven.Persistence -f net10.0\ndotnet new web -n Host -f net10.0\n\n# Agregar a solución\ndotnet sln add Domain/Domain.csproj\ndotnet sln add Application/Application.csproj\ndotnet sln add Adapters.Driving.Api/Adapters.Driving.Api.csproj\ndotnet sln add Adapters.Driven.Persistence/Adapters.Driven.Persistence.csproj\ndotnet sln add Host/Host.csproj\n\`\`\`\n\n---\n\n## 2. Referencias entre Proyectos\n\n\`\`\`bash\n# Application → Domain\ndotnet add Application reference Domain\n\n# Adapters.Driving.Api → Application\ndotnet add Adapters.Driving.Api reference Application\n\n# Adapters.Driven.Persistence → Domain\ndotnet add Adapters.Driven.Persistence reference Domain\n\n# Host → Todos\ndotnet add Host reference Application\ndotnet add Host reference Adapters.Driving.Api\ndotnet add Host reference Adapters.Driven.Persistence\n\`\`\`\n\n\`\`\`\nHost\n├── Adapters.Driving.Api → Application → Domain\n└── Adapters.Driven.Persistence ────────→ Domain\n\`\`\`\n\n---\n\n## 3. Paquetes NuGet por Proyecto\n\n### Domain (sin dependencias externas)\n\`\`\`xml\n\n\`\`\`\n\n### Application\n\`\`\`xml\n\n\n\n\`\`\`\n\n### Adapters.Driven.Persistence\n\`\`\`xml\n\n\n\n\`\`\`\n\n### Adapters.Driving.Api\n\`\`\`xml\n\n\n\n\`\`\`\n\n### Host\n\`\`\`xml\n\n\`\`\`\n\n---\n\n## 4. Directory.Build.props (Raíz backend)\n\n\`\`\`xml\n\n \n net10.0\n enable\n enable\n true\n \n\n\`\`\`\n\n---\n\n## 5. Program.cs (Host)\n\n\`\`\`csharp\nvar builder = WebApplication.CreateBuilder(args);\n\n// Services\nbuilder.Services.AddApplication();\nbuilder.Services.AddPersistence(builder.Configuration);\nbuilder.Services.AddGraphQLApi();\n\n// CORS\nbuilder.Services.AddCors(options =>\n{\n options.AddDefaultPolicy(policy =>\n policy.WithOrigins("http://localhost:4200")\n .AllowAnyHeader()\n .AllowAnyMethod());\n});\n\nvar app = builder.Build();\n\napp.UseCors();\napp.MapGraphQL();\n\napp.Run();\n\`\`\`\n\n---\n\n## 6. Comandos de Desarrollo\n\n\`\`\`bash\n# Restaurar dependencias\ndotnet restore\n\n# Build\ndotnet build\n\n# Ejecutar\ndotnet run --project Host\n\n# Watch mode\ndotnet watch run --project Host\n\n# Tests\ndotnet test\n\n# Migraciones EF\ndotnet ef migrations add Initial -p Adapters.Driven.Persistence -s Host\ndotnet ef database update -p Adapters.Driven.Persistence -s Host\n\`\`\`\n`, "DV-003 Configuración Angular": `# DV-003: Configuración Proyecto Angular 21\n\n**Proyecto:** Sistema de Registro de Estudiantes\n**Fecha:** 2026-01-07\n\n---\n\n## 1. Crear Proyecto\n\n\`\`\`bash\ncd src/frontend\n\n# Crear proyecto Angular 21\nng new student-enrollment \\\n --standalone \\\n --style=scss \\\n --routing \\\n --ssr=false\n\ncd student-enrollment\n\`\`\`\n\n---\n\n## 2. Instalar Dependencias\n\n\`\`\`bash\n# Angular Material\nng add @angular/material\n\n# Apollo GraphQL\nnpm install apollo-angular @apollo/client graphql\n\n# GraphQL Code Generator\nnpm install -D @graphql-codegen/cli \\\n @graphql-codegen/typescript \\\n @graphql-codegen/typescript-operations \\\n @graphql-codegen/typescript-apollo-angular\n\`\`\`\n\n---\n\n## 3. Estructura de Carpetas\n\n\`\`\`bash\n# Crear estructura\nmkdir -p src/app/core/{services,graphql/{queries,mutations},interceptors}\nmkdir -p src/app/shared/{components,pipes,directives}\nmkdir -p src/app/features/{students,enrollment,classmates}/{pages,components}\n\`\`\`\n\n---\n\n## 4. Configuración Apollo (app.config.ts)\n\n\`\`\`typescript\nimport { ApplicationConfig } from '@angular/core';\nimport { provideRouter } from '@angular/router';\nimport { provideHttpClient } from '@angular/common/http';\nimport { provideApollo } from 'apollo-angular';\nimport { HttpLink } from 'apollo-angular/http';\nimport { InMemoryCache } from '@apollo/client/core';\nimport { inject } from '@angular/core';\nimport { routes } from './app.routes';\nimport { environment } from '../environments/environment';\n\nexport const appConfig: ApplicationConfig = {\n providers: [\n provideRouter(routes),\n provideHttpClient(),\n provideApollo(() => {\n const httpLink = inject(HttpLink);\n return {\n link: httpLink.create({ uri: environment.graphqlUrl }),\n cache: new InMemoryCache(),\n };\n }),\n ],\n};\n\`\`\`\n\n---\n\n## 5. Environment Files\n\n\`\`\`typescript\n// environments/environment.ts\nexport const environment = {\n production: false,\n graphqlUrl: 'https://localhost:5001/graphql',\n};\n\n// environments/environment.prod.ts\nexport const environment = {\n production: true,\n graphqlUrl: '/graphql',\n};\n\`\`\`\n\n---\n\n## 6. GraphQL Codegen (codegen.ts)\n\n\`\`\`typescript\nimport type { CodegenConfig } from '@graphql-codegen/cli';\n\nconst config: CodegenConfig = {\n schema: 'https://localhost:5001/graphql',\n documents: 'src/app/core/graphql/**/*.graphql',\n generates: {\n 'src/app/core/graphql/generated/types.ts': {\n plugins: [\n 'typescript',\n 'typescript-operations',\n 'typescript-apollo-angular',\n ],\n },\n },\n};\n\nexport default config;\n\`\`\`\n\n\`\`\`json\n// package.json scripts\n{\n "scripts": {\n "codegen": "graphql-codegen --config codegen.ts"\n }\n}\n\`\`\`\n\n---\n\n## 7. Path Aliases (tsconfig.json)\n\n\`\`\`json\n{\n "compilerOptions": {\n "paths": {\n "@core/*": ["src/app/core/*"],\n "@shared/*": ["src/app/shared/*"],\n "@features/*": ["src/app/features/*"],\n "@env/*": ["src/environments/*"]\n }\n }\n}\n\`\`\`\n\n---\n\n## 8. Comandos de Desarrollo\n\n\`\`\`bash\n# Desarrollo\nng serve\n\n# Build producción\nng build --configuration production\n\n# Generar tipos GraphQL\nnpm run codegen\n\n# Lint\nng lint\n\n# Tests\nng test\nng test --watch=false --code-coverage\n\n# Generar componente standalone\nng g c features/students/pages/student-list --standalone\n\`\`\`\n`, "DV-004 Configuración Base Datos": `# DV-004: Configuración Base de Datos\n\n**Proyecto:** Sistema de Registro de Estudiantes\n**Fecha:** 2026-01-07\n\n---\n\n## 1. Docker Compose (SQL Server)\n\n\`\`\`yaml\n# deploy/docker/docker-compose.yml\nservices:\n sqlserver:\n image: mcr.microsoft.com/mssql/server\n container_name: sqlserver-students\n environment:\n - ACCEPT_EULA=Y\n - SA_PASSWORD=\${DB_PASSWORD:-Asde71.4Asde71.4}\n - MSSQL_PID=Developer\n ports:\n - "1433:1433"\n volumes:\n - sqlserver-data:/var/opt/mssql\n healthcheck:\n test: /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "\$\$SA_PASSWORD" -C -Q "SELECT 1"\n interval: 10s\n timeout: 5s\n retries: 5\n\nvolumes:\n sqlserver-data:\n\`\`\`\n\n---\n\n## 2. Comandos Docker\n\n\`\`\`bash\n# Iniciar SQL Server\ndocker-compose -f deploy/docker/docker-compose.yml up -d sqlserver\n\n# Ver logs\ndocker logs sqlserver-students\n\n# Conectar a SQL Server\ndocker exec -it sqlserver-students /opt/mssql-tools18/bin/sqlcmd \\\n -S localhost -U sa -P 'Asde71.4Asde71.4' -C\n\n# Detener\ndocker-compose -f deploy/docker/docker-compose.yml down\n\`\`\`\n\n---\n\n## 3. Connection String\n\n\`\`\`json\n// appsettings.Development.json\n{\n "ConnectionStrings": {\n "DefaultConnection": "Server=localhost;Database=StudentEnrollment;User Id=sa;Password=Asde71.4Asde71.4;TrustServerCertificate=True"\n }\n}\n\`\`\`\n\n---\n\n## 4. DbContext Configuration\n\n\`\`\`csharp\n// Adapters/Driven/Persistence/Context/AppDbContext.cs\npublic class AppDbContext : DbContext\n{\n public AppDbContext(DbContextOptions options) : base(options) { }\n\n public DbSet Students => Set();\n public DbSet Subjects => Set();\n public DbSet Professors => Set();\n public DbSet Enrollments => Set();\n\n protected override void OnModelCreating(ModelBuilder modelBuilder)\n {\n modelBuilder.ApplyConfigurationsFromAssembly(typeof(AppDbContext).Assembly);\n }\n}\n\`\`\`\n\n---\n\n## 5. Registrar DbContext\n\n\`\`\`csharp\n// Adapters/Driven/Persistence/DependencyInjection.cs\npublic static class DependencyInjection\n{\n public static IServiceCollection AddPersistence(\n this IServiceCollection services,\n IConfiguration configuration)\n {\n services.AddDbContext(options =>\n options.UseSqlServer(\n configuration.GetConnectionString("DefaultConnection")));\n\n services.AddScoped();\n services.AddScoped();\n services.AddScoped();\n\n return services;\n }\n}\n\`\`\`\n\n---\n\n## 6. Migraciones\n\n\`\`\`bash\n# Crear migración inicial\ndotnet ef migrations add InitialCreate \\\n -p src/backend/Adapters.Driven.Persistence \\\n -s src/backend/Host\n\n# Aplicar migración\ndotnet ef database update \\\n -p src/backend/Adapters.Driven.Persistence \\\n -s src/backend/Host\n\n# Generar script SQL\ndotnet ef migrations script \\\n -p src/backend/Adapters.Driven.Persistence \\\n -s src/backend/Host \\\n -o database/scripts/create.sql\n\`\`\`\n\n---\n\n## 7. Seed Data\n\n\`\`\`csharp\n// Adapters/Driven/Persistence/Seeding/DataSeeder.cs\npublic static class DataSeeder\n{\n public static void Seed(ModelBuilder modelBuilder)\n {\n // Profesores\n modelBuilder.Entity().HasData(\n new { Id = 1, Name = "Dr. García" },\n new { Id = 2, Name = "Dra. Martínez" },\n new { Id = 3, Name = "Dr. López" },\n new { Id = 4, Name = "Dra. Rodríguez" },\n new { Id = 5, Name = "Dr. Hernández" }\n );\n\n // Materias (2 por profesor)\n modelBuilder.Entity().HasData(\n new { Id = 1, Name = "Matemáticas I", Credits = 3, ProfessorId = 1 },\n new { Id = 2, Name = "Matemáticas II", Credits = 3, ProfessorId = 1 },\n new { Id = 3, Name = "Física I", Credits = 3, ProfessorId = 2 },\n new { Id = 4, Name = "Física II", Credits = 3, ProfessorId = 2 },\n new { Id = 5, Name = "Programación I", Credits = 3, ProfessorId = 3 },\n new { Id = 6, Name = "Programación II", Credits = 3, ProfessorId = 3 },\n new { Id = 7, Name = "Base de Datos I", Credits = 3, ProfessorId = 4 },\n new { Id = 8, Name = "Base de Datos II", Credits = 3, ProfessorId = 4 },\n new { Id = 9, Name = "Redes I", Credits = 3, ProfessorId = 5 },\n new { Id = 10, Name = "Redes II", Credits = 3, ProfessorId = 5 }\n );\n }\n}\n\`\`\`\n`, @@ -1316,13 +1316,13 @@ }, "Despliegue": { "Manual de Despliegue": `# Manual de Despliegue\n\n## Requisitos del Sistema\n\n| Componente | Versión Mínima |\n|------------|----------------|\n| .NET SDK | 10.0 |\n| Node.js | 22.x |\n| SQL Server | 2022 |\n| Docker | 24.x |\n| Docker Compose | 2.x |\n\n## Variables de Entorno\n\n### Backend (.NET)\n\n| Variable | Descripción | Ejemplo |\n|----------|-------------|---------|\n| \`ConnectionStrings__DefaultConnection\` | Connection string SQL Server | \`Server=db;Database=StudentEnrollment;...\` |\n| \`ASPNETCORE_ENVIRONMENT\` | Ambiente | \`Production\` |\n| \`ASPNETCORE_URLS\` | URLs de escucha | \`http://+:8080\` |\n| \`JWT_SECRET_KEY\` | **REQUERIDO** - Secret JWT (mín. 32 chars) | \`your-super-secret-key-minimum-32-chars\` |\n| \`JWT_ISSUER\` | Emisor JWT | \`StudentEnrollmentApi\` |\n| \`JWT_AUDIENCE\` | Audiencia JWT | \`StudentEnrollmentApp\` |\n| \`JWT_EXPIRATION_MINUTES\` | Expiración token | \`60\` |\n\n### Frontend (Angular)\n\n| Variable | Descripción | Ejemplo |\n|----------|-------------|---------|\n| \`API_URL\` | URL del backend GraphQL | \`https://api.example.com/graphql\` |\n\n### Desarrollo Local (SQLite)\n\n| Variable | Descripción | Ejemplo |\n|----------|-------------|---------|\n| \`USE_SQLITE\` | Usar SQLite en lugar de SQL Server | \`true\` |\n| \`ConnectionStrings__DefaultConnection\` | Path a archivo SQLite | \`Data Source=./data/dev.db\` |\n\n## Despliegue con Docker\n\n### 1. Estructura de Archivos\n\n\`\`\`\ndeploy/\n└── docker/\n ├── Dockerfile.api\n ├── Dockerfile.frontend\n ├── docker-compose.yml\n └── nginx.conf\n\`\`\`\n\n### 2. Dockerfile Backend\n\n\`\`\`dockerfile\n# deploy/docker/Dockerfile.api\nFROM mcr.microsoft.com/dotnet/sdk:10.0 AS build\nWORKDIR /src\n\nCOPY src/backend/ .\nRUN dotnet restore Host/Host.csproj\nRUN dotnet publish Host/Host.csproj -c Release -o /app\n\nFROM mcr.microsoft.com/dotnet/aspnet:10.0\nWORKDIR /app\nCOPY --from=build /app .\n\n# Non-root user\nRUN adduser --disabled-password --gecos '' appuser\nUSER appuser\n\nEXPOSE 5000\nHEALTHCHECK --interval=30s --timeout=3s \\\n CMD curl -f http://localhost:5000/health || exit 1\n\nENTRYPOINT ["dotnet", "Host.dll"]\n\`\`\`\n\n### 3. Dockerfile Frontend\n\n\`\`\`dockerfile\n# deploy/docker/Dockerfile.frontend\nFROM node:22-alpine AS build\nWORKDIR /app\n\nCOPY src/frontend/package*.json ./\nRUN npm ci\n\nCOPY src/frontend/ .\nRUN npm run build -- --configuration production\n\nFROM nginx:alpine\nCOPY --from=build /app/dist/student-enrollment/browser /usr/share/nginx/html\nCOPY deploy/docker/nginx.conf /etc/nginx/conf.d/default.conf\n\nEXPOSE 80\nHEALTHCHECK --interval=30s --timeout=3s \\\n CMD curl -f http://localhost/ || exit 1\n\`\`\`\n\n### 4. Nginx Configuration\n\n\`\`\`nginx\n# deploy/docker/nginx.conf\nserver {\n listen 80;\n server_name localhost;\n root /usr/share/nginx/html;\n index index.html;\n\n # Gzip\n gzip on;\n gzip_types text/plain text/css application/json application/javascript;\n\n # SPA routing\n location / {\n try_files \$uri \$uri/ /index.html;\n }\n\n # Proxy GraphQL\n location /graphql {\n proxy_pass http://api:5000/graphql;\n proxy_http_version 1.1;\n proxy_set_header Upgrade \$http_upgrade;\n proxy_set_header Connection "upgrade";\n proxy_set_header Host \$host;\n }\n\n # Security headers\n add_header X-Frame-Options "DENY" always;\n add_header X-Content-Type-Options "nosniff" always;\n add_header X-XSS-Protection "1; mode=block" always;\n}\n\`\`\`\n\n### 5. Docker Compose\n\n\`\`\`yaml\n# deploy/docker/docker-compose.yml\nservices:\n db:\n image: mcr.microsoft.com/mssql/server:2022-latest\n environment:\n - ACCEPT_EULA=Y\n - SA_PASSWORD=\${DB_PASSWORD}\n ports:\n - "1433:1433"\n volumes:\n - sqlserver-data:/var/opt/mssql\n healthcheck:\n test: /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P \$\${SA_PASSWORD} -Q "SELECT 1" -C\n interval: 10s\n timeout: 3s\n retries: 10\n\n api:\n build:\n context: ../..\n dockerfile: deploy/docker/Dockerfile.api\n environment:\n - ConnectionStrings__DefaultConnection=Server=db;Database=StudentEnrollment;User Id=sa;Password=\${DB_PASSWORD};TrustServerCertificate=True\n - ASPNETCORE_ENVIRONMENT=Production\n ports:\n - "5000:5000"\n depends_on:\n db:\n condition: service_healthy\n\n frontend:\n build:\n context: ../..\n dockerfile: deploy/docker/Dockerfile.frontend\n ports:\n - "80:80"\n depends_on:\n - api\n\nvolumes:\n sqlserver-data:\n\`\`\`\n\n### 6. Ejecutar\n\n\`\`\`bash\ncd deploy/docker\n\n# Crear archivo .env\necho "DB_PASSWORD=Asde71.4Asde71.4" > .env\n\n# Build e iniciar\ndocker-compose up -d --build\n\n# Ver logs\ndocker-compose logs -f\n\n# Detener\ndocker-compose down\n\`\`\`\n\n## Desarrollo Local (Sin Docker)\n\nScript que levanta backend + frontend con **SQLite** (sin necesidad de SQL Server):\n\n\`\`\`bash\n# Iniciar todo\n./scripts/dev-start.sh start\n\n# Ver estado\n./scripts/dev-start.sh status\n\n# Detener\n./scripts/dev-start.sh stop\n\n# Reiniciar\n./scripts/dev-start.sh restart\n\`\`\`\n\n**Características:**\n- Backend usa SQLite en \`./data/dev.db\`\n- No requiere Docker ni SQL Server\n- Frontend en puerto 4200, Backend en puerto 5000\n- Hot reload habilitado\n- PIDs guardados para cleanup automático\n\n---\n\n## CI/CD Pipeline (Gitea Actions)\n\n**Ubicación:** \`.gitea/workflows/deploy.yaml\`\n\n**Trigger:** Push a rama \`main\`\n\n### Flujo Automático\n\n1. Checkout código en Gitea runner\n2. Setup SSH hacia K3s master\n3. Sync código con rsync (excluye node_modules, dist, etc.)\n4. Build imágenes en paralelo (API + Frontend)\n5. Import a K3s containerd (\`docker save | k3s ctr images import\`)\n6. Apply manifiestos con Kustomize\n7. Rolling restart de deployments\n8. Health checks con curl\n9. Rollback automático si falla\n\n### Secretos Requeridos en Gitea\n\n| Secreto | Descripción |\n|---------|-------------|\n| \`K3S_SSH_KEY\` | Clave SSH privada para conectar a K3s master |\n| \`K3S_SUDO_PASS\` | Password de sudo en K3s host |\n\n### Configuración\n\n\`\`\`yaml\n# Variables de entorno en el workflow\nK3S_HOST: 100.67.198.92 # IP del master (hp62a)\nNAMESPACE: academia\nDOMAIN: academia.ingeniumcodex.com\n\`\`\`\n\n**Tiempo de despliegue:** ~3-5 minutos desde push hasta producción\n\n---\n\n## Despliegue Manual\n\n### Backend\n\n\`\`\`bash\ncd src/backend/Host\n\n# Build producción\ndotnet publish -c Release -o ./publish\n\n# Configurar connection string\nexport ConnectionStrings__DefaultConnection="Server=..."\n\n# Ejecutar migraciones\ndotnet ef database update --project ../Adapters/Driven/Persistence\n\n# Iniciar\ncd publish\ndotnet Host.dll\n\`\`\`\n\n### Frontend\n\n\`\`\`bash\ncd src/frontend\n\n# Build producción\nng build --configuration production\n\n# Los archivos quedan en dist/student-enrollment/browser/\n# Servir con cualquier servidor web (nginx, apache, etc.)\n\`\`\`\n\n## Checklist Pre-Producción\n\n### Seguridad\n\n- [ ] Connection strings en variables de entorno (no en código)\n- [ ] JWT_SECRET_KEY configurado (mínimo 32 caracteres)\n- [ ] HTTPS habilitado\n- [ ] CORS configurado solo para dominios permitidos\n- [ ] Rate limiting activo (30 mutations/min, 100 queries/min)\n- [ ] Security headers configurados\n- [ ] Logs sin datos sensibles (Serilog filtra tokens/passwords)\n\n### Performance\n\n- [ ] Response compression habilitado\n- [ ] Output caching configurado\n- [ ] Bundle Angular optimizado (< 200KB transferidos)\n- [ ] Índices de BD aplicados\n\n### Monitoreo\n\n- [ ] Health checks funcionando (\`/health\`)\n- [ ] Logs centralizados\n- [ ] Métricas de aplicación\n\n### Base de Datos\n\n- [ ] Backup configurado\n- [ ] Migraciones aplicadas\n- [ ] Datos seed cargados (5 profesores, 10 materias)\n\n## URLs de Verificación\n\n| Servicio | URL | Esperado |\n|----------|-----|----------|\n| API Health | \`http://api:8080/health\` | 200 OK |\n| GraphQL Playground | \`http://api:8080/graphql\` | Banana Cake Pop |\n| Frontend | \`http://frontend:80\` | App Angular |\n\n### URLs de Producción (K3s)\n\n| Servicio | URL |\n|----------|-----|\n| Frontend | \`https://academia.ingeniumcodex.com\` |\n| API GraphQL | \`https://academia.ingeniumcodex.com/graphql\` |\n| Health Check | \`https://academia.ingeniumcodex.com/health\` |\n| Login | \`https://academia.ingeniumcodex.com/login\` |\n| Registro | \`https://academia.ingeniumcodex.com/register\` |\n| Dashboard | \`https://academia.ingeniumcodex.com/dashboard\` |\n\n## Rollback\n\n\`\`\`bash\n# Docker\ndocker-compose down\ndocker-compose up -d --no-build # Usa imágenes anteriores\n\n# Manual\n# Restaurar versión anterior de DLLs/archivos\n# Rollback de migraciones si es necesario:\ndotnet ef database update \n\`\`\`\n\n---\n\n## Despliegue en Kubernetes (k3s)\n\n### Estructura de Manifiestos\n\n\`\`\`\ndeploy/k3s/\n├── namespace.yaml # Namespace: academia\n├── secrets.yaml # Credenciales BD\n├── configmap.yaml # Configuración\n├── sqlserver.yaml # Base de datos\n├── api.yaml # Backend GraphQL\n├── frontend.yaml # Frontend Angular\n├── ingress.yaml # Traefik IngressRoute + TLS\n├── networkpolicy.yaml # Seguridad de red (incluido en kustomize)\n├── hpa.yaml # Autoscaling (opcional, no incluido)\n├── kustomization.yaml # Kustomize config\n└── deploy.sh # Script de despliegue\n\`\`\`\n\n**Nota:** \`networkpolicy.yaml\` está incluido en \`kustomization.yaml\` y aplica las siguientes reglas:\n- Default deny: Bloquea todo tráfico entrante por defecto\n- Frontend: Solo acepta tráfico desde Ingress\n- API: Solo acepta tráfico desde Frontend e Ingress\n- SQL Server: Solo acepta conexiones desde API\n\n### Requisitos k3s\n\n- k3s instalado y funcionando\n- kubectl configurado\n- Acceso al cluster\n- (Opcional) cert-manager para TLS\n\n### Despliegue Rápido\n\n\`\`\`bash\ncd deploy/k3s\n\n# Opción 1: Con script\n./deploy.sh all # Build + Deploy\n\n# Opción 2: Con kustomize\nkubectl apply -k .\n\n# Verificar estado\nkubectl get all -n academia\n\`\`\`\n\n### Comandos del Script\n\n\`\`\`bash\n./deploy.sh build # Construir imágenes Docker\n./deploy.sh deploy # Desplegar a k3s\n./deploy.sh status # Ver estado del cluster\n./deploy.sh logs api # Ver logs del API\n./deploy.sh forward # Port-forward para desarrollo\n./deploy.sh delete # Eliminar deployment\n\`\`\`\n\n### Configurar Secrets\n\n\`\`\`bash\n# Editar secrets antes de desplegar\nkubectl create secret generic student-secrets \\\n --namespace=academia \\\n --from-literal=db-password='Asde71.4Asde71.4' \\\n --from-literal=db-connection-string='Server=sqlserver;Database=StudentEnrollment;User Id=sa;Password=Asde71.4Asde71.4;TrustServerCertificate=True' \\\n --dry-run=client -o yaml > secrets.yaml\n\`\`\`\n\n### Acceso Local (Desarrollo)\n\n\`\`\`bash\n# Agregar entrada en /etc/hosts\necho "127.0.0.1 students.local" | sudo tee -a /etc/hosts\n\n# Port forward\n./deploy.sh forward\n\n# Acceder en:\n# - Frontend: http://localhost:8080\n# - API: http://localhost:5000/graphql\n\`\`\`\n\n### Habilitar TLS (Producción)\n\n\`\`\`bash\n# 1. Instalar cert-manager\nkubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.14.0/cert-manager.yaml\n\n# 2. Editar ingress-tls.yaml con tu dominio y email\n\n# 3. Aplicar ingress con TLS\nkubectl apply -f ingress-tls.yaml -n academia\n\`\`\`\n\n### Scaling Manual\n\n\`\`\`bash\n# Escalar API\nkubectl scale deployment student-api -n academia --replicas=3\n\n# Escalar Frontend\nkubectl scale deployment student-frontend -n academia --replicas=2\n\`\`\`\n\n### Monitoreo\n\n\`\`\`bash\n# Estado de pods\nkubectl get pods -n academia -w\n\n# Logs en tiempo real\nkubectl logs -n academia -l app=student-api -f\n\n# Eventos\nkubectl get events -n academia --sort-by='.lastTimestamp'\n\n# Recursos\nkubectl top pods -n academia\n\`\`\`\n\n### Rollback en k3s\n\n\`\`\`bash\n# Ver historial de deployments\nkubectl rollout history deployment/student-api -n academia\n\n# Rollback a versión anterior\nkubectl rollout undo deployment/student-api -n academia\n\n# Rollback a revisión específica\nkubectl rollout undo deployment/student-api -n academia --to-revision=2\n\`\`\`\n\n### Troubleshooting\n\n\`\`\`bash\n# Pod no inicia\nkubectl describe pod -n academia\n\n# Conectar a pod\nkubectl exec -it -n academia -- /bin/sh\n\n# Verificar conectividad BD\nkubectl exec -it -n academia -- \\\n curl -v telnet://sqlserver:1433\n\n# Verificar ingress\nkubectl describe ingress student-ingress -n academia\n\`\`\`\n`, - "Plan de Actividades": `# Plan de Actividades - Prueba Técnica Senior .NET/Angular\n\n## Información del Proyecto\n- **Cargo:** Desarrollador Master .NET/Angular\n- **Empresa:** Inter Rapidísimo\n- **Proyecto:** Sistema de Registro de Estudiantes\n- **Stack:** .NET 10 + GraphQL (HotChocolate) + Angular 21 + SQL Server\n\n---\n\n## Procesos de Fábrica de Software\n\n| Código | Proceso | Descripción |\n|--------|---------|-------------|\n| **AN** | Análisis | Levantamiento de requisitos, historias de usuario |\n| **DI** | Diseño | Arquitectura, modelos, prototipos UI/UX |\n| **DE** | Desarrollo | Codificación, implementación |\n| **QA** | Quality Assurance | Testing, revisión de código |\n| **DV** | DevOps | CI/CD, containerización, despliegue |\n| **DO** | Documentación | Técnica, usuario, API |\n| **SE** | Seguridad | Validaciones, autenticación, OWASP |\n\n---\n\n## Tabla de Actividades\n\n### Fase 1: Análisis y Planificación (AN)\n\n| # | Actividad | Detalle | Rol | Proceso |\n|---|-----------|---------|-----|---------|\n| 1.1 | Análisis de requisitos funcionales | Identificar y documentar los 9 requisitos del enunciado, criterios de aceptación por cada uno | Analista | AN |\n| 1.2 | Identificación de reglas de negocio | Documentar restricciones: máx 3 materias, 3 créditos/materia, 5 profesores con 2 materias c/u, restricción de profesor único | Analista | AN |\n| 1.3 | Definición de historias de usuario | Crear historias con formato "Como [rol] quiero [acción] para [beneficio]" con criterios de aceptación | Product Owner | AN |\n| 1.4 | Análisis de requisitos no funcionales | Definir: rendimiento (<200ms respuesta), seguridad (OWASP Top 10), usabilidad (responsive), mantenibilidad | Arquitecto | AN |\n| 1.5 | Identificación de riesgos técnicos | Mapear riesgos: complejidad de validaciones, integración frontend-backend, manejo de concurrencia | Líder Técnico | AN |\n\n### Fase 2: Diseño de Arquitectura (DI)\n\n| # | Actividad | Detalle | Rol | Proceso |\n|---|-----------|---------|-----|---------|\n| 2.1 | Diseño de arquitectura backend | Definir Clean Architecture: Domain, Application, Infrastructure, GraphQL. Diagrama de capas y dependencias | Arquitecto Backend | DI |\n| 2.2 | Diseño del modelo de dominio | Crear diagrama de entidades: Student, Subject, Professor, Enrollment. Definir agregados y value objects | Arquitecto Backend | DI |\n| 2.3 | Diseño de base de datos | Modelo E-R normalizado (3FN), índices, constraints, scripts DDL con integridad referencial | DBA/Arquitecto | DI |\n| 2.4 | Diseño de esquema GraphQL | Definir Types, Queries, Mutations, Inputs, Payloads. Diseñar resolvers y DataLoaders para N+1 | Arquitecto Backend | DI |\n| 2.5 | Diseño de arquitectura frontend | Definir estructura Angular: standalone components, signals, lazy loading, Apollo Client para GraphQL | Arquitecto Frontend | DI |\n| 2.6 | Diseño de componentes UI | Wireframes de pantallas: listado estudiantes, formulario inscripción, selección materias, vista compañeros | UI/UX Designer | DI |\n| 2.7 | Definición de contratos GraphQL | Schema GraphQL completo, DTOs de request/response, interfaces de servicios, contratos entre capas | Arquitecto | DI |\n| 2.8 | Diseño de estrategia de manejo de errores | Definir excepciones de dominio, error handling en GraphQL (Union types para errores), respuestas estandarizadas | Arquitecto | DI |\n\n### Fase 3: Configuración del Entorno (DV)\n\n| # | Actividad | Detalle | Rol | Proceso |\n|---|-----------|---------|-----|---------|\n| 3.1 | Inicialización del repositorio | Crear estructura de carpetas, .gitignore, README, CLAUDE.md con convenciones del proyecto | DevOps | DV |\n| 3.2 | Configuración solución .NET | Crear solución con 4 proyectos (Domain, Application, Infrastructure, GraphQL), referencias entre proyectos | Backend Dev | DV |\n| 3.3 | Configuración proyecto Angular | ng new con standalone, configurar ESLint, Prettier, paths aliases, Apollo Angular para GraphQL | Frontend Dev | DV |\n| 3.4 | Configuración de base de datos | Docker compose para SQL Server, scripts de inicialización, connection strings por ambiente | DevOps/DBA | DV |\n| 3.5 | Configuración de variables de entorno | User secrets para desarrollo, appsettings por ambiente, environment.ts en Angular | DevOps | DV |\n| 3.6 | Configuración de herramientas de calidad | EditorConfig, .NET analyzers, ESLint rules, Husky para pre-commit hooks | DevOps | DV |\n\n### Fase 4: Desarrollo Backend (DE)\n\n| # | Actividad | Detalle | Rol | Proceso |\n|---|-----------|---------|-----|---------|\n| 4.1 | Implementar capa Domain | Entidades (Student, Subject, Professor, Enrollment), Value Objects, interfaces de repositorios, excepciones de dominio | Backend Dev | DE |\n| 4.2 | Implementar reglas de negocio en Domain | Validaciones en entidades: EnrollmentPolicy (max 3 materias), ProfessorConstraint (no repetir profesor) | Backend Dev | DE |\n| 4.3 | Implementar capa Application - DTOs | Records inmutables para requests/responses, mappers con Mapster o extension methods | Backend Dev | DE |\n| 4.4 | Implementar capa Application - Servicios | StudentService, EnrollmentService con casos de uso: Create, Update, Delete, GetAll, GetById, GetClassmates | Backend Dev | DE |\n| 4.5 | Implementar validadores FluentValidation | Validators para CreateStudentInput, EnrollStudentInput con reglas de negocio | Backend Dev | DE |\n| 4.6 | Implementar capa Infrastructure - DbContext | Configurar EF Core 10, Fluent API para mapeos, configuraciones de entidades, seeding de datos iniciales | Backend Dev | DE |\n| 4.7 | Implementar capa Infrastructure - Repositorios | Repositorios genérico y específicos, Unit of Work, queries optimizadas con Include/ThenInclude | Backend Dev | DE |\n| 4.8 | Implementar GraphQL Types | StudentType, SubjectType, ProfessorType, EnrollmentType con HotChocolate | Backend Dev | DE |\n| 4.9 | Implementar GraphQL Queries | Resolvers para: students, student(id), subjects, availableSubjects(studentId), classmates(studentId), professors | Backend Dev | DE |\n| 4.10 | Implementar GraphQL Mutations | createStudent, updateStudent, deleteStudent, enrollStudent, unenrollStudent con Payloads de respuesta | Backend Dev | DE |\n| 4.11 | Implementar DataLoaders | DataLoaders para evitar N+1: StudentByIdDataLoader, SubjectByIdDataLoader, ProfessorByIdDataLoader | Backend Dev | DE |\n| 4.12 | Implementar middleware de errores | ExceptionHandlingMiddleware, mapeo de excepciones de dominio a errores GraphQL | Backend Dev | DE |\n| 4.13 | Configurar Dependency Injection | Registrar servicios por capa en Program.cs, configurar HotChocolate con servicios | Backend Dev | DE |\n| 4.14 | Implementar migraciones EF Core | Crear migración inicial, script de seed para profesores y materias predefinidas | Backend Dev | DE |\n\n### Fase 5: Desarrollo Frontend (DE)\n\n| # | Actividad | Detalle | Rol | Proceso |\n|---|-----------|---------|-----|---------|\n| 5.1 | Configurar Apollo Angular | Instalar apollo-angular, configurar ApolloModule con endpoint GraphQL, cache policies | Frontend Dev | DE |\n| 5.2 | Implementar GraphQL Queries en Angular | Archivos .graphql o queries en TypeScript para students, subjects, classmates | Frontend Dev | DE |\n| 5.3 | Implementar GraphQL Mutations en Angular | Mutations para crear/editar estudiante, inscribir/desinscribir materias | Frontend Dev | DE |\n| 5.4 | Implementar capa Core - Servicios | StudentService, SubjectService, EnrollmentService usando Apollo Client | Frontend Dev | DE |\n| 5.5 | Implementar capa Core - Interceptores | HttpErrorInterceptor para manejo global de errores, LoadingInterceptor para indicador de carga | Frontend Dev | DE |\n| 5.6 | Implementar capa Shared - Componentes UI | ButtonComponent, InputComponent, CardComponent, TableComponent, ModalComponent, AlertComponent | Frontend Dev | DE |\n| 5.7 | Implementar capa Shared - Directivas y Pipes | HighlightDirective, TooltipDirective, TruncatePipe, CreditsPipe | Frontend Dev | DE |\n| 5.8 | Implementar feature Students - Listado | Tabla con estudiantes usando Apollo watchQuery, búsqueda, paginación, acciones CRUD | Frontend Dev | DE |\n| 5.9 | Implementar feature Students - Formulario | Reactive form para crear/editar estudiante con validaciones, mutation de Apollo | Frontend Dev | DE |\n| 5.10 | Implementar feature Enrollment - Selección materias | Componente con query availableSubjects, validación visual de restricción de profesor, contador de créditos | Frontend Dev | DE |\n| 5.11 | Implementar feature Enrollment - Vista compañeros | Query classmates con listado de nombres por materia inscrita | Frontend Dev | DE |\n| 5.12 | Implementar gestión de estado | Signals para estado local, Apollo cache para estado del servidor, optimistic updates | Frontend Dev | DE |\n| 5.13 | Implementar manejo de errores UI | Toast notifications, estados de error en formularios, manejo de errores GraphQL | Frontend Dev | DE |\n| 5.14 | Implementar responsive design | CSS con mobile-first, breakpoints para tablet/desktop, Angular Material responsive | Frontend Dev | DE |\n| 5.15 | Implementar loading states | Skeletons, spinners, estados de carga con Apollo loading state | Frontend Dev | DE |\n\n### Fase 6: Integración GraphQL (DE)\n\n| # | Actividad | Detalle | Rol | Proceso |\n|---|-----------|---------|-----|---------|\n| 6.1 | Configurar CORS | Permitir origen del frontend en desarrollo y producción, headers para GraphQL | Backend Dev | DE |\n| 6.2 | Configurar Banana Cake Pop | Playground integrado de HotChocolate para testing de queries/mutations | Backend Dev | DE |\n| 6.3 | Implementar health checks | Endpoint /health para verificar conectividad a BD y servicios | Backend Dev | DE |\n| 6.4 | Configurar Apollo DevTools | Habilitar Apollo DevTools en desarrollo para debugging de queries y cache | Frontend Dev | DE |\n| 6.5 | Implementar caché de Apollo | Configurar cache policies: cache-first para datos estáticos, network-only para datos dinámicos | Frontend Dev | DE |\n| 6.6 | Generar tipos TypeScript | Usar GraphQL Code Generator para generar tipos desde el schema GraphQL | Frontend Dev | DE |\n\n### Fase 7: Seguridad (SE)\n\n| # | Actividad | Detalle | Rol | Proceso |\n|---|-----------|---------|-----|---------|\n| 7.1 | Implementar validación de entrada | Sanitización de inputs, validación en frontend y backend, prevención de inyección | Security Dev | SE |\n| 7.2 | Configurar headers de seguridad | Content-Security-Policy, X-Content-Type-Options, X-Frame-Options, HSTS | Security Dev | SE |\n| 7.3 | Implementar rate limiting | Limitar requests por IP para prevenir DoS, configurar en middleware GraphQL | Security Dev | SE |\n| 7.4 | Configurar query complexity | Limitar profundidad y complejidad de queries GraphQL para prevenir ataques | Security Dev | SE |\n| 7.5 | Validar OWASP Top 10 | Revisar: Injection, Broken Auth, XSS, Insecure Design, Security Misconfiguration | Security Dev | SE |\n| 7.6 | Configurar logging seguro | No loguear datos sensibles, structured logging con Serilog, niveles apropiados | Security Dev | SE |\n\n### Fase 8: Testing (QA)\n\n| # | Actividad | Detalle | Rol | Proceso |\n|---|-----------|---------|-----|---------|\n| 8.1 | Unit tests - Domain | Tests para reglas de negocio: validación max 3 materias, restricción profesor, cálculo créditos | QA/Backend Dev | QA |\n| 8.2 | Unit tests - Application | Tests para servicios, mappers, validators usando mocks de repositorios | QA/Backend Dev | QA |\n| 8.3 | Integration tests - GraphQL | Tests de queries y mutations con WebApplicationFactory, base de datos in-memory | QA/Backend Dev | QA |\n| 8.4 | Unit tests - Angular Components | Tests con Jest/Jasmine para componentes, servicios con Apollo testing utilities | QA/Frontend Dev | QA |\n| 8.5 | E2E tests | Tests con Playwright para flujos críticos: registro estudiante, inscripción materias | QA | QA |\n| 8.6 | Tests de reglas de negocio | Casos de prueba específicos para restricciones: intentar 4ta materia, mismo profesor | QA | QA |\n| 8.7 | Code review | Revisión de código aplicando checklist: SOLID, Clean Code, convenciones, seguridad | Líder Técnico | QA |\n| 8.8 | Análisis de código estático | Ejecutar analyzers .NET, ESLint, corregir code smells, vulnerabilidades, duplicación | QA | QA |\n\n### Fase 9: Optimización y Rendimiento (DE)\n\n| # | Actividad | Detalle | Rol | Proceso |\n|---|-----------|---------|-----|---------|\n| 9.1 | Optimizar queries EF Core | Revisar N+1 (usar DataLoaders), AsNoTracking para lecturas, proyecciones con Select, índices en BD | Backend Dev | DE |\n| 9.2 | Implementar caché backend | Response caching para queries estáticas, memory cache para datos frecuentes | Backend Dev | DE |\n| 9.3 | Optimizar bundle Angular | Lazy loading de rutas, tree shaking, análisis de bundle size | Frontend Dev | DE |\n| 9.4 | Optimizar rendimiento UI | OnPush change detection, trackBy en ngFor, debounce en búsquedas | Frontend Dev | DE |\n| 9.5 | Comprimir assets | Minificación CSS/JS, compresión gzip/brotli | DevOps | DE |\n\n### Fase 10: Documentación (DO)\n\n| # | Actividad | Detalle | Rol | Proceso |\n|---|-----------|---------|-----|---------|\n| 10.1 | Documentar arquitectura | Diagrama C4 (Context, Container, Component), decisiones de arquitectura (ADR) | Arquitecto | DO |\n| 10.2 | Documentar esquema GraphQL | Schema completo con descripciones, ejemplos de queries/mutations en Banana Cake Pop | Backend Dev | DO |\n| 10.3 | Documentar modelo de datos | Diagrama E-R, diccionario de datos, scripts de creación comentados | DBA | DO |\n| 10.4 | README del proyecto | Instrucciones de instalación, configuración, ejecución, estructura del proyecto | Líder Técnico | DO |\n| 10.5 | Documentar decisiones técnicas | Por qué Clean Architecture, por qué GraphQL vs REST, por qué Signals vs RxJS | Arquitecto | DO |\n| 10.6 | Manual de despliegue | Pasos para deploy, variables de entorno requeridas, checklist pre-producción | DevOps | DO |\n\n### Fase 11: Entrega y Despliegue (DV)\n\n| # | Actividad | Detalle | Rol | Proceso |\n|---|-----------|---------|-----|---------|\n| 11.1 | Configurar Dockerfile GraphQL | Multi-stage build, imagen optimizada, health check, non-root user | DevOps | DV |\n| 11.2 | Configurar Dockerfile frontend | Build con Node, serve con Nginx, configuración de proxy para GraphQL | DevOps | DV |\n| 11.3 | Crear docker-compose | Orquestación de GraphQL API, frontend, SQL Server, configuración de red y volúmenes | DevOps | DV |\n| 11.4 | Pruebas de despliegue | Verificar funcionamiento end-to-end en ambiente containerizado | DevOps/QA | DV |\n| 11.5 | Preparar entregables | Empaquetar código fuente, scripts BD, documentación, instrucciones de ejecución | Líder Técnico | DV |\n| 11.6 | Validación final | Checklist de requisitos cumplidos, demo funcional, revisión de calidad | Líder Técnico | DV |\n\n---\n\n## Resumen por Proceso\n\n| Proceso | Actividades | Peso |\n|---------|-------------|------|\n| Análisis (AN) | 5 | 5% |\n| Diseño (DI) | 8 | 15% |\n| DevOps (DV) | 12 | 10% |\n| Desarrollo Backend (DE) | 14 | 30% |\n| Desarrollo Frontend (DE) | 15 | 25% |\n| Seguridad (SE) | 6 | 5% |\n| Testing (QA) | 8 | 5% |\n| Documentación (DO) | 6 | 5% |\n| **TOTAL** | **74** | **100%** |\n\n---\n\n## Criterios de Calidad Senior\n\n### Competencias Demostradas\n\n| Área | Evidencia |\n|------|-----------|\n| **Arquitectura** | Clean Architecture, separación de concerns, principios SOLID |\n| **GraphQL** | Schema bien diseñado, DataLoaders para N+1, error handling |\n| **Código Limpio** | Naming conventions, SRP, métodos pequeños, sin duplicación |\n| **Testing** | Cobertura de reglas críticas, tests unitarios y de integración |\n| **Seguridad** | OWASP compliance, validación de inputs, query complexity limits |\n| **Rendimiento** | Queries optimizadas, caching estratégico, Apollo cache |\n| **Mantenibilidad** | Código autodocumentado, arquitectura desacoplada, DTOs |\n| **DevOps** | Containerización, configuración por ambiente |\n| **Documentación** | Schema GraphQL documentado, README completo |\n\n### Diferenciadores Senior vs Junior\n\n| Aspecto | Junior | Senior (Este proyecto) |\n|---------|--------|------------------------|\n| Arquitectura | Monolítico, acoplado | Clean Architecture, capas bien definidas |\n| API | REST básico | GraphQL con HotChocolate, DataLoaders |\n| Validaciones | Solo en frontend | Frontend + Backend + Domain |\n| Errores | Try-catch genéricos | Excepciones de dominio, Union types para errores |\n| Testing | Manual o ninguno | Unit + Integration + E2E automatizados |\n| Estado Frontend | Variables globales | Signals + Apollo Cache |\n| BD | EF directo en controller | Repository + Unit of Work + Specifications |\n| Seguridad | Ninguna | OWASP, headers, rate limiting, query complexity |\n\n---\n\n## Orden de Ejecución Recomendado\n\n\`\`\`\nBloque 1: Fundamentos\n├── AN (1.1-1.5) → Requisitos claros\n├── DI (2.1-2.8) → Arquitectura definida\n└── DV (3.1-3.6) → Ambiente configurado\n\nBloque 2: Backend Core\n├── DE (4.1-4.7) → Domain + Application + Infrastructure\n└── DE (4.8-4.14) → GraphQL API funcional\n\nBloque 3: Frontend Core\n├── DE (5.1-5.7) → Core + Shared + Apollo config\n└── DE (5.8-5.15) → Features completas\n\nBloque 4: Integración\n└── DE (6.1-6.6) → Frontend ↔ Backend conectados\n\nBloque 5: Calidad\n├── SE (7.1-7.6) → Seguridad implementada\n├── QA (8.1-8.8) → Tests ejecutados\n└── DE (9.1-9.5) → Optimizaciones aplicadas\n\nBloque 6: Entrega\n├── DO (10.1-10.6) → Documentación completa\n└── DV (11.1-11.6) → Despliegue validado\n\`\`\`\n\n> **Nota:** Ejecutar los bloques secuencialmente. Dentro de cada bloque, las actividades pueden paralelizarse según disponibilidad de recursos.\n`, + "Plan de Actividades": `# Plan de Actividades - Prueba Técnica Senior .NET/Angular\n\n## Información del Proyecto\n- **Cargo:** Desarrollador Master .NET/Angular\n- **Empresa:** Inter Rapidísimo\n- **Proyecto:** Sistema de Registro de Estudiantes\n- **Stack:** .NET 10 + GraphQL (HotChocolate) + Angular 21 + SQL Server\n\n---\n\n## Procesos de Fábrica de Software\n\n| Código | Proceso | Descripción |\n|--------|---------|-------------|\n| **AN** | Análisis | Levantamiento de requisitos, historias de usuario |\n| **DI** | Diseño | Arquitectura, modelos, prototipos UI/UX |\n| **DE** | Desarrollo | Codificación, implementación |\n| **QA** | Quality Assurance | Testing, revisión de código |\n| **DV** | DevOps | CI/CD, containerización, despliegue |\n| **DO** | Documentación | Técnica, usuario, API |\n| **SE** | Seguridad | Validaciones, autenticación, OWASP |\n\n---\n\n## Tabla de Actividades\n\n### Fase 1: Análisis y Planificación (AN)\n\n| # | Actividad | Detalle | Rol | Proceso |\n|---|-----------|---------|-----|---------|\n| 1.1 | Análisis de requisitos funcionales | Identificar y documentar los 9 requisitos del enunciado, criterios de aceptación por cada uno | Analista | AN |\n| 1.2 | Identificación de reglas de negocio | Documentar restricciones: máx 3 materias, 3 créditos/materia, 5 profesores con 2 materias c/u, restricción de profesor único | Analista | AN |\n| 1.3 | Definición de historias de usuario | Crear historias con formato "Como [rol] quiero [acción] para [beneficio]" con criterios de aceptación | Product Owner | AN |\n| 1.4 | Análisis de requisitos no funcionales | Definir: rendimiento (<200ms respuesta), seguridad (OWASP Top 10), usabilidad (responsive), mantenibilidad | Arquitecto | AN |\n| 1.5 | Identificación de riesgos técnicos | Mapear riesgos: complejidad de validaciones, integración frontend-backend, manejo de concurrencia | Líder Técnico | AN |\n\n### Fase 2: Diseño de Arquitectura (DI)\n\n| # | Actividad | Detalle | Rol | Proceso |\n|---|-----------|---------|-----|---------|\n| 2.1 | Diseño de arquitectura backend | Definir Clean Architecture: Domain, Application, Infrastructure, GraphQL. Diagrama de capas y dependencias | Arquitecto Backend | DI |\n| 2.2 | Diseño del modelo de dominio | Crear diagrama de entidades: Student, Subject, Professor, Enrollment. Definir agregados y value objects | Arquitecto Backend | DI |\n| 2.3 | Diseño de base de datos | Modelo E-R normalizado (3FN), índices, constraints, scripts DDL con integridad referencial | DBA/Arquitecto | DI |\n| 2.4 | Diseño de esquema GraphQL | Definir Types, Queries, Mutations, Inputs, Payloads. Diseñar resolvers y DataLoaders para N+1 | Arquitecto Backend | DI |\n| 2.5 | Diseño de arquitectura frontend | Definir estructura Angular: standalone components, signals, lazy loading, Apollo Client para GraphQL | Arquitecto Frontend | DI |\n| 2.6 | Diseño de componentes UI | Wireframes de pantallas: listado estudiantes, formulario inscripción, selección materias, vista compañeros | UI/UX Designer | DI |\n| 2.7 | Definición de contratos GraphQL | Schema GraphQL completo, DTOs de request/response, interfaces de servicios, contratos entre capas | Arquitecto | DI |\n| 2.8 | Diseño de estrategia de manejo de errores | Definir excepciones de dominio, error handling en GraphQL (Union types para errores), respuestas estandarizadas | Arquitecto | DI |\n\n### Fase 3: Configuración del Entorno (DV)\n\n| # | Actividad | Detalle | Rol | Proceso |\n|---|-----------|---------|-----|---------|\n| 3.1 | Inicialización del repositorio | Crear estructura de carpetas, .gitignore, README, DEV-GUIDE.md con convenciones del proyecto | DevOps | DV |\n| 3.2 | Configuración solución .NET | Crear solución con 4 proyectos (Domain, Application, Infrastructure, GraphQL), referencias entre proyectos | Backend Dev | DV |\n| 3.3 | Configuración proyecto Angular | ng new con standalone, configurar ESLint, Prettier, paths aliases, Apollo Angular para GraphQL | Frontend Dev | DV |\n| 3.4 | Configuración de base de datos | Docker compose para SQL Server, scripts de inicialización, connection strings por ambiente | DevOps/DBA | DV |\n| 3.5 | Configuración de variables de entorno | User secrets para desarrollo, appsettings por ambiente, environment.ts en Angular | DevOps | DV |\n| 3.6 | Configuración de herramientas de calidad | EditorConfig, .NET analyzers, ESLint rules, Husky para pre-commit hooks | DevOps | DV |\n\n### Fase 4: Desarrollo Backend (DE)\n\n| # | Actividad | Detalle | Rol | Proceso |\n|---|-----------|---------|-----|---------|\n| 4.1 | Implementar capa Domain | Entidades (Student, Subject, Professor, Enrollment), Value Objects, interfaces de repositorios, excepciones de dominio | Backend Dev | DE |\n| 4.2 | Implementar reglas de negocio en Domain | Validaciones en entidades: EnrollmentPolicy (max 3 materias), ProfessorConstraint (no repetir profesor) | Backend Dev | DE |\n| 4.3 | Implementar capa Application - DTOs | Records inmutables para requests/responses, mappers con Mapster o extension methods | Backend Dev | DE |\n| 4.4 | Implementar capa Application - Servicios | StudentService, EnrollmentService con casos de uso: Create, Update, Delete, GetAll, GetById, GetClassmates | Backend Dev | DE |\n| 4.5 | Implementar validadores FluentValidation | Validators para CreateStudentInput, EnrollStudentInput con reglas de negocio | Backend Dev | DE |\n| 4.6 | Implementar capa Infrastructure - DbContext | Configurar EF Core 10, Fluent API para mapeos, configuraciones de entidades, seeding de datos iniciales | Backend Dev | DE |\n| 4.7 | Implementar capa Infrastructure - Repositorios | Repositorios genérico y específicos, Unit of Work, queries optimizadas con Include/ThenInclude | Backend Dev | DE |\n| 4.8 | Implementar GraphQL Types | StudentType, SubjectType, ProfessorType, EnrollmentType con HotChocolate | Backend Dev | DE |\n| 4.9 | Implementar GraphQL Queries | Resolvers para: students, student(id), subjects, availableSubjects(studentId), classmates(studentId), professors | Backend Dev | DE |\n| 4.10 | Implementar GraphQL Mutations | createStudent, updateStudent, deleteStudent, enrollStudent, unenrollStudent con Payloads de respuesta | Backend Dev | DE |\n| 4.11 | Implementar DataLoaders | DataLoaders para evitar N+1: StudentByIdDataLoader, SubjectByIdDataLoader, ProfessorByIdDataLoader | Backend Dev | DE |\n| 4.12 | Implementar middleware de errores | ExceptionHandlingMiddleware, mapeo de excepciones de dominio a errores GraphQL | Backend Dev | DE |\n| 4.13 | Configurar Dependency Injection | Registrar servicios por capa en Program.cs, configurar HotChocolate con servicios | Backend Dev | DE |\n| 4.14 | Implementar migraciones EF Core | Crear migración inicial, script de seed para profesores y materias predefinidas | Backend Dev | DE |\n\n### Fase 5: Desarrollo Frontend (DE)\n\n| # | Actividad | Detalle | Rol | Proceso |\n|---|-----------|---------|-----|---------|\n| 5.1 | Configurar Apollo Angular | Instalar apollo-angular, configurar ApolloModule con endpoint GraphQL, cache policies | Frontend Dev | DE |\n| 5.2 | Implementar GraphQL Queries en Angular | Archivos .graphql o queries en TypeScript para students, subjects, classmates | Frontend Dev | DE |\n| 5.3 | Implementar GraphQL Mutations en Angular | Mutations para crear/editar estudiante, inscribir/desinscribir materias | Frontend Dev | DE |\n| 5.4 | Implementar capa Core - Servicios | StudentService, SubjectService, EnrollmentService usando Apollo Client | Frontend Dev | DE |\n| 5.5 | Implementar capa Core - Interceptores | HttpErrorInterceptor para manejo global de errores, LoadingInterceptor para indicador de carga | Frontend Dev | DE |\n| 5.6 | Implementar capa Shared - Componentes UI | ButtonComponent, InputComponent, CardComponent, TableComponent, ModalComponent, AlertComponent | Frontend Dev | DE |\n| 5.7 | Implementar capa Shared - Directivas y Pipes | HighlightDirective, TooltipDirective, TruncatePipe, CreditsPipe | Frontend Dev | DE |\n| 5.8 | Implementar feature Students - Listado | Tabla con estudiantes usando Apollo watchQuery, búsqueda, paginación, acciones CRUD | Frontend Dev | DE |\n| 5.9 | Implementar feature Students - Formulario | Reactive form para crear/editar estudiante con validaciones, mutation de Apollo | Frontend Dev | DE |\n| 5.10 | Implementar feature Enrollment - Selección materias | Componente con query availableSubjects, validación visual de restricción de profesor, contador de créditos | Frontend Dev | DE |\n| 5.11 | Implementar feature Enrollment - Vista compañeros | Query classmates con listado de nombres por materia inscrita | Frontend Dev | DE |\n| 5.12 | Implementar gestión de estado | Signals para estado local, Apollo cache para estado del servidor, optimistic updates | Frontend Dev | DE |\n| 5.13 | Implementar manejo de errores UI | Toast notifications, estados de error en formularios, manejo de errores GraphQL | Frontend Dev | DE |\n| 5.14 | Implementar responsive design | CSS con mobile-first, breakpoints para tablet/desktop, Angular Material responsive | Frontend Dev | DE |\n| 5.15 | Implementar loading states | Skeletons, spinners, estados de carga con Apollo loading state | Frontend Dev | DE |\n\n### Fase 6: Integración GraphQL (DE)\n\n| # | Actividad | Detalle | Rol | Proceso |\n|---|-----------|---------|-----|---------|\n| 6.1 | Configurar CORS | Permitir origen del frontend en desarrollo y producción, headers para GraphQL | Backend Dev | DE |\n| 6.2 | Configurar Banana Cake Pop | Playground integrado de HotChocolate para testing de queries/mutations | Backend Dev | DE |\n| 6.3 | Implementar health checks | Endpoint /health para verificar conectividad a BD y servicios | Backend Dev | DE |\n| 6.4 | Configurar Apollo DevTools | Habilitar Apollo DevTools en desarrollo para debugging de queries y cache | Frontend Dev | DE |\n| 6.5 | Implementar caché de Apollo | Configurar cache policies: cache-first para datos estáticos, network-only para datos dinámicos | Frontend Dev | DE |\n| 6.6 | Generar tipos TypeScript | Usar GraphQL Code Generator para generar tipos desde el schema GraphQL | Frontend Dev | DE |\n\n### Fase 7: Seguridad (SE)\n\n| # | Actividad | Detalle | Rol | Proceso |\n|---|-----------|---------|-----|---------|\n| 7.1 | Implementar validación de entrada | Sanitización de inputs, validación en frontend y backend, prevención de inyección | Security Dev | SE |\n| 7.2 | Configurar headers de seguridad | Content-Security-Policy, X-Content-Type-Options, X-Frame-Options, HSTS | Security Dev | SE |\n| 7.3 | Implementar rate limiting | Limitar requests por IP para prevenir DoS, configurar en middleware GraphQL | Security Dev | SE |\n| 7.4 | Configurar query complexity | Limitar profundidad y complejidad de queries GraphQL para prevenir ataques | Security Dev | SE |\n| 7.5 | Validar OWASP Top 10 | Revisar: Injection, Broken Auth, XSS, Insecure Design, Security Misconfiguration | Security Dev | SE |\n| 7.6 | Configurar logging seguro | No loguear datos sensibles, structured logging con Serilog, niveles apropiados | Security Dev | SE |\n\n### Fase 8: Testing (QA)\n\n| # | Actividad | Detalle | Rol | Proceso |\n|---|-----------|---------|-----|---------|\n| 8.1 | Unit tests - Domain | Tests para reglas de negocio: validación max 3 materias, restricción profesor, cálculo créditos | QA/Backend Dev | QA |\n| 8.2 | Unit tests - Application | Tests para servicios, mappers, validators usando mocks de repositorios | QA/Backend Dev | QA |\n| 8.3 | Integration tests - GraphQL | Tests de queries y mutations con WebApplicationFactory, base de datos in-memory | QA/Backend Dev | QA |\n| 8.4 | Unit tests - Angular Components | Tests con Jest/Jasmine para componentes, servicios con Apollo testing utilities | QA/Frontend Dev | QA |\n| 8.5 | E2E tests | Tests con Playwright para flujos críticos: registro estudiante, inscripción materias | QA | QA |\n| 8.6 | Tests de reglas de negocio | Casos de prueba específicos para restricciones: intentar 4ta materia, mismo profesor | QA | QA |\n| 8.7 | Code review | Revisión de código aplicando checklist: SOLID, Clean Code, convenciones, seguridad | Líder Técnico | QA |\n| 8.8 | Análisis de código estático | Ejecutar analyzers .NET, ESLint, corregir code smells, vulnerabilidades, duplicación | QA | QA |\n\n### Fase 9: Optimización y Rendimiento (DE)\n\n| # | Actividad | Detalle | Rol | Proceso |\n|---|-----------|---------|-----|---------|\n| 9.1 | Optimizar queries EF Core | Revisar N+1 (usar DataLoaders), AsNoTracking para lecturas, proyecciones con Select, índices en BD | Backend Dev | DE |\n| 9.2 | Implementar caché backend | Response caching para queries estáticas, memory cache para datos frecuentes | Backend Dev | DE |\n| 9.3 | Optimizar bundle Angular | Lazy loading de rutas, tree shaking, análisis de bundle size | Frontend Dev | DE |\n| 9.4 | Optimizar rendimiento UI | OnPush change detection, trackBy en ngFor, debounce en búsquedas | Frontend Dev | DE |\n| 9.5 | Comprimir assets | Minificación CSS/JS, compresión gzip/brotli | DevOps | DE |\n\n### Fase 10: Documentación (DO)\n\n| # | Actividad | Detalle | Rol | Proceso |\n|---|-----------|---------|-----|---------|\n| 10.1 | Documentar arquitectura | Diagrama C4 (Context, Container, Component), decisiones de arquitectura (ADR) | Arquitecto | DO |\n| 10.2 | Documentar esquema GraphQL | Schema completo con descripciones, ejemplos de queries/mutations en Banana Cake Pop | Backend Dev | DO |\n| 10.3 | Documentar modelo de datos | Diagrama E-R, diccionario de datos, scripts de creación comentados | DBA | DO |\n| 10.4 | README del proyecto | Instrucciones de instalación, configuración, ejecución, estructura del proyecto | Líder Técnico | DO |\n| 10.5 | Documentar decisiones técnicas | Por qué Clean Architecture, por qué GraphQL vs REST, por qué Signals vs RxJS | Arquitecto | DO |\n| 10.6 | Manual de despliegue | Pasos para deploy, variables de entorno requeridas, checklist pre-producción | DevOps | DO |\n\n### Fase 11: Entrega y Despliegue (DV)\n\n| # | Actividad | Detalle | Rol | Proceso |\n|---|-----------|---------|-----|---------|\n| 11.1 | Configurar Dockerfile GraphQL | Multi-stage build, imagen optimizada, health check, non-root user | DevOps | DV |\n| 11.2 | Configurar Dockerfile frontend | Build con Node, serve con Nginx, configuración de proxy para GraphQL | DevOps | DV |\n| 11.3 | Crear docker-compose | Orquestación de GraphQL API, frontend, SQL Server, configuración de red y volúmenes | DevOps | DV |\n| 11.4 | Pruebas de despliegue | Verificar funcionamiento end-to-end en ambiente containerizado | DevOps/QA | DV |\n| 11.5 | Preparar entregables | Empaquetar código fuente, scripts BD, documentación, instrucciones de ejecución | Líder Técnico | DV |\n| 11.6 | Validación final | Checklist de requisitos cumplidos, demo funcional, revisión de calidad | Líder Técnico | DV |\n\n---\n\n## Resumen por Proceso\n\n| Proceso | Actividades | Peso |\n|---------|-------------|------|\n| Análisis (AN) | 5 | 5% |\n| Diseño (DI) | 8 | 15% |\n| DevOps (DV) | 12 | 10% |\n| Desarrollo Backend (DE) | 14 | 30% |\n| Desarrollo Frontend (DE) | 15 | 25% |\n| Seguridad (SE) | 6 | 5% |\n| Testing (QA) | 8 | 5% |\n| Documentación (DO) | 6 | 5% |\n| **TOTAL** | **74** | **100%** |\n\n---\n\n## Criterios de Calidad Senior\n\n### Competencias Demostradas\n\n| Área | Evidencia |\n|------|-----------|\n| **Arquitectura** | Clean Architecture, separación de concerns, principios SOLID |\n| **GraphQL** | Schema bien diseñado, DataLoaders para N+1, error handling |\n| **Código Limpio** | Naming conventions, SRP, métodos pequeños, sin duplicación |\n| **Testing** | Cobertura de reglas críticas, tests unitarios y de integración |\n| **Seguridad** | OWASP compliance, validación de inputs, query complexity limits |\n| **Rendimiento** | Queries optimizadas, caching estratégico, Apollo cache |\n| **Mantenibilidad** | Código autodocumentado, arquitectura desacoplada, DTOs |\n| **DevOps** | Containerización, configuración por ambiente |\n| **Documentación** | Schema GraphQL documentado, README completo |\n\n### Diferenciadores Senior vs Junior\n\n| Aspecto | Junior | Senior (Este proyecto) |\n|---------|--------|------------------------|\n| Arquitectura | Monolítico, acoplado | Clean Architecture, capas bien definidas |\n| API | REST básico | GraphQL con HotChocolate, DataLoaders |\n| Validaciones | Solo en frontend | Frontend + Backend + Domain |\n| Errores | Try-catch genéricos | Excepciones de dominio, Union types para errores |\n| Testing | Manual o ninguno | Unit + Integration + E2E automatizados |\n| Estado Frontend | Variables globales | Signals + Apollo Cache |\n| BD | EF directo en controller | Repository + Unit of Work + Specifications |\n| Seguridad | Ninguna | OWASP, headers, rate limiting, query complexity |\n\n---\n\n## Orden de Ejecución Recomendado\n\n\`\`\`\nBloque 1: Fundamentos\n├── AN (1.1-1.5) → Requisitos claros\n├── DI (2.1-2.8) → Arquitectura definida\n└── DV (3.1-3.6) → Ambiente configurado\n\nBloque 2: Backend Core\n├── DE (4.1-4.7) → Domain + Application + Infrastructure\n└── DE (4.8-4.14) → GraphQL API funcional\n\nBloque 3: Frontend Core\n├── DE (5.1-5.7) → Core + Shared + Apollo config\n└── DE (5.8-5.15) → Features completas\n\nBloque 4: Integración\n└── DE (6.1-6.6) → Frontend ↔ Backend conectados\n\nBloque 5: Calidad\n├── SE (7.1-7.6) → Seguridad implementada\n├── QA (8.1-8.8) → Tests ejecutados\n└── DE (9.1-9.5) → Optimizaciones aplicadas\n\nBloque 6: Entrega\n├── DO (10.1-10.6) → Documentación completa\n└── DV (11.1-11.6) → Despliegue validado\n\`\`\`\n\n> **Nota:** Ejecutar los bloques secuencialmente. Dentro de cada bloque, las actividades pueden paralelizarse según disponibilidad de recursos.\n`, }, "Calidad": { - "Code Review Checklist": `# Code Review Checklist - Sistema Registro Estudiantes\n\n## Estado: Validado\n\n### Arquitectura (Clean Architecture)\n\n| Criterio | Estado | Evidencia |\n|----------|--------|-----------|\n| Separación de capas | ✅ | Domain, Application, Adapters, Host |\n| Regla de dependencia | ✅ | Domain no depende de nada externo |\n| Ports & Adapters | ✅ | IStudentRepository, IEnrollmentRepository |\n| CQRS implementado | ✅ | Commands y Queries separados |\n\n### Principios SOLID\n\n| Principio | Estado | Evidencia |\n|-----------|--------|-----------|\n| **S**ingle Responsibility | ✅ | Cada clase tiene una responsabilidad |\n| **O**pen/Closed | ✅ | Extensible via interfaces |\n| **L**iskov Substitution | ✅ | Repositorios intercambiables |\n| **I**nterface Segregation | ✅ | Interfaces específicas por entidad |\n| **D**ependency Inversion | ✅ | Inyección de dependencias |\n\n### Clean Code\n\n| Criterio | Estado | Notas |\n|----------|--------|-------|\n| Naming conventions | ✅ | PascalCase clases, camelCase variables |\n| Métodos pequeños | ✅ | < 20 líneas promedio |\n| Sin código duplicado | ✅ | DRY aplicado |\n| Comentarios mínimos | ✅ | Código autodocumentado |\n| Archivos < 100 líneas | ✅ | Refactorizado donde necesario |\n\n### Seguridad\n\n| Criterio | Estado | Ubicación |\n|----------|--------|-----------|\n| Input validation | ✅ | FluentValidation + Regex |\n| SQL Injection prevention | ✅ | EF Core parametrizado |\n| XSS prevention | ✅ | Sanitización en validators |\n| Security headers | ✅ | Program.cs middleware |\n| Rate limiting | ✅ | 100 req/min |\n| Query complexity limits | ✅ | Depth 5, complexity 100 |\n\n### Testing\n\n| Tipo | Cantidad | Cobertura |\n|------|----------|-----------|\n| Domain Tests | 30 | Entidades, ValueObjects, Services |\n| Application Tests | 66 | Commands, Queries, Validators |\n| Integration Tests | 5 | GraphQL flujo completo |\n| Angular Unit Tests | 24 | Services, Pipes |\n| E2E Tests (Playwright) | 20 | Flujos principales |\n| **Total** | **145** | |\n\n### Convenciones de Código\n\n#### Backend (.NET)\n\n- [x] Async/await en operaciones I/O\n- [x] Records para DTOs inmutables\n- [x] Nullable habilitado\n- [x] Global usings configurados\n- [x] FluentValidation para validaciones\n\n#### Frontend (Angular)\n\n- [x] Standalone components\n- [x] Signals para estado reactivo\n- [x] Lazy loading por feature\n- [x] OnPush change detection\n- [x] Apollo Client para GraphQL\n\n### GraphQL\n\n| Criterio | Estado |\n|----------|--------|\n| Types bien definidos | ✅ |\n| DataLoaders para N+1 | ✅ |\n| Error handling | ✅ |\n| Payloads con errors | ✅ |\n| Depth limiting | ✅ |\n\n### Performance\n\n| Optimización | Implementada |\n|--------------|--------------|\n| Response compression | ✅ Brotli + Gzip |\n| Output caching | ✅ 5 min para subjects/professors |\n| Apollo cache | ✅ cache-and-network |\n| Lazy loading | ✅ Por feature module |\n| Bundle optimization | ✅ < 800KB initial |\n\n### Documentación\n\n| Documento | Estado |\n|-----------|--------|\n| README.md | ✅ |\n| CLAUDE.md | ✅ |\n| OWASP_CHECKLIST.md | ✅ |\n| GraphQL Schema | ✅ (Banana Cake Pop) |\n\n---\n\n## Checklist de Revisión Manual\n\n### Antes de Merge\n\n- [ ] Todos los tests pasan\n- [ ] Build sin errores ni warnings\n- [ ] Código formateado\n- [ ] Sin TODOs pendientes críticos\n- [ ] Variables de entorno documentadas\n\n### Seguridad\n\n- [ ] Sin secrets hardcodeados\n- [ ] Sin console.log en producción\n- [ ] Validaciones en frontend Y backend\n- [ ] Error messages no exponen detalles internos\n\n### UX\n\n- [ ] Loading states implementados\n- [ ] Error messages claros\n- [ ] Responsive design funcional\n- [ ] Accesibilidad básica (a11y)\n`, + "Code Review Checklist": `# Code Review Checklist - Sistema Registro Estudiantes\n\n## Estado: Validado\n\n### Arquitectura (Clean Architecture)\n\n| Criterio | Estado | Evidencia |\n|----------|--------|-----------|\n| Separación de capas | ✅ | Domain, Application, Adapters, Host |\n| Regla de dependencia | ✅ | Domain no depende de nada externo |\n| Ports & Adapters | ✅ | IStudentRepository, IEnrollmentRepository |\n| CQRS implementado | ✅ | Commands y Queries separados |\n\n### Principios SOLID\n\n| Principio | Estado | Evidencia |\n|-----------|--------|-----------|\n| **S**ingle Responsibility | ✅ | Cada clase tiene una responsabilidad |\n| **O**pen/Closed | ✅ | Extensible via interfaces |\n| **L**iskov Substitution | ✅ | Repositorios intercambiables |\n| **I**nterface Segregation | ✅ | Interfaces específicas por entidad |\n| **D**ependency Inversion | ✅ | Inyección de dependencias |\n\n### Clean Code\n\n| Criterio | Estado | Notas |\n|----------|--------|-------|\n| Naming conventions | ✅ | PascalCase clases, camelCase variables |\n| Métodos pequeños | ✅ | < 20 líneas promedio |\n| Sin código duplicado | ✅ | DRY aplicado |\n| Comentarios mínimos | ✅ | Código autodocumentado |\n| Archivos < 100 líneas | ✅ | Refactorizado donde necesario |\n\n### Seguridad\n\n| Criterio | Estado | Ubicación |\n|----------|--------|-----------|\n| Input validation | ✅ | FluentValidation + Regex |\n| SQL Injection prevention | ✅ | EF Core parametrizado |\n| XSS prevention | ✅ | Sanitización en validators |\n| Security headers | ✅ | Program.cs middleware |\n| Rate limiting | ✅ | 100 req/min |\n| Query complexity limits | ✅ | Depth 5, complexity 100 |\n\n### Testing\n\n| Tipo | Cantidad | Cobertura |\n|------|----------|-----------|\n| Domain Tests | 30 | Entidades, ValueObjects, Services |\n| Application Tests | 66 | Commands, Queries, Validators |\n| Integration Tests | 5 | GraphQL flujo completo |\n| Angular Unit Tests | 24 | Services, Pipes |\n| E2E Tests (Playwright) | 20 | Flujos principales |\n| **Total** | **145** | |\n\n### Convenciones de Código\n\n#### Backend (.NET)\n\n- [x] Async/await en operaciones I/O\n- [x] Records para DTOs inmutables\n- [x] Nullable habilitado\n- [x] Global usings configurados\n- [x] FluentValidation para validaciones\n\n#### Frontend (Angular)\n\n- [x] Standalone components\n- [x] Signals para estado reactivo\n- [x] Lazy loading por feature\n- [x] OnPush change detection\n- [x] Apollo Client para GraphQL\n\n### GraphQL\n\n| Criterio | Estado |\n|----------|--------|\n| Types bien definidos | ✅ |\n| DataLoaders para N+1 | ✅ |\n| Error handling | ✅ |\n| Payloads con errors | ✅ |\n| Depth limiting | ✅ |\n\n### Performance\n\n| Optimización | Implementada |\n|--------------|--------------|\n| Response compression | ✅ Brotli + Gzip |\n| Output caching | ✅ 5 min para subjects/professors |\n| Apollo cache | ✅ cache-and-network |\n| Lazy loading | ✅ Por feature module |\n| Bundle optimization | ✅ < 800KB initial |\n\n### Documentación\n\n| Documento | Estado |\n|-----------|--------|\n| README.md | ✅ |\n| DEV-GUIDE.md | ✅ |\n| OWASP_CHECKLIST.md | ✅ |\n| GraphQL Schema | ✅ (Banana Cake Pop) |\n\n---\n\n## Checklist de Revisión Manual\n\n### Antes de Merge\n\n- [ ] Todos los tests pasan\n- [ ] Build sin errores ni warnings\n- [ ] Código formateado\n- [ ] Sin TODOs pendientes críticos\n- [ ] Variables de entorno documentadas\n\n### Seguridad\n\n- [ ] Sin secrets hardcodeados\n- [ ] Sin console.log en producción\n- [ ] Validaciones en frontend Y backend\n- [ ] Error messages no exponen detalles internos\n\n### UX\n\n- [ ] Loading states implementados\n- [ ] Error messages claros\n- [ ] Responsive design funcional\n- [ ] Accesibilidad básica (a11y)\n`, "OWASP Checklist": `# OWASP Top 10 Security Checklist\n\n## Estado: Validado\n\n| # | Vulnerabilidad | Mitigación Implementada | Ubicación |\n|---|---------------|-------------------------|-----------|\n| A01 | **Broken Access Control** | No aplica (sin autenticación requerida) | N/A |\n| A02 | **Cryptographic Failures** | HTTPS forzado en producción (HSTS) | \`Program.cs:127\` |\n| A03 | **Injection** | FluentValidation + Regex sanitization, EF Core parameterized queries | \`CreateStudentValidator.cs\`, \`EnrollStudentValidator.cs\` |\n| A04 | **Insecure Design** | Clean Architecture, input validation en todas las capas | Arquitectura por capas |\n| A05 | **Security Misconfiguration** | Security headers (CSP, X-Frame-Options, etc.), Exception details disabled in prod | \`Program.cs:106-130\`, \`GraphQLExtensions.cs:53\` |\n| A06 | **Vulnerable Components** | Dependencias actualizadas (.NET 10, Angular 21) | \`*.csproj\`, \`package.json\` |\n| A07 | **Auth Failures** | No aplica (sin autenticación en este MVP) | N/A |\n| A08 | **Data Integrity Failures** | Input validation, FluentValidation, GraphQL type safety | Validators |\n| A09 | **Security Logging Failures** | Serilog structured logging, sensitive data filtering | \`appsettings.json:38-45\` |\n| A10 | **Server-Side Request Forgery** | No endpoints que acepten URLs externas | N/A |\n\n## Medidas de Seguridad Implementadas\n\n### Backend (.NET)\n\n1. **Input Validation**\n - FluentValidation con regex patterns\n - Sanitización de HTML/scripts\n - Longitud máxima de campos\n - Validación de formato email\n\n2. **Security Headers**\n - \`Content-Security-Policy\`\n - \`X-Content-Type-Options: nosniff\`\n - \`X-Frame-Options: DENY\`\n - \`Referrer-Policy: strict-origin-when-cross-origin\`\n - \`Permissions-Policy\`\n - \`Strict-Transport-Security\` (producción)\n\n3. **Rate Limiting**\n - 100 requests/minuto para queries GraphQL\n - 30 mutations/minuto\n - Queue limit para prevenir acumulación\n\n4. **GraphQL Security**\n - Query depth limit: 5 niveles\n - Query complexity limit: 100\n - Execution timeout: 30 segundos\n - Pagination max: 50 items\n\n5. **Logging Seguro**\n - Filtrado de datos sensibles (passwords, tokens)\n - Structured logging con Serilog\n - Rotación de logs (7 días)\n\n### Frontend (Angular)\n\n1. **XSS Prevention**\n - Angular sanitization por defecto\n - Content Security Policy\n\n2. **CSRF Protection**\n - No cookies de sesión (stateless GraphQL)\n\n3. **Secure Communication**\n - Solo HTTPS en producción\n - GraphQL sobre HTTPS\n\n## Pruebas de Seguridad Recomendadas\n\n\`\`\`bash\n# Test security headers\ncurl -I http://localhost:5000/graphql\n\n# Test rate limiting (debe retornar 429 después de 100 requests)\nfor i in {1..150}; do curl -s -o /dev/null -w "%{http_code}\\n" http://localhost:5000/graphql; done\n\n# Test query depth (debe fallar con depth > 5)\ncurl -X POST http://localhost:5000/graphql \\\n -H "Content-Type: application/json" \\\n -d '{"query":"{ students { enrollments { subject { professor { subjects { name } } } } } }"}'\n\`\`\`\n`, "Recomendaciones": `# Recomendaciones Finales\n\n**Fecha:** 2026-01-08\n**Proyecto:** Sistema de Inscripción de Estudiantes\n**Versión:** 1.0\n\n---\n\n## Resumen del Estado Actual\n\nEl sistema cumple con todos los requisitos funcionales de la prueba técnica:\n\n| Requisito | Estado |\n|-----------|--------|\n| CRUD de estudiantes | ✅ Implementado |\n| Programa de créditos (10 materias, 3 créditos c/u) | ✅ Implementado |\n| Máximo 3 materias por estudiante | ✅ Implementado |\n| 5 profesores con 2 materias c/u | ✅ Implementado |\n| Restricción de mismo profesor | ✅ Implementado |\n| Ver compañeros de clase (solo nombres) | ✅ Implementado |\n| Autenticación y autorización | ✅ Implementado |\n| Recuperación de contraseña | ✅ Implementado |\n\n---\n\n## Recomendaciones Técnicas\n\n### 1. Seguridad\n\n#### Alta Prioridad\n- **Rate Limiting:** Implementar limitación de solicitudes en endpoints de autenticación para prevenir ataques de fuerza bruta.\n- **Refresh Tokens:** Actualmente solo se usa un token JWT. Implementar refresh tokens para mejor seguridad.\n- **Logging de Auditoría:** Agregar logs para acciones sensibles (login fallido, cambio de contraseña, etc.).\n\n#### Media Prioridad\n- **CORS Restrictivo:** Revisar configuración de CORS para producción (actualmente permite localhost).\n- **Helmet Headers:** Agregar headers de seguridad HTTP en producción.\n\n### 2. Rendimiento\n\n#### Alta Prioridad\n- **Paginación:** La query \`students\` debería usar paginación para escalabilidad.\n- **DataLoaders:** Ya implementados, pero verificar N+1 queries en GraphQL.\n\n#### Media Prioridad\n- **Caché de Apollo:** Optimizar políticas de caché en frontend para reducir llamadas al servidor.\n- **Compression:** Habilitar Brotli/gzip en nginx para assets estáticos.\n\n### 3. Calidad de Código\n\n#### Alta Prioridad\n- **Tests E2E:** Los tests de Playwright existen pero deben ejecutarse en CI/CD.\n- **Cobertura de Tests:** Aumentar cobertura en Domain y Application layers.\n\n#### Media Prioridad\n- **Error Handling Centralizado:** Crear interceptor global para manejo de errores GraphQL.\n- **Typing Estricto:** Generar tipos TypeScript desde el schema GraphQL automáticamente.\n\n### 4. DevOps\n\n#### Alta Prioridad\n- **Health Checks:** Mejorar endpoint \`/health\` para incluir dependencias externas.\n- **Secrets Management:** No hardcodear credenciales en manifiestos de k8s (usar Sealed Secrets o Vault).\n\n#### Media Prioridad\n- **Monitoring:** Agregar métricas con Prometheus y dashboards en Grafana.\n- **Logging Centralizado:** Configurar stack ELK o Loki para logs.\n\n---\n\n## Mejoras Funcionales Sugeridas\n\n### Corto Plazo (Sprint actual)\n1. **Confirmación de Cancelación:** Agregar diálogo de confirmación antes de desinscribir materia.\n2. **Notificaciones Push:** Informar a estudiantes cuando un compañero se inscribe en su clase.\n3. **Validación de Email:** Agregar validación de formato de email en frontend.\n\n### Mediano Plazo (2-4 sprints)\n1. **Horarios:** Agregar horarios a materias para evitar conflictos.\n2. **Waitlist:** Implementar lista de espera para materias muy demandadas.\n3. **Reportes:** Dashboard administrativo con métricas de inscripciones.\n\n### Largo Plazo (Roadmap)\n1. **Multi-tenant:** Soporte para múltiples instituciones.\n2. **Integración LMS:** Conectar con sistemas de gestión de aprendizaje.\n3. **App Mobile:** Versión móvil nativa con Flutter/React Native.\n\n---\n\n## Arquitectura\n\n### Fortalezas Actuales\n- **Clean Architecture:** Separación clara de capas (Domain, Application, Adapters).\n- **CQRS:** Comandos y queries bien separados con MediatR.\n- **GraphQL:** API flexible con HotChocolate.\n- **Angular Signals:** Estado reactivo moderno y eficiente.\n\n### Áreas de Mejora\n1. **Event Sourcing:** Considerar para auditoría completa de inscripciones.\n2. **SAGA Pattern:** Para operaciones distribuidas (si se escala a microservicios).\n3. **API Gateway:** Si se agregan más servicios, usar Kong o Traefik.\n\n---\n\n## Checklist de Producción\n\n### Pre-Deployment\n- [ ] Variables de entorno configuradas (no hardcoded)\n- [ ] Connection strings seguros\n- [ ] JWT secret rotado\n- [ ] CORS configurado para dominio de producción\n- [ ] SSL/TLS configurado\n- [ ] Rate limiting habilitado\n- [ ] Logging en nivel apropiado (Warning en prod)\n\n### Post-Deployment\n- [ ] Smoke tests ejecutados\n- [ ] Monitoreo activo\n- [ ] Alertas configuradas\n- [ ] Backup de base de datos verificado\n- [ ] Runbook de incidentes documentado\n\n---\n\n## Conclusión\n\nEl sistema está **listo para demostración** y cumple con todos los requisitos de la prueba técnica. Las recomendaciones anteriores son para un escenario de producción real y escalamiento futuro.\n\n**Puntos destacados:**\n- Arquitectura sólida y mantenible\n- Reglas de negocio correctamente implementadas en el dominio\n- UI moderna y responsiva\n- Buena cobertura de casos de uso\n\n**Próximos pasos inmediatos:**\n1. ~~Ejecutar pruebas de regresión tras las correcciones de defectos~~ ✅ Completado\n2. Preparar ambiente de demostración\n3. Documentar proceso de instalación para evaluadores\n\n---\n\n## Actualización 2026-01-08: CI/CD y Deployment\n\n### Implementaciones Realizadas\n\n#### 1. CI/CD con Gitea Actions\n- **Pipeline:** \`.gitea/workflows/deploy.yaml\`\n- **Características:**\n - Builds paralelos de API y Frontend\n - Caché de Docker layers (GitHub Actions cache)\n - Deploy automático en push a \`main\`\n - Health check post-deploy\n\n#### 2. Kubernetes (k3s) Deployment\n- **Namespace:** \`academia\`\n- **Servicios:** student-api, student-frontend, sqlserver\n- **Ingress:** \`academia.ingeniumcodex.com\` (Traefik)\n- **Seguridad:** NetworkPolicy (default-deny + allow rules)\n- **TLS:** Configurado con cert-manager\n\n#### 3. Optimizaciones de Deployment\n| Optimización | Beneficio |\n|--------------|-----------|\n| Builds paralelos | Reduce tiempo de CI ~40% |\n| Docker layer cache | Builds incrementales más rápidos |\n| Artifact upload/download | Evita rebuild en deploy |\n| Rolling updates | Zero-downtime deployments |\n\n### Pruebas de Regresión Completadas\n- **Total:** 14 pruebas ejecutadas\n- **Resultado:** 100% exitosas\n- **Defectos verificados:** DEF-001 y DEF-002 corregidos\n- **Reporte:** \`docs/qa/QA-REPORT-2026-01-08-REGRESSION-TESTS.md\`\n\n### URLs de Producción\n| Servicio | URL |\n|----------|-----|\n| Frontend | https://academia.ingeniumcodex.com |\n| GraphQL API | https://academia.ingeniumcodex.com/graphql |\n| Health Check | https://academia.ingeniumcodex.com/health |\n\n### Repositorio Git\n- **URL:** https://devops.ingeniumcodex.com/andresgarcia0313/academia.git\n- **CI/CD:** Auto-deploy en push a main\n`, - "Defectos QA": `# Reporte de Pruebas Manuales QA\n\n**Fecha:** 2026-01-08\n**Tester:** Claude Code\n**Ambiente:** Desarrollo Local (localhost:4200 / localhost:5000)\n\n---\n\n## Resumen Ejecutivo\n\n| Categoría | Total | Pasaron | Fallaron | Corregidos |\n|-----------|-------|---------|----------|------------|\n| CRUD Estudiantes | 4 | 4 | 0 | 1 |\n| Inscripciones | 5 | 5 | 0 | 0 |\n| Compañeros | 2 | 2 | 0 | 0 |\n| **Total** | **11** | **11** | **0** | **1** |\n\n---\n\n## Capturas de Pantalla\n\n| # | Archivo | Descripción |\n|---|---------|-------------|\n| 01 | \`01-inicio-cargando.png\` | Página inicial cargando |\n| 02 | \`02-formulario-nuevo-estudiante.png\` | Formulario de nuevo estudiante |\n| 03 | \`03-formulario-lleno.png\` | Formulario con datos |\n| 04 | \`04-estudiante-creado.png\` | Estudiante creado exitosamente |\n| 05 | \`05-DEFECTO-editar-estudiante-no-encontrado.png\` | **DEFECTO: Error al editar** |\n| 06 | \`06-pagina-inscripcion.png\` | Página de inscripción |\n| 07 | \`07-inscripcion-exitosa-regla-profesor.png\` | Regla de profesor funcionando |\n| 08 | \`08-maximo-3-materias.png\` | Límite de materias visible |\n| 09 | \`09-creditos-maximos-9-9.png\` | 9/9 créditos alcanzados |\n| 10 | \`10-dos-estudiantes.png\` | Lista con dos estudiantes |\n| 11 | \`11-companeros-de-clase.png\` | Vista de compañeros |\n| 12 | \`12-confirmar-eliminacion.png\` | Diálogo de confirmación |\n| 13 | \`13-estudiante-eliminado.png\` | Estudiante eliminado |\n| 14 | \`14-CORREGIDO-editar-estudiante-funciona.png\` | **CORREGIDO: Editar funciona** |\n\n---\n\n## Defectos Encontrados\n\n### DEFECTO #1: Error "Estudiante no encontrado" al editar\n\n**ID:** DEF-001\n**Severidad:** Alta\n**Prioridad:** P1\n**Estado:** RESUELTO\n\n#### Descripcion\nAl hacer clic en el boton de editar (icono de lapiz) en la lista de estudiantes, aparece un snackbar con el mensaje "Estudiante no encontrado" en lugar de abrir el formulario de edicion.\n\n#### Pasos para Reproducir\n1. Ir a http://localhost:4200/students\n2. Crear un nuevo estudiante\n3. En la tabla, hacer clic en el boton de editar (icono de lapiz)\n4. **Resultado (antes):** Aparecia mensaje "Estudiante no encontrado"\n5. **Resultado (despues del fix):** El formulario de edicion abre correctamente\n\n#### Capturas de Pantalla\n| Estado | Captura |\n|--------|---------|\n| Antes | ![Defecto](../.playwright-mcp/05-DEFECTO-editar-estudiante-no-encontrado.png) |\n| Despues | ![Corregido](../.playwright-mcp/14-CORREGIDO-editar-estudiante-funciona.png) |\n\n#### Causa Raiz Identificada\nSe encontraron **DOS problemas** combinados:\n\n1. **Problema de navegacion:** El boton de editar usaba \`\n\n// DESPUES (funciona)\n\n edit\n\n\`\`\`\n\n#### Fix 2: Usar \`effect()\` en lugar de \`ngOnInit\` en student-form.component.ts\n\n\`\`\`typescript\n// ANTES (no funcionaba - el input signal no estaba listo en ngOnInit)\nngOnInit(): void {\n const studentId = this.id();\n if (studentId) {\n this.loadStudent(parseInt(studentId, 10));\n }\n}\n\n// DESPUES (funciona - effect reacciona cuando el signal tiene valor)\nconstructor() {\n effect(() => {\n const studentId = this.id();\n if (studentId && !this.isEditing()) {\n this.isEditing.set(true);\n this.loadStudent(parseInt(studentId, 10));\n }\n });\n}\n\`\`\`\n\n### Validacion del Fix\n- El formulario de edicion carga correctamente con los datos del estudiante\n- La actualizacion de datos funciona sin errores\n- No aparece mas el snackbar "Estudiante no encontrado"\n\n---\n\n## Funcionalidades Verificadas (OK)\n\n### Crear Estudiante\n- Formulario con validación de campos requeridos\n- Botón deshabilitado hasta completar campos\n- Mensaje de éxito al crear\n- Redirección a lista de estudiantes\n\n### Inscripción en Materias\n- Lista de 10 materias con 5 profesores\n- Regla de negocio: No repetir profesor (FUNCIONA)\n- Regla de negocio: Máximo 3 materias (FUNCIONA)\n- Indicadores visuales de disponibilidad\n- Mensajes claros de restricciones\n\n### Ver Compañeros\n- Lista de materias inscritas\n- Nombres de compañeros visibles\n- Mensaje cuando no hay compañeros\n\n### Eliminar Estudiante\n- Diálogo de confirmación\n- Mensaje de éxito al eliminar\n- Actualización de lista\n\n---\n\n## Recomendaciones\n\n### Mejoras de UX\n1. Agregar tooltips a los botones de acción\n2. Mostrar spinner durante operaciones async\n3. Agregar confirmación antes de cancelar inscripción\n\n### Mejoras Técnicas\n1. Implementar caché de estudiantes para evitar consultas repetidas\n2. Agregar paginación a la lista de estudiantes\n3. Implementar búsqueda/filtro de estudiantes\n\n### Mejoras de Calidad\n1. Agregar tests E2E con Playwright\n2. Implementar monitoreo de errores (Sentry)\n3. Agregar métricas de rendimiento\n\n---\n\n*Reporte generado automáticamente durante pruebas manuales con Playwright MCP*\n`, + "Defectos QA": `# Reporte de Pruebas Manuales QA\n\n**Fecha:** 2026-01-08\n**Tester:** QA Team\n**Ambiente:** Desarrollo Local (localhost:4200 / localhost:5000)\n\n---\n\n## Resumen Ejecutivo\n\n| Categoría | Total | Pasaron | Fallaron | Corregidos |\n|-----------|-------|---------|----------|------------|\n| CRUD Estudiantes | 4 | 4 | 0 | 1 |\n| Inscripciones | 5 | 5 | 0 | 0 |\n| Compañeros | 2 | 2 | 0 | 0 |\n| **Total** | **11** | **11** | **0** | **1** |\n\n---\n\n## Capturas de Pantalla\n\n| # | Archivo | Descripción |\n|---|---------|-------------|\n| 01 | \`01-inicio-cargando.png\` | Página inicial cargando |\n| 02 | \`02-formulario-nuevo-estudiante.png\` | Formulario de nuevo estudiante |\n| 03 | \`03-formulario-lleno.png\` | Formulario con datos |\n| 04 | \`04-estudiante-creado.png\` | Estudiante creado exitosamente |\n| 05 | \`05-DEFECTO-editar-estudiante-no-encontrado.png\` | **DEFECTO: Error al editar** |\n| 06 | \`06-pagina-inscripcion.png\` | Página de inscripción |\n| 07 | \`07-inscripcion-exitosa-regla-profesor.png\` | Regla de profesor funcionando |\n| 08 | \`08-maximo-3-materias.png\` | Límite de materias visible |\n| 09 | \`09-creditos-maximos-9-9.png\` | 9/9 créditos alcanzados |\n| 10 | \`10-dos-estudiantes.png\` | Lista con dos estudiantes |\n| 11 | \`11-companeros-de-clase.png\` | Vista de compañeros |\n| 12 | \`12-confirmar-eliminacion.png\` | Diálogo de confirmación |\n| 13 | \`13-estudiante-eliminado.png\` | Estudiante eliminado |\n| 14 | \`14-CORREGIDO-editar-estudiante-funciona.png\` | **CORREGIDO: Editar funciona** |\n\n---\n\n## Defectos Encontrados\n\n### DEFECTO #1: Error "Estudiante no encontrado" al editar\n\n**ID:** DEF-001\n**Severidad:** Alta\n**Prioridad:** P1\n**Estado:** RESUELTO\n\n#### Descripcion\nAl hacer clic en el boton de editar (icono de lapiz) en la lista de estudiantes, aparece un snackbar con el mensaje "Estudiante no encontrado" en lugar de abrir el formulario de edicion.\n\n#### Pasos para Reproducir\n1. Ir a http://localhost:4200/students\n2. Crear un nuevo estudiante\n3. En la tabla, hacer clic en el boton de editar (icono de lapiz)\n4. **Resultado (antes):** Aparecia mensaje "Estudiante no encontrado"\n5. **Resultado (despues del fix):** El formulario de edicion abre correctamente\n\n#### Capturas de Pantalla\n| Estado | Captura |\n|--------|---------|\n| Antes | ![Defecto](../.playwright-mcp/05-DEFECTO-editar-estudiante-no-encontrado.png) |\n| Despues | ![Corregido](../.playwright-mcp/14-CORREGIDO-editar-estudiante-funciona.png) |\n\n#### Causa Raiz Identificada\nSe encontraron **DOS problemas** combinados:\n\n1. **Problema de navegacion:** El boton de editar usaba \`\n\n// DESPUES (funciona)\n\n edit\n\n\`\`\`\n\n#### Fix 2: Usar \`effect()\` en lugar de \`ngOnInit\` en student-form.component.ts\n\n\`\`\`typescript\n// ANTES (no funcionaba - el input signal no estaba listo en ngOnInit)\nngOnInit(): void {\n const studentId = this.id();\n if (studentId) {\n this.loadStudent(parseInt(studentId, 10));\n }\n}\n\n// DESPUES (funciona - effect reacciona cuando el signal tiene valor)\nconstructor() {\n effect(() => {\n const studentId = this.id();\n if (studentId && !this.isEditing()) {\n this.isEditing.set(true);\n this.loadStudent(parseInt(studentId, 10));\n }\n });\n}\n\`\`\`\n\n### Validacion del Fix\n- El formulario de edicion carga correctamente con los datos del estudiante\n- La actualizacion de datos funciona sin errores\n- No aparece mas el snackbar "Estudiante no encontrado"\n\n---\n\n## Funcionalidades Verificadas (OK)\n\n### Crear Estudiante\n- Formulario con validación de campos requeridos\n- Botón deshabilitado hasta completar campos\n- Mensaje de éxito al crear\n- Redirección a lista de estudiantes\n\n### Inscripción en Materias\n- Lista de 10 materias con 5 profesores\n- Regla de negocio: No repetir profesor (FUNCIONA)\n- Regla de negocio: Máximo 3 materias (FUNCIONA)\n- Indicadores visuales de disponibilidad\n- Mensajes claros de restricciones\n\n### Ver Compañeros\n- Lista de materias inscritas\n- Nombres de compañeros visibles\n- Mensaje cuando no hay compañeros\n\n### Eliminar Estudiante\n- Diálogo de confirmación\n- Mensaje de éxito al eliminar\n- Actualización de lista\n\n---\n\n## Recomendaciones\n\n### Mejoras de UX\n1. Agregar tooltips a los botones de acción\n2. Mostrar spinner durante operaciones async\n3. Agregar confirmación antes de cancelar inscripción\n\n### Mejoras Técnicas\n1. Implementar caché de estudiantes para evitar consultas repetidas\n2. Agregar paginación a la lista de estudiantes\n3. Implementar búsqueda/filtro de estudiantes\n\n### Mejoras de Calidad\n1. Agregar tests E2E con Playwright\n2. Implementar monitoreo de errores (Sentry)\n3. Agregar métricas de rendimiento\n\n---\n\n*Reporte generado automáticamente durante pruebas manuales con Playwright MCP*\n`, }, };