# 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 <repo-url>
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 <Nombre> -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 <PID>
```

### 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
