commit dfcfca0b4e4872e9b8b2b9add40a7f4ca8d1fe58 Author: Andrés Eduardo García Márquez Date: Wed Jan 7 22:58:56 2026 -0500 chore: add initial project configuration - Add .gitignore for .NET, Node.js, and IDE files - Add README.md with project overview diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3c2add9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,145 @@ +# ═══════════════════════════════════════════════════════════════ +# .NET / C# +# ═══════════════════════════════════════════════════════════════ +bin/ +obj/ +*.dll +*.exe +*.pdb +*.user +*.suo +*.cache +*.log +*.vspscc +*.vssscc +.vs/ +*.nupkg +project.lock.json +*.nuget.props +*.nuget.targets + +# User-specific files +*.rsuser +*.userprefs + +# Build results +[Dd]ebug/ +[Rr]elease/ +x64/ +x86/ +[Bb]uild/ +bld/ + +# NuGet +packages/ +*.nupkg +.nuget/ + +# Entity Framework +*.mdf +*.ldf + +# ═══════════════════════════════════════════════════════════════ +# Node.js / Angular +# ═══════════════════════════════════════════════════════════════ +node_modules/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.npm/ +.yarn/ +.pnpm-store/ + +# Angular +dist/ +.angular/ +.sass-cache/ +*.css.map +*.js.map + +# TypeScript +*.tsbuildinfo + +# ═══════════════════════════════════════════════════════════════ +# IDE / Editors +# ═══════════════════════════════════════════════════════════════ +# VS Code +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +# JetBrains (Rider, WebStorm) +.idea/ +*.iml + +# Visual Studio +.vs/ +*.sln.docstates + +# ═══════════════════════════════════════════════════════════════ +# Logs +# ═══════════════════════════════════════════════════════════════ +logs/ +*.log +npm-debug.log* + +# ═══════════════════════════════════════════════════════════════ +# Environment / Secrets +# ═══════════════════════════════════════════════════════════════ +.env +.env.local +.env.*.local +*.env +appsettings.*.local.json +secrets.json +credentials.json + +# ═══════════════════════════════════════════════════════════════ +# Docker +# ═══════════════════════════════════════════════════════════════ +.docker/ + +# ═══════════════════════════════════════════════════════════════ +# Testing +# ═══════════════════════════════════════════════════════════════ +coverage/ +*.lcov +.nyc_output/ +test-results/ +TestResults/ +playwright-report/ +playwright/.cache/ + +# ═══════════════════════════════════════════════════════════════ +# OS Generated +# ═══════════════════════════════════════════════════════════════ +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db +desktop.ini + +# ═══════════════════════════════════════════════════════════════ +# Misc +# ═══════════════════════════════════════════════════════════════ +*.tmp +*.temp +*.swp +*.swo +*~ +.cache/ +tmp/ +temp/ +CLAUDE.md + +# ═══════════════════════════════════════════════════════════════ +# Data / Runtime +# ═══════════════════════════════════════════════════════════════ +data/ +*.bak +*.backup diff --git a/README.md b/README.md new file mode 100644 index 0000000..4a7d060 --- /dev/null +++ b/README.md @@ -0,0 +1,498 @@ +# Sistema de Registro de Estudiantes + +Sistema web para gestionar inscripciones de estudiantes en materias con restricciones de créditos y profesores. + +## Stack Tecnológico + +| Capa | Tecnología | +|------|------------| +| Backend | .NET 10, C# | +| API | GraphQL (HotChocolate) | +| Frontend | Angular 21, TypeScript | +| Base de Datos | SQL Server 2022 | +| ORM | Entity Framework Core | +| UI | Angular Material | + +## Reglas de Negocio + +- 10 materias, cada una vale 3 créditos +- 5 profesores, cada uno imparte 2 materias +- Estudiantes pueden inscribir **máximo 3 materias** (9 créditos) +- **Restricción:** Un estudiante NO puede tener materias con el mismo profesor + +## Características del Sistema + +### Funcionalidades +- CRUD completo de estudiantes +- Inscripción/cancelación de materias con validación de reglas +- Visualización de compañeros de clase por materia +- Interfaz responsive con Angular Material + +### Calidad y Robustez +- **Manejo de errores**: Mensajes amigables para usuarios + logging detallado para desarrolladores +- **Monitoreo de conectividad**: Verificación cada 5 segundos con overlay bloqueante si se pierde conexión +- **Validación**: FluentValidation en backend + validación reactiva en frontend +- **Arquitectura**: Clean Architecture + CQRS + Ports & Adapters + +### DevOps +- **Docker Compose**: Despliegue optimizado con un solo comando (`./start.sh`) +- **Health Check**: Endpoint `/health` con verificación de base de datos +- **Diagramas UML**: 8 diagramas PlantUML documentando la arquitectura + +## Requisitos Previos + +- [.NET 10 SDK](https://dotnet.microsoft.com/download) +- [Node.js 22+](https://nodejs.org/) +- [Docker](https://www.docker.com/) (para SQL Server) +- Angular CLI 21: `npm install -g @angular/cli` + +## Inicio Rápido + +### Paso 1: Clonar e ir al directorio + +```bash +git clone +cd Interrapidisimo +``` + +### Paso 2: Iniciar SQL Server con Docker + +```bash +docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=Your_password123" \ + -p 1433:1433 --name sqlserver -d mcr.microsoft.com/mssql/server:2022-latest +``` + +Esperar ~10 segundos a que inicie completamente. + +### Paso 3: Configurar y ejecutar Backend + +```bash +cd src/backend + +# 1. Instalar herramienta EF Core (solo primera vez) +dotnet tool install --global dotnet-ef +# Si ya está instalada, ignorar el mensaje + +# 2. Restaurar dependencias +dotnet restore + +# 3. Crear base de datos y aplicar migraciones +dotnet ef database update -p Adapters/Driven/Persistence -s Host +# NOTA: El mensaje "HostAbortedException" es NORMAL - indica que las migraciones se completaron + +# 4. Liberar puerto si está ocupado (opcional) +fuser -k 5000/tcp 2>/dev/null + +# 5. Ejecutar API +dotnet run --project Host +``` + +**API GraphQL:** http://localhost:5000/graphql + +### Paso 4: Verificar que funciona + +En otra terminal: + +```bash +# Consultar materias (debe retornar 10) +curl -s http://localhost:5000/graphql -X POST \ + -H "Content-Type: application/json" \ + -d '{"query":"{ subjects { id name credits } }"}' | jq . + +# Crear un estudiante +curl -s http://localhost:5000/graphql -X POST \ + -H "Content-Type: application/json" \ + -d '{"query":"mutation { createStudent(input: {name: \"Test User\", email: \"test@example.com\"}) { student { id name email } } }"}' | jq . +``` + +### Paso 5: Frontend (opcional) + +```bash +cd src/frontend + +# Instalar dependencias (usar --legacy-peer-deps por compatibilidad) +npm install --legacy-peer-deps + +# Iniciar servidor de desarrollo +npx ng serve +``` + +**App Angular:** http://localhost:4200 + +> **Nota:** Si `ng` no está instalado globalmente, usar `npx ng serve` + +## Datos de Ejemplo + +La migración incluye datos iniciales: + +| Profesor | Materias | +|----------|----------| +| Dr. García | Matemáticas I, Matemáticas II | +| Dra. López | Física I, Física II | +| Ing. Martínez | Programación I, Programación II | +| Ing. Rodríguez | Base de Datos I, Base de Datos II | +| Ing. Sánchez | Redes I, Redes II | + +## Arquitectura + +``` +Clean Architecture + CQRS + Ports & Adapters + +┌─────────────────────────────────────────┐ +│ HOST │ +│ (DI, Configuration) │ +└────────────────┬────────────────────────┘ + │ +┌────────────────▼────────────────────────┐ +│ ADAPTERS │ +│ Driving: GraphQL Driven: EF Core │ +└────────────────┬────────────────────────┘ + │ +┌────────────────▼────────────────────────┐ +│ APPLICATION │ +│ Commands / Queries / Validators │ +└────────────────┬────────────────────────┘ + │ +┌────────────────▼────────────────────────┐ +│ DOMAIN │ +│ Entities / Value Objects / Ports │ +└─────────────────────────────────────────┘ +``` + +## Estructura del Proyecto + +``` +/ +├── src/ +│ ├── backend/ +│ │ ├── Domain/ # Entities, ValueObjects, Ports, Services +│ │ ├── Application/ # Commands, Queries, DTOs, Validators +│ │ ├── Adapters/ +│ │ │ ├── Driving/Api/ # GraphQL (HotChocolate) +│ │ │ └── Driven/Persistence/ # EF Core, Repositories, DataLoaders +│ │ └── Host/ # Entry point, DI, Configuration +│ └── frontend/ +│ ├── src/app/ # Core, Shared, Features +│ └── e2e/ # Playwright E2E tests +├── tests/ +│ ├── Domain.Tests/ # Entity, ValueObject, Service tests +│ ├── Application.Tests/ # Command, Query, Validator tests +│ └── Integration.Tests/ # End-to-end flow tests +├── docs/ +│ ├── entregables/ # 01-analisis, 02-diseno, 03-configuracion +│ └── architecture/decisions/ # ADRs +├── database/ +│ ├── stored-procedures/ +│ └── views/ +└── deploy/ + ├── docker/ + ├── k3s/ # Kubernetes manifests + └── scripts/ +``` + +## Comandos Útiles + +### Backend + +```bash +cd src/backend + +# Build y ejecución +dotnet build +dotnet run --project Host +dotnet watch run --project Host # Hot reload + +# Tests +dotnet test + +# Migraciones EF Core +dotnet ef migrations add -p Adapters/Driven/Persistence -s Host +dotnet ef database update -p Adapters/Driven/Persistence -s Host +dotnet ef migrations list -p Adapters/Driven/Persistence -s Host +``` + +### Frontend + +```bash +cd src/frontend + +npx ng serve # Desarrollo +npx ng build --configuration prod # Producción +npx ng test # Tests unitarios +npx ng lint # Linting +``` + +### Docker + +```bash +# Ver contenedor SQL Server +docker ps | grep sqlserver + +# Logs +docker logs sqlserver + +# Reiniciar +docker restart sqlserver + +# Conectar con sqlcmd +docker exec -it sqlserver /opt/mssql-tools18/bin/sqlcmd \ + -S localhost -U sa -P "Your_password123" -C +``` + +## API GraphQL + +### Queries + +```graphql +# Listar estudiantes +query { + students { + id + name + email + totalCredits + enrollments { subjectId } + } +} + +# Obtener estudiante por ID +query { + student(id: 1) { + id + name + email + totalCredits + } +} + +# Listar materias +query { + subjects { + id + name + credits + professorId + } +} +``` + +### Mutations + +```graphql +# Crear estudiante +mutation { + createStudent(input: { name: "Juan Pérez", email: "juan@test.com" }) { + student { id name email } + } +} + +# Inscribir en materia +mutation { + enrollStudent(input: { studentId: 1, subjectId: 1 }) { + enrollment { id } + } +} + +# Cancelar inscripción +mutation { + unenrollStudent(enrollmentId: 1) { + success + } +} +``` + +## Solución de Problemas + +### `dotnet-ef` no encontrado + +```bash +# Instalar +dotnet tool install --global dotnet-ef + +# Agregar al PATH (si es necesario) +export PATH="$PATH:$HOME/.dotnet/tools" + +# Verificar instalación +dotnet ef --version +``` + +### Error de conexión a SQL Server + +```bash +# Verificar que el contenedor esté corriendo +docker ps | grep sqlserver + +# Si no está, iniciarlo +docker start sqlserver + +# Verificar conexión +docker exec -it sqlserver /opt/mssql-tools18/bin/sqlcmd \ + -S localhost -U sa -P "Your_password123" -C -Q "SELECT 1" +``` + +### Puerto 5000 en uso + +```bash +# Linux: encontrar y matar proceso +fuser -k 5000/tcp + +# Alternativa: ver qué usa el puerto +lsof -i :5000 +kill -9 +``` + +### Error "Invalid object name 'Students'" + +Las migraciones no se han aplicado: + +```bash +cd src/backend +dotnet ef database update -p Adapters/Driven/Persistence -s Host +``` + +### Error "No migrations were found" + +Crear migración inicial: + +```bash +cd src/backend +dotnet ef migrations add InitialCreate -p Adapters/Driven/Persistence -s Host +dotnet ef database update -p Adapters/Driven/Persistence -s Host +``` + +### Password incorrecto de SQL Server + +Verificar que el password en `appsettings.json` coincida con el del contenedor Docker: + +```json +{ + "ConnectionStrings": { + "DefaultConnection": "Server=localhost;Database=StudentEnrollment;User Id=sa;Password=Your_password123;TrustServerCertificate=True" + } +} +``` + +### Error npm ERESOLVE (conflicto de dependencias) + +Si aparecen errores de peer dependencies al instalar el frontend: + +```bash +cd src/frontend +rm -rf node_modules package-lock.json +npm install --legacy-peer-deps +``` + +### Error "ng: command not found" + +Usar `npx` en lugar del comando directo: + +```bash +npx ng serve +npx ng build +``` + +## Despliegue + +### Docker Compose (Recomendado) + +Despliegue optimizado con un solo comando: + +```bash +cd deploy/docker +./start.sh +``` + +El script: +1. Limpia contenedores anteriores +2. Construye imágenes optimizadas con cache +3. Inicia todos los servicios +4. Espera hasta que estén listos + +**URLs después del despliegue:** +- Frontend: http://localhost +- API GraphQL: http://localhost:5000/graphql +- SQL Server: localhost:1433 + +**Comandos útiles:** + +```bash +# Ver logs en tiempo real +docker compose logs -f + +# Solo API +docker compose logs -f api + +# Reiniciar un servicio +docker compose restart api + +# Detener todo +docker compose down + +# Rebuild sin cache +docker compose build --no-cache && docker compose up -d +``` + +**Recursos asignados (optimizado para 12 cores / 15GB RAM):** + +| Servicio | CPU | RAM | +|----------|-----|-----| +| SQL Server | 2 cores | 2.5 GB | +| API .NET | 4 cores | 1.5 GB | +| Frontend | 2 cores | 256 MB | + +### Kubernetes (k3s) + +```bash +cd deploy/k3s +./deploy.sh +``` + +Ver [DEPLOYMENT.md](docs/DEPLOYMENT.md) para instrucciones detalladas. + +## Documentación + +### Análisis +- [Requisitos Funcionales](docs/entregables/01-analisis/requisitos/AN-001-requisitos-funcionales.md) +- [Reglas de Negocio](docs/entregables/01-analisis/reglas-negocio/AN-002-reglas-negocio.md) +- [Historias de Usuario](docs/entregables/01-analisis/historias-usuario/AN-003-historias-usuario.md) + +### Diseño +- [Arquitectura Backend](docs/entregables/02-diseno/arquitectura/DI-001-arquitectura-backend.md) +- [Arquitectura Frontend](docs/entregables/02-diseno/arquitectura/DI-005-arquitectura-frontend.md) +- [Modelo de Dominio](docs/entregables/02-diseno/modelo-dominio/DI-002-modelo-dominio.md) +- [Diseño Base de Datos](docs/entregables/02-diseno/base-datos/DI-003-diseno-base-datos.md) +- [Esquema GraphQL](docs/entregables/02-diseno/esquema-graphql/DI-004-esquema-graphql.md) + +### Configuración +- [Configuración .NET](docs/entregables/03-configuracion/DV-002-configuracion-dotnet.md) +- [Configuración Angular](docs/entregables/03-configuracion/DV-003-configuracion-angular.md) +- [Variables de Entorno](docs/entregables/03-configuracion/DV-005-variables-entorno.md) + +### Operaciones +- [Manual de Despliegue](docs/DEPLOYMENT.md) +- [Decisiones de Arquitectura](docs/architecture/decisions/) +- [Checklist OWASP](docs/OWASP_CHECKLIST.md) +- [Plan de Actividades](docs/PLAN_ACTIVIDADES.md) + +### Diagramas UML +- [Casos de Uso](docs/architecture/diagrams/01-use-cases.svg) +- [Modelo de Dominio](docs/architecture/diagrams/02-domain-model.svg) +- [Secuencia: Inscripción](docs/architecture/diagrams/03-sequence-enrollment.svg) +- [Componentes](docs/architecture/diagrams/04-components.svg) +- [Entidad-Relación](docs/architecture/diagrams/05-entity-relationship.svg) +- [Estados: Inscripción](docs/architecture/diagrams/06-state-enrollment.svg) +- [Despliegue](docs/architecture/diagrams/07-deployment.svg) +- [C4 Contexto](docs/architecture/diagrams/08-c4-context.svg) + +## Seguridad + +- Input validation con FluentValidation +- Sanitización contra XSS +- Security headers (CSP, HSTS, X-Frame-Options) +- Rate limiting (100 req/min queries, 30 req/min mutations) +- Query complexity limits (depth: 5, cost: 100) +- Logging estructurado con Serilog (sin datos sensibles) + +## Licencia + +Prueba técnica - Inter Rapidísimo