Student Enrollment System - .NET/Angular
Go to file
Andrés Eduardo García Márquez e2fdea8f9e ci: remove checkout action, use passwordless sudo, simplify workflow
- No checkout needed (code pulled via git on K3s server)
- Use passwordless sudo on K3s server
- Simplified smoke tests to single step
- Reduced workflow complexity
2026-01-09 07:51:24 -05:00
.gitea/workflows ci: remove checkout action, use passwordless sudo, simplify workflow 2026-01-09 07:51:24 -05:00
deploy chore(deploy): update deployment config and add utility scripts 2026-01-09 07:44:43 -05:00
docs refactor(qa): reorganize QA documentation structure 2026-01-09 07:44:22 -05:00
scripts docs(qa): add manual QA testing report and dev startup script 2026-01-08 08:41:24 -05:00
src test(e2e): add Playwright tests for auth and enrollment 2026-01-09 07:43:13 -05:00
tests feat(auth): implement account activation backend 2026-01-09 07:42:05 -05:00
.env.example docs: add project documentation and env template 2026-01-07 23:00:56 -05:00
.gitignore docs: add credentials section and update namespace to academia 2026-01-08 16:48:56 -05:00
CLAUDE.md docs: update project documentation for activation feature 2026-01-09 07:43:57 -05:00
README.md docs(readme): add test coverage summary and commands 2026-01-09 07:45:07 -05:00
generate-docs.sh chore(deploy): update deployment config and add utility scripts 2026-01-09 07:44:43 -05:00
index.html chore(deploy): update deployment config and add utility scripts 2026-01-09 07:44:43 -05:00
start.backend.sh chore(deploy): update deployment config and add utility scripts 2026-01-09 07:44:43 -05:00
start.db.sh chore(deploy): update deployment config and add utility scripts 2026-01-09 07:44:43 -05:00
start.db.simple.sh chore(deploy): update deployment config and add utility scripts 2026-01-09 07:44:43 -05:00
start.frontend.sh feat(deploy): add Docker and Kubernetes deployment 2026-01-07 23:00:41 -05:00
start.webclient.sh feat(deploy): add Docker and Kubernetes deployment 2026-01-07 23:00:41 -05:00

README.md

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
  • Sistema de autenticación con flujo de activación
  • Control de acceso por roles (Admin/Student)

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

Inicio Rápido

Paso 1: Clonar e ir al directorio

git clone <repo-url>
cd Interrapidisimo

Paso 2: Iniciar SQL Server con Docker

docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=Asde71.4Asde71.4" \
  -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

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:

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

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

cd src/backend

# Build y ejecución
dotnet build
dotnet run --project Host
dotnet watch run --project Host    # Hot reload

# Tests - Todos
dotnet test tests/Application.Tests
dotnet test tests/Domain.Tests
dotnet test tests/Integration.Tests

# Tests - Solo Auth
dotnet test tests/Application.Tests --filter "FullyQualifiedName~Auth"

# 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

cd src/frontend

npx ng serve                          # Desarrollo
npx ng build --configuration prod     # Producción
npx ng test                           # Tests unitarios
npx ng lint                           # Linting

# E2E Tests
npx playwright test                   # Todos
npx playwright test auth.spec.ts      # Solo auth
npx playwright test --reporter=html   # Con reporte HTML

Tests Automatizados

Resumen

Tipo Cantidad Estado
Application Tests 98 100%
Domain Tests 30 100%
Integration Tests 5 100%
E2E Tests 97 ⚠️ 26%
Total 230

Tests de Auth (Backend)

Handler Tests Cobertura
LoginCommand 6 Credenciales válidas/inválidas
RegisterCommand 8 Registro, duplicados, validaciones
ResetPasswordCommand 8 Reset válido/inválido
ActivateAccountCommand 10 Activación, expiración, JWT

Tests E2E (Playwright)

Categoría Tests Descripción
Autenticación 15 Login, registro, reset
Control de Acceso 16 Roles Admin/Student
Reglas de Negocio 16 Max 3 materias, mismo profesor
Activación 18 Flujo completo de activación
CRUD 32 Estudiantes, inscripciones, compañeros

Docker

# 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 "Asde71.4Asde71.4" -C

API GraphQL

Queries

# 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

# 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

# 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

# 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 "Asde71.4Asde71.4" -C -Q "SELECT 1"

Puerto 5000 en uso

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

cd src/backend
dotnet ef database update -p Adapters/Driven/Persistence -s Host

Error "No migrations were found"

Crear migración inicial:

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:

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=localhost;Database=StudentEnrollment;User Id=sa;Password=Asde71.4Asde71.4;TrustServerCertificate=True"
  }
}

Error npm ERESOLVE (conflicto de dependencias)

Si aparecen errores de peer dependencies al instalar el frontend:

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:

npx ng serve
npx ng build

Despliegue

Docker Compose (Recomendado)

Despliegue optimizado con un solo comando:

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:

Comandos útiles:

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

cd deploy/k3s
./deploy.sh

Ver DEPLOYMENT.md para instrucciones detalladas.

Documentación

Análisis

Diseño

Configuración

Operaciones

Diagramas UML

Autenticación y Roles

Flujo de Activación de Estudiantes

1. Admin crea estudiante → Sistema genera código de activación (12 chars)
2. Admin comparte código/URL con estudiante
3. Estudiante accede a /activate?code=XXXX
4. Estudiante crea credenciales (usuario + contraseña)
5. Sistema genera código de recuperación (mostrado una sola vez)
6. Estudiante inicia sesión → Dashboard personal

Roles del Sistema

Rol Permisos
Admin CRUD estudiantes, ver todo, generar códigos de activación
Student Dashboard personal, inscribir materias, ver compañeros

URLs de Autenticación

Ruta Descripción
/login Inicio de sesión
/activate?code=XXX Activación de cuenta
/dashboard Dashboard de estudiante
/admin Panel de administración

Seguridad

  • JWT con HMAC-SHA256, expiración configurable
  • PBKDF2-SHA256 para hashing de contraseñas (100,000 iteraciones)
  • Código de activación: 12 caracteres, expira en 48 horas
  • Código de recuperación: 12 caracteres, se muestra solo una vez
  • 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