arquitecture
sidebar_position: 2 title: Arquitectura del Sistema
Arquitectura del Sistema
Enfoque Database-Centric
Este sistema rompe el paradigma tradicional donde el backend contiene las reglas de negocio. Aquí toda la lógica vive en la base de datos.
Regla de oro: el backend es "tonto" y la base de datos es "inteligente". Ninguna validación compleja, cálculo o flujo de negocio se escribe en el servidor de aplicaciones.
Roles de cada componente
Motores de Base de Datos
El sistema usa dos motores, cada uno con un propósito distinto:
- SQL Server (
ControlDB) — base de control interna. Guarda usuarios, referencias de aprovisionamiento, auditoría y métricas. Ejecuta el 100% de su lógica mediante Stored Procedures, Views y Functions. - MySQL — motor donde se aprovisionan las bases de datos reales de los estudiantes. Su propio Stored Procedure crea la base física, el usuario MySQL, genera la contraseña y asigna permisos — todo dentro del motor, sin lógica en el backend.
Backend (.NET Web API)
- Middleware de paso: expone endpoints HTTP.
- Gestiona autenticación/autorización (JWT, OAuth Google/GitHub).
- Aplica Rate Limiting (particionado por usuario autenticado, con fallback a IP).
- Invoca los Stored Procedures/Functions/Views correspondientes.
- Mapea resultados de la base de datos hacia el cliente. No transforma ni decide reglas de negocio.
Únicas excepciones de lógica en el backend (justificadas por seguridad, no por conveniencia):
- Hasheo de contraseñas locales con BCrypt (nunca deben llegar en texto plano a la base).
- Generación de la contraseña aleatoria de MySQL antes de invocar el SP de aprovisionamiento.
- Construcción y validación del JWT.
Patrón de diseño
Se usa Repository Pattern + Dependency Inversion Principle (DIP): Controller → IRepository (interfaz, en Domain) → Repository (implementación, en Infrastructure) → SP/Function/View
El controlador y los servicios del backend solo conocen la interfaz — nunca la implementación concreta ni el motor de base de datos por debajo. Esto permite, por ejemplo, tener IDatabaseProvisioningRepository (SQL Server) e IMySqlProvisioningRepository (MySQL) coexistiendo sin que el resto del sistema necesite saber cómo cada uno habla con su motor.
Flujo de autenticación y aprovisionamiento
- El usuario se registra/inicia sesión (local, Google o GitHub).
- El backend valida credenciales o intercambia el
codede OAuth por los datos del usuario. - Un Stored Procedure (
sp_RegisterUser,sp_UpsertOAuthUser) crea o reconoce al usuario — fusionando cuentas si el mismo email se usa en distintos proveedores, para no duplicar usuarios. - Si es la primera vez que el usuario obtiene acceso, el backend invoca al SP de MySQL para aprovisionar automáticamente su base de datos.
- Se registra la referencia en
ControlDBy un evento de auditoría. - Se devuelve un JWT al cliente (frontend), que lo usa en cada petición autenticada posterior.
Seguridad aplicada
- Contraseñas locales: hash con BCrypt.
- Contraseñas de MySQL: generadas criptográficamente, mostradas una sola vez al usuario, nunca almacenadas.
- SQL Server y MySQL corren en Docker, aislados; SQL Server solo accesible en
localhost. MySQL se expone controladamente (verservidor.md) porque los estudiantes necesitan conectarse directo a sus bases. - Cada usuario MySQL tiene permisos únicamente sobre su propia base (verificado: un usuario no puede ver ni tocar la base de otro).
- Rate limiting por usuario/IP en endpoints sensibles.
- Todos los secretos (JWT key, connection strings, OAuth secrets) viven fuera del repositorio, como variables de entorno en el servidor.