feat: implement core domain models, authentication service, and UI components for the attendance system

This commit is contained in:
2026-07-31 14:39:25 -04:00
commit f476f704eb
329 changed files with 12622 additions and 0 deletions
+201
View File
@@ -0,0 +1,201 @@
# INFORME DE AUDITORÍA
## Proyecto Desktop: Asistencia (Avalonia UI)
**Ruta:** `/home/juan/dev/asistencia-desktop/`
**Referencia (guía):** `/home/juan/dev/sam/Profesores/` (Módulo Profesores SAM)
---
## 1. RESUMEN EJECUTIVO
| Aspecto | Desktop App (Asistencia) | SAM Profesores (guía) |
|---------|------------------------|----------------------|
| **Framework** | Avalonia UI + .NET 10 | ASP.NET WebForms .NET 4.8.1 |
| **Base de datos** | SQLite local (aislada) | MariaDB remota (AWS EC2) |
| **Tipo de app** | Desktop (Windows/Linux/macOS) | Web |
| **Estado** | Prototipo inicial - solo 4 vistas | Completo - 11 páginas |
| **Conexión SAM** | No conecta | Sí, via SPs |
---
## 2. ESTRUCTURA DEL PROYECTO DESKTOP
```
asistencia-desktop/
├── Asistencia.slnx
├── Asistencia/
│ ├── Asistencia.csproj (.NET 10 + Avalonia 12.1.1 + SQLite + DI)
│ ├── Program.cs (entry point clásico Avalonia)
│ ├── App.axaml / App.axaml.cs (DI: DbContext, Repos, Services, ViewModels)
│ ├── ViewLocator.cs
│ ├── app.manifest
│ ├── Models/ (7 entidades)
│ │ ├── Profesor.cs
│ │ ├── Curso.cs
│ │ ├── CursoAbierto.cs
│ │ ├── DetalleContrato.cs
│ │ ├── AsistenciaProfesor.cs
│ │ ├── AsistenciaAlumno.cs
│ │ └── TipoAsistencia.cs
│ ├── Data/
│ │ ├── AppDbContext.cs (SQLite + SeedData)
│ │ └── Repositories/
│ │ ├── ProfesorRepository.cs
│ │ ├── CursoRepository.cs
│ │ └── AsistenciaRepository.cs
│ ├── Services/
│ │ ├── AuthService.cs (login, crear clave, cambiar clave, email)
│ │ └── AsistenciaService.cs (iniciar/finalizar sesión, asistencia alumnos)
│ ├── Helpers/
│ │ └── CryptoHelper.cs (AES key hardcodeada)
│ ├── ViewModels/
│ │ ├── MainWindowViewModel.cs (navegación: Login→Dashboard→Asistencia→Perfil)
│ │ ├── LoginViewModel.cs
│ │ ├── DashboardViewModel.cs
│ │ ├── AsistenciaViewModel.cs (incluye AlumnoAsistenciaViewModel)
│ │ └── PerfilViewModel.cs
│ └── Views/
│ ├── MainWindow.axaml
│ ├── LoginView.axaml
│ ├── DashboardView.axaml
│ ├── AsistenciaView.axaml
│ └── PerfilView.axaml
```
---
## 3. FUNCIONALIDAD IMPLEMENTADA VS. GUÍA (SAM PROFESORES)
| # | Funcionalidad | Desktop App | SAM Profesores | Estado |
|---|--------------|-------------|----------------|--------|
| 1 | **Login / Autenticación** | ✅ SQLite local | ✅ FormsAuth + MariaDB | **Completo** |
| 2 | **Crear clave primera vez** | ✅ Implementado | ✅ CrearClave.aspx | **Completo** |
| 3 | **Dashboard (lista cursos)** | ✅ Básico | ✅ Index.aspx | **Completo** |
| 4 | **Iniciar clase (marcación)** | ✅ SQLite local | ✅ MariaDB + IP validation | **⚠ Parcial** |
| 5 | **Tomar asistencia alumnos** | ✅ P/L/A radio buttons | ✅ P/L/A radio buttons | **Completo** |
| 6 | **Finalizar clase** | ✅ | ✅ | **Completo** |
| 7 | **Perfil (email, clave)** | ✅ | ✅ Profile.aspx | **Completo** |
| 8 | **Ver sesiones y pagos** | ❌ No implementado | ✅ Sesiones.aspx | **FALTANTE** |
| 9 | **Notas / Calificaciones** | ❌ No implementado | ✅ Notas.aspx (CA, MWT, MOT, FOT, FWT) | **FALTANTE** |
| 10 | **Reportes por curso** | ❌ No implementado | ✅ Reports.aspx | **FALTANTE** |
| 11 | **Reemplazo de profesor** | ❌ No implementado | ✅ Reemplazo.aspx | **FALTANTE** |
| 12 | **Contenido del curso (bitácora)** | ❌ No implementado | ✅ Contenido.aspx | **FALTANTE** |
| 13 | **Validación IP/sede** | ❌ No implementado | ✅ Attendance.aspx (IP whitelist) | **FALTANTE** |
| 14 | **Notificaciones email** | ❌ No implementado | ✅ Mails.cs (reemplazos, sedes) | **FALTANTE** |
| 15 | **Soporte múltiples schemas** (abierto/cerrado) | ❌ No implementado | ✅ Plan Central + Empresa | **FALTANTE** |
| 16 | **Olvido de clave** | ❌ No implementado | ✅ OlvidoClave.aspx | **FALTANTE** |
---
## 4. HALLAZGOS CRÍTICOS
### 4.1 Base de datos aislada (SQLite local)
La desktop app usa SQLite local con datos de prueba (seed data). **No se conecta a la base de datos real SAM (MariaDB)**. Esto significa que:
- Los profesores no pueden ver sus cursos reales
- Las marcaciones no quedan registradas en el sistema SAM
- Los datos de asistencia de alumnos no se sincronizan
- No hay integración con el módulo de pagos (RRHH)
**Solución:** Reemplazar SQLite por conexión directa a MariaDB usando las mismas stored procedures que usa el módulo SAM Profesores (sam.BuscarCursoProfesor, sam.IngresoAsistenciaProfesor, etc.)
### 4.2 Seguridad: Encriptación AES con clave hardcodeada
Ambos proyectos comparten la misma vulnerabilidad:
```
Clave AES: "S4M_Pru3b4_2024!"
IV: new byte[16] (ceros estáticos)
Modo: CBC
```
La clave está hardcodeada en el código fuente (`CryptoHelper.cs` y `Seguridad.cs`). Un atacante con acceso al binario o al código puede desencriptar todas las contraseñas de los profesores.
**Recomendación:** Usar hash con salt (bcrypt/argon2) en lugar de encriptación reversible, o al menos mover la clave a una variable de entorno/configuración segura.
### 4.3 Sin validación de IP/Sede
La app SAM actual valida que el profesor solo pueda iniciar clases desde las IPs de la red del instituto:
```csharp
string[] IPsPermitidas = { "200.68.55.74", "200.54.121.26", "181.212.110.122", "127.0.0.1", "::1" };
```
Y para sedes ONLINE/EMPRESAS omite esta validación. La desktop app **no tiene ninguna validación**, lo que permite iniciar clases desde cualquier lugar.
**Recomendación:** La carta que se generó previamente (sobre inicio solo desde sedes físicas) debería reflejarse aquí: validar que el equipo esté en la red de una sede física autorizada.
### 4.4 Sin soporte para schemas múltiples
SAM maneja dos orígenes de datos:
- **Plan Central** (schema `sige_sam_V3`) — cursos regulares
- **Empresa** (schema `sige_sam_empresa`) — cursos cerrados
La desktop app no diferencia entre ambos.
### 4.5 Sin ciclo de vida de sesión completo
En SAM, cuando se finaliza una clase se registra `HoraSalida` y se cambia `Estado = 'Finalizada'`. La desktop hace lo mismo localmente, pero no hay registro del período de pago (21→20), ni se calculan horas para RRHH.
### 4.6 Modelo AsistenciaProfesor tiene campo `Temporal` no usado
El modelo `AsistenciaProfesor` tiene un campo `Temporal` (bool, default false) que no se utiliza en ninguna parte del código. En SAM este campo se usa para identificar reemplazos (`temporal = 1`).
### 4.7 Sin View ni ViewModel para Sesiones, Notas, Reportes, Reemplazo, Contenido
Faltan **5 vistas completas** para igualar la funcionalidad del módulo SAM.
---
## 5. COMPARATIVA ARQUITECTÓNICA
### SAM Profesores (WebForms)
```
Web (aspx.cs) → Negocio (NProfesor, NCurso, Seguridad, Mails) → Datos (Conexion MariaDB, Profesor.cs, Curso.cs)
```
### Desktop App (Avalonia)
```
Views (axaml) → ViewModels → Services (AuthService, AsistenciaService) → Repositories → AppDbContext (SQLite)
```
Ambos usan una arquitectura en capas similar, pero el desktop reemplaza la capa de datos MariaDB por SQLite local.
---
## 6. PENDIENTE PARA COMPILAR MULTIPLATAFORMA
Antes de compilar para Windows, macOS y Linux (deb + Arch), se debe:
### 6.1 Funcional (para igualar la guía SAM)
1. Conectar a MariaDB real (replicar stored procedures)
2. Implementar validación de IP/Sede (inicio solo desde sedes físicas)
3. Agregar vistas: Sesiones (pagos), Notas, Reportes, Reemplazo, Contenido
4. Agregar notificaciones por email
5. Soportar schemas Plan Central y Empresa
### 6.2 Técnico
1. Corregir seguridad de contraseñas (bcrypt/argon2)
2. Mover configuración sensible a variables de entorno o archivo de configuración
3. Agregar `RuntimeIdentifiers` en `.csproj` para publicación multiplataforma
4. Probar compilación con:
- `dotnet publish -c Release -r win-x64 --self-contained`
- `dotnet publish -c Release -r linux-x64 --self-contained`
- `dotnet publish -c Release -r osx-x64 --self-contained`
5. Para empaquetado:
- **Windows**: NSIS o Inno Setup (o .exe directo)
- **Linux .deb**: `dotnet publish` + `dpkg-deb` para crear .deb
- **Linux Arch**: PKGBUILD para AUR/local
- **macOS**: .app bundle o .dmg
---
## 7. CONCLUSIÓN
La desktop app es un **prototipo funcional** con las 4 vistas básicas (login, dashboard, asistencia, perfil) pero que **actualmente opera en aislamiento** con SQLite local. No reemplaza al sistema SAM real porque:
1. No está conectada a la base de datos de producción
2. Le falta más de la mitad de la funcionalidad del módulo Profesores SAM
3. Carece de las validaciones de seguridad y sede que el sistema actual tiene
**Para producción:** Se requiere conectar a MariaDB (usando las mismas SPs), agregar las vistas faltantes, e implementar las validaciones de IP/sede antes de distribuir ejecutables a los profesores.