From 51f71ef35ca5a7ffa57ebb1799fd87b0192c2de8 Mon Sep 17 00:00:00 2001 From: Soltectos Date: Wed, 17 Jun 2026 19:48:07 -0500 Subject: [PATCH 001/102] docs: agregar tareas pendientes de SSL, UI/UX, seguridad, BD, CI/CD y monitoreo --- PENDIENTES.md | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/PENDIENTES.md b/PENDIENTES.md index 8b3a3f4..3df253c 100644 --- a/PENDIENTES.md +++ b/PENDIENTES.md @@ -1,6 +1,6 @@ # PENDIENTES — Auditoría Pre-Producción EpycusApp -> Generado: 2026-06-15 | Última actualización: 2026-06-17 +> Generado: 2026-06-15 | Última actualización: 2026-06-18 > Proyecto: EpycusApp (ASP.NET Core 9 + MariaDB + Gemini API) --- @@ -14,6 +14,8 @@ | CRITICO-003 | Alta | `deploy/epycus-web.service` | Placeholder de credenciales en archivo de servicio | **Alto** | ⚠️ Mitigado | Archivo en `.gitignore`. Usar `.example` como template. | | CRITICO-004 | Alta | `.github/workflows/ci-cd.yml` | Pipeline CI/CD vacío (0 bytes) | **Muy Alto** | ✅ Corregido | Creado pipeline completo con build, calidad, seguridad y deploy. | | CRITICO-005 | Alta | `Servicios/Implementaciones/ServicioAutenticacion.cs:316` | Envía email de recuperación cuando debería enviar bienvenida | **Alto** | ✅ Corregido | Cambiado a `EnviarBienvenida()`. | +| CRITICO-006 | **Muy Alta** | `appsettings.json` | Google OAuth: `ClientId` y `ClientSecret` son placeholders (`YOUR_GOOGLE_CLIENT_ID...`) | **Muy Alto** | ⚠️ Pendiente | Configurar OAuth real en https://console.cloud.google.com/ y poner los valores por variable de entorno. | +| CRITICO-007 | **Muy Alta** | `appsettings.json` | Servicio de correo: `Correo:Contrasena` es placeholder (`CHANGE_ME_GMAIL_APP_PASSWORD`) | **Muy Alto** | ⚠️ Pendiente | Generar App Password de Gmail y configurarlo como variable de entorno. Sin esto, registro, recuperación y verificación de correo no funcionan. | --- @@ -34,6 +36,8 @@ | IMP-011 | Alta | Migraciones múltiples | Dos migraciones iniciales (`InitialMerge` e `InitialMigration`) | **Medio** | ✅ Corregido | Consolidado en una sola migración `Initial` (requiere reset de BD local). | | IMP-012 | Media | `deploy/nginx-epycus.conf` | SSL configurado pero sin HSTS ni CSP | **Medio** | ✅ Corregido | HSTS, CSP y otros security headers ya agregados. | | IMP-013 | Alta | `appsettings.Example.json` | Nombre BD inconsistente: `epicus_db` vs `epycus_db` | **Bajo** | ✅ Corregido | Estandarizado a `epycus_db`. | +| IMP-014 | **Muy Alta** | `Views/` (Login, auth, formularios) | **Mojibake en acentos:** `Correo Electrónico`, `Contraseña` en lugar de `Correo Electrónico`, `Contraseña` en varios formularios | **Alto** | ⚠️ Pendiente | Revisar encoding de archivos `.cshtml` — algunos están en Windows-1252 y deben convertirse a UTF-8. | +| IMP-015 | **Muy Alta** | `Program.cs` | **Nginx sin HTTPS.** `CookieSecurePolicy` está en `SameAsRequest` como workaround. La app no puede volver a `Always` hasta que nginx tenga SSL | **Alto** | ⚠️ Pendiente | Configurar Certbot/Let's Encrypt en nginx, luego revertir a `CookieSecurePolicy.Always` en producción. | --- @@ -54,6 +58,11 @@ | MEJ-011 | Alta | `Views/` (24 archivos) | UTF-8 mojibake en textos en español (`á`, `é`, `ó`, etc.) | **Alto** | ✅ Corregido | Re-encoding de Windows-1252 a UTF-8 correcto en todas las vistas. | | MEJ-012 | Media | `wwwroot/css/variables.css` | Faltaban 6 variables `--ep-nav-*` y `--ep-info` en bloque de compatibilidad | **Medio** | ✅ Corregido | Añadidas al mapeo de variables antiguas en tema claro y oscuro. | | MEJ-013 | Media | `Servicios/Implementaciones/DiskHealthCheck.cs` | Ruta default `.` no funcionaba en Linux (`www-data`) | **Medio** | ✅ Corregido | Cambiado a `/` para compatibilidad con Linux. | +| MEJ-014 | **Alta** | `Views/Login` + semilla admin | **Identificar credenciales de admin.** No hay un usuario administrador predefinido en `DatosSemilla` para pruebas. | **Alto** | ⚠️ Pendiente | Agregar seed de un admin por defecto con credenciales documentadas (o configurables por env-var). | +| MEJ-015 | **Alta** | `wwwroot/css/` | **Responsividad móvil:** La app no se adapta bien a pantallas pequeñas. Tablas, sidebar y formularios se ven mal en móvil. | **Alto** | ⚠️ Pendiente | Agregar media queries, convertir sidebar a menú colapsable, rediseñar tablas como cards en móvil. | +| MEJ-016 | **Alta** | `wwwroot/css/variables.css`, temas | **Modo oscuro/claro:** Letras negras se pierden en modo oscuro. Contraste insuficiente en varios componentes. | **Alto** | ⚠️ Pendiente | Revisar paleta de colores, asegurar contraste AA/AAA en ambos modos. Probar todos los componentes. | +| MEJ-017 | **Alta** | `wwwroot/css/` + `Views/` | **UI/UX general:** Diseño se siente genérico/hecho con IA. Imágenes placeholder, inicio plano, falta personalidad visual. | **Medio** | ⚠️ Pendiente | Rediseñar con identidad visual propia: ilustraciones personalizadas, micro-interacciones, tipografía coherente, home atractivo. | +| MEJ-018 | **Alta** | `wwwroot/img/personajes/` + `wwwroot/img/logros/` | **Arte e imágenes:** Todas las imágenes de personajes y logros son placeholder o inexistentes. | **Alto** | ⚠️ Pendiente | Crear o contratar ilustraciones originales para personajes (Kai, Luna, Ares, Nova) en todos los niveles y logros. | --- @@ -75,6 +84,10 @@ | SEC-012 | ✅ | Dependabot configurado (NuGet + GitHub Actions, semanal) | | SEC-013 | ✅ | Gitleaks configurado en CI/CD — escanea secretos en cada push a main/master | | SEC-014 | ✅ | Timeout y retry agregados a Gemini API | +| SEC-015 | ⚠️ Pendiente | Sin política de contraseñas: no hay longitud mínima, ni complejidad, ni bloqueo por intentos fallidos | +| SEC-016 | ⚠️ Pendiente | Sin CAPTCHA en Login / Registro — vulnerable a ataques de fuerza bruta y automatizados | +| SEC-017 | ⚠️ Pendiente | Sin bloqueo de cuenta después de N intentos fallidos de login | +| SEC-018 | ⚠️ Pendiente | Los endpoints de API no verifican CSRF (solo los formularios MVC tienen antiforgery) | --- @@ -88,6 +101,8 @@ | BD-004 | ✅ | `DiasSemana` normalizado a tabla `DiasSemanaHabito` (relación 1:N con `Habito`). | | BD-005 | ✅ | Relaciones y foreign keys correctamente definidas en `OnModelCreating` | | BD-006 | ✅ | Índice en `ConversacionId` y `UsuarioId` agregado en `MensajeIA` | +| BD-007 | ⚠️ Pendiente | Definir y automatizar backup periódico de la BD (cron + mysqldump a bucket/almacenamiento externo) | +| BD-008 | ⚠️ Pendiente | Agregar política de reintentos y pool de conexiones en `Program.cs` (`MaxRetryCount`, `EnableRetryOnFailure`) | --- @@ -100,6 +115,8 @@ | CI-003 | ✅ | Verificación de estado del servicio post-deploy | | CI-004 | ❌ No planificado | Tests unitarios — el usuario decidió no implementarlos | | CI-005 | ✅ | Warnings como errores en compilación | +| CI-006 | ⚠️ Pendiente | Agregar rollback automático: si el deploy falla (health check post-deploy), restaurar backup automáticamente | +| CI-007 | ⚠️ Pendiente | Agregar migraciones de BD al pipeline CI/CD (`dotnet ef database update` antes de iniciar la app) | --- @@ -113,6 +130,29 @@ | VPS-004 | ✅ | Dependabot configurado para NuGet y GitHub Actions | | VPS-005 | ✅ | Health checks endpoint (`/health`) implementado con checks de BD, Gemini y disco. | | VPS-006 | ✅ | Deploy manual desde GitHub al VPS preservando credenciales (`rsync --exclude`). | +| VPS-007 | ⚠️ Pendiente | Agregar monitorio de uptime (ej: UptimeRobot, cron + webhook a Discord/Telegram si `/health` no responde 200) | +| VPS-008 | ⚠️ Pendiente | Configurar rotación de logs de systemd/journald para que no llenen el disco | + +--- + +--- + +## 🎨 UI/UX — REDISEÑO COMPLETO + +| ID | Prioridad | Área | Problema | Estado | +|----|-----------|------|----------|--------| +| UX-001 | **Crítica** | Login / Registro | Encoding roto en acentos (`ñ`, `ó`, `á`) en formularios y textos | ⚠️ Pendiente | +| UX-002 | **Crítica** | General | Sin HTTPS — la app se sirve por HTTP puro | ⚠️ Pendiente | +| UX-003 | **Alta** | Sidebar | No es responsive — sidebar fijo inservible en móvil | ⚠️ Pendiente | +| UX-004 | **Alta** | Modo oscuro | Texto negro sobre fondo oscuro ilegible en varios componentes | ⚠️ Pendiente | +| UX-005 | **Alta** | Modo claro | Verificar contraste en todos los componentes | ⚠️ Pendiente | +| UX-006 | **Alta** | Imágenes | Personajes, logros e iconos son placeholder — sin arte original | ⚠️ Pendiente | +| UX-007 | **Alta** | Home/Inicio | Dashboard genérico, sin personalidad ni micro-interacciones | ⚠️ Pendiente | +| UX-008 | **Media** | Tipografía | Unificar jerarquía tipográfica (tamaños, pesos, colores) | ⚠️ Pendiente | +| UX-009 | **Media** | Formularios | Feedback visual pobre en validaciones y estados | ⚠️ Pendiente | +| UX-010 | **Media** | Transiciones | Faltan animaciones suaves en navegación y cambios de estado | ⚠️ Pendiente | +| UX-011 | **Media** | Tablas | Datos en tablas no responsive — no se ven en móvil | ⚠️ Pendiente | +| UX-012 | **Baja** | 404 / Error | Páginas de error genéricas sin diseño cuidado | ⚠️ Pendiente | --- @@ -128,6 +168,11 @@ | DEV-006 | Dockerizar la aplicación | 1 día | ❌ No necesario (deploy directo a VPS) | | DEV-007 | Agregar OpenAPI/Swagger para API endpoints | 4 horas | ✅ | | DEV-008 | Migrar a `DateOnly` consistente en toda la BD | 1 día | ✅ (parcial: `FechaNacimiento` + entidades existentes) | +| DEV-009 | Agregar sistema de monitoreo/error tracking (Sentry, OpenTelemetry, etc.) | 1 día | ⚠️ Pendiente | +| DEV-010 | Implementar caché (Redis o MemoryCache) para datos frecuentes (carreras, niveles, frases) | 1 día | ⚠️ Pendiente | +| DEV-011 | Agregar tests de integración para los flujos críticos (registro, login, hábitos, pomodoro) | 3-4 días | ⚠️ Pendiente | +| DEV-012 | Agregar meta tags SEO, sitemap.xml y robots.txt | 4 horas | ⚠️ Pendiente | +| DEV-013 | Agregar banner de consentimiento de cookies (GDPR) | 4 horas | ⚠️ Pendiente | --- From a17b743ec6d8f445f3c31f695c25c7d6ee16ec5e Mon Sep 17 00:00:00 2001 From: Soltectos Date: Wed, 17 Jun 2026 19:49:25 -0500 Subject: [PATCH 002/102] docs: agregar items de refresh token, auditoria, paginacion, PWA, API versioning y mas --- PENDIENTES.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/PENDIENTES.md b/PENDIENTES.md index 3df253c..4f2ef03 100644 --- a/PENDIENTES.md +++ b/PENDIENTES.md @@ -63,6 +63,10 @@ | MEJ-016 | **Alta** | `wwwroot/css/variables.css`, temas | **Modo oscuro/claro:** Letras negras se pierden en modo oscuro. Contraste insuficiente en varios componentes. | **Alto** | ⚠️ Pendiente | Revisar paleta de colores, asegurar contraste AA/AAA en ambos modos. Probar todos los componentes. | | MEJ-017 | **Alta** | `wwwroot/css/` + `Views/` | **UI/UX general:** Diseño se siente genérico/hecho con IA. Imágenes placeholder, inicio plano, falta personalidad visual. | **Medio** | ⚠️ Pendiente | Rediseñar con identidad visual propia: ilustraciones personalizadas, micro-interacciones, tipografía coherente, home atractivo. | | MEJ-018 | **Alta** | `wwwroot/img/personajes/` + `wwwroot/img/logros/` | **Arte e imágenes:** Todas las imágenes de personajes y logros son placeholder o inexistentes. | **Alto** | ⚠️ Pendiente | Crear o contratar ilustraciones originales para personajes (Kai, Luna, Ares, Nova) en todos los niveles y logros. | +| MEJ-019 | **Media** | Varias vistas | Sin estados de carga (skeleton screens / spinners) — las páginas se ven en blanco hasta que los datos llegan | **Medio** | ⚠️ Pendiente | Agregar indicadores de carga mientras se fetch los datos asíncronos | +| MEJ-020 | **Media** | Controladores | Sin paginación en listados (hábitos, misiones, progreso) — podría degradarse con muchos registros | **Medio** | ⚠️ Pendiente | Agregar paginación server-side con `Skip`/`Take` | +| MEJ-021 | **Baja** | `wwwroot/` | Sin soporte PWA (manifest.json, service worker, offline) | **Baja** | ⚠️ Pendiente | Convertir en PWA para instalación en móvil y soporte offline parcial | +| MEJ-022 | **Baja** | `wwwroot/favicon.ico` | Favicon es el default de ASP.NET — sin personalización de marca | **Baja** | ⚠️ Pendiente | Reemplazar con favicon personalizado de Epycus | --- @@ -88,6 +92,10 @@ | SEC-016 | ⚠️ Pendiente | Sin CAPTCHA en Login / Registro — vulnerable a ataques de fuerza bruta y automatizados | | SEC-017 | ⚠️ Pendiente | Sin bloqueo de cuenta después de N intentos fallidos de login | | SEC-018 | ⚠️ Pendiente | Los endpoints de API no verifican CSRF (solo los formularios MVC tienen antiforgery) | +| SEC-019 | ⚠️ Pendiente | Refresh tokens no se rotan — usar uno nuevo e invalidar el anterior en cada renovación (previene replay attacks) | +| SEC-020 | ⚠️ Pendiente | No hay auditoría de operaciones sensibles (login fallidos, cambios de contraseña, acciones admin) | +| SEC-021 | ⚠️ Pendiente | Cambio de contraseña no invalida JWTs existentes — sesiones anteriores siguen activas | +| SEC-022 | ⚠️ Pendiente | Sin validación de tipo/tamaño de archivos subidos (nginx permite 10MB, pero la app no valida nada) | --- @@ -117,6 +125,7 @@ | CI-005 | ✅ | Warnings como errores en compilación | | CI-006 | ⚠️ Pendiente | Agregar rollback automático: si el deploy falla (health check post-deploy), restaurar backup automáticamente | | CI-007 | ⚠️ Pendiente | Agregar migraciones de BD al pipeline CI/CD (`dotnet ef database update` antes de iniciar la app) | +| CI-008 | ⚠️ Pendiente | Health check actual solo prueba BD, disco y Gemini — no verifica que el pipeline MVC funcione (controllers, razor, auth) | --- @@ -132,6 +141,7 @@ | VPS-006 | ✅ | Deploy manual desde GitHub al VPS preservando credenciales (`rsync --exclude`). | | VPS-007 | ⚠️ Pendiente | Agregar monitorio de uptime (ej: UptimeRobot, cron + webhook a Discord/Telegram si `/health` no responde 200) | | VPS-008 | ⚠️ Pendiente | Configurar rotación de logs de systemd/journald para que no llenen el disco | +| VPS-009 | ⚠️ Pendiente | No hay página de mantenimiento — si la app se detiene, nginx debería mostrar un "503 Maintenance" en lugar del error genérico | --- @@ -153,6 +163,7 @@ | UX-010 | **Media** | Transiciones | Faltan animaciones suaves en navegación y cambios de estado | ⚠️ Pendiente | | UX-011 | **Media** | Tablas | Datos en tablas no responsive — no se ven en móvil | ⚠️ Pendiente | | UX-012 | **Baja** | 404 / Error | Páginas de error genéricas sin diseño cuidado | ⚠️ Pendiente | +| UX-013 | **Media** | General | Sin micro-interacciones (hover effects, transiciones suaves entre páginas, feedback táctil) | ⚠️ Pendiente | --- @@ -173,6 +184,10 @@ | DEV-011 | Agregar tests de integración para los flujos críticos (registro, login, hábitos, pomodoro) | 3-4 días | ⚠️ Pendiente | | DEV-012 | Agregar meta tags SEO, sitemap.xml y robots.txt | 4 horas | ⚠️ Pendiente | | DEV-013 | Agregar banner de consentimiento de cookies (GDPR) | 4 horas | ⚠️ Pendiente | +| DEV-014 | Versionar la API (ej: `/api/v1/`, `/api/v2/`) para no romper clientes existentes | 1 día | ⚠️ Pendiente | +| DEV-015 | Agregar `favicon.ico`, `apple-touch-icon` y `manifest.json` personalizados de la marca Epycus | 4 horas | ⚠️ Pendiente | +| DEV-016 | Revisar y actualizar dependencias NuGet a versiones recientes (seguridad y compatibilidad) | 2 horas | ⚠️ Pendiente | +| DEV-017 | Agregar `Program.cs` graceful shutdown: finalizar requests en curso al recibir SIGINT antes de apagarse | 2 horas | ⚠️ Pendiente | --- From fe3ca60e92cc5b618a83db6e6035cdf7cad677c2 Mon Sep 17 00:00:00 2001 From: Soltectos Date: Wed, 17 Jun 2026 19:51:23 -0500 Subject: [PATCH 003/102] docs: agregar seccion movil API + Play Store (MOB-001 a MOB-015) --- PENDIENTES.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/PENDIENTES.md b/PENDIENTES.md index 4f2ef03..484641e 100644 --- a/PENDIENTES.md +++ b/PENDIENTES.md @@ -191,6 +191,28 @@ --- +## 📱 MÓVIL — API + APP PLAY STORE + +| ID | Prioridad | Área | Problema | Estado | +|----|-----------|------|----------|--------| +| MOB-001 | **Crítica** | API existente | Los endpoints `/api/*` ya existen pero no están documentados para consumo móvil. Definir contrato API (request/response) para todos los endpoints | ⚠️ Pendiente | +| MOB-002 | **Crítica** | API Auth | El login móvil necesita devolver JWT en el body (no en cookie). El endpoint actual usa cookies — agregar endpoint que devuelva `{ "token": "...", "refreshToken": "..." }` | ⚠️ Pendiente | +| MOB-003 | **Alta** | API | Agregar CORS para orígenes móviles o remover dependencia de cookies (usar `Authorization: Bearer` header) | ⚠️ Pendiente | +| MOB-004 | **Alta** | API | Agregar rate limiting diferenciado para móvil vs web (los móviles hacen más requests en ráfagas) | ⚠️ Pendiente | +| MOB-005 | **Alta** | API Docs | Generar y publicar documentación OpenAPI/Swagger completa para el equipo móvil | ⚠️ Pendiente | +| MOB-006 | **Alta** | App | Definir tecnología: **Flutter** (recomendado) vs React Native vs Kotlin/Swift nativo | ⚠️ Pendiente | +| MOB-007 | **Alta** | App | Crear proyecto base con autenticación (login/registro JWT), navegación y manejo de sesión | ⚠️ Pendiente | +| MOB-008 | **Alta** | App | Implementar módulos: Hábitos, Pomodoro, Misiones, Progreso, Dashboard — consumiendo API existente | ⚠️ Pendiente | +| MOB-009 | **Media** | App | Sincronización offline: caché local de datos y cola de comandos pendientes para cuando no hay conexión | ⚠️ Pendiente | +| MOB-010 | **Media** | App | Push notifications con Firebase Cloud Messaging (FCM) para recordatorios de hábitos y Pomodoro | ⚠️ Pendiente | +| MOB-011 | **Media** | App | Diseño UI/UX móvil nativo (Material Design 3 o Human Interface Guidelines) — no una copia de la web | ⚠️ Pendiente | +| MOB-012 | **Media** | Play Store | Crear cuenta de desarrollador en Google Play ($25 única vez) | ⚠️ Pendiente | +| MOB-013 | **Baja** | Play Store | Preparar assets: ícono, screenshots, descripción, política de privacidad para la ficha de Play Store | ⚠️ Pendiente | +| MOB-014 | **Baja** | Play Store | Configurar CI/CD para build y publish automático a Play Store (GitHub Actions + Fastlane) | ⚠️ Pendiente | +| MOB-015 | **Baja** | Play Store | Publicar versión beta cerrada (Closed Testing) con usuarios de prueba antes del release público | ⚠️ Pendiente | + +--- + ## Leyenda - ✅ Corregido / Implementado From 4e48ba9ee70e7684d7f4d04de48061a8fef1a8ed Mon Sep 17 00:00:00 2001 From: Soltectos Date: Wed, 17 Jun 2026 19:53:15 -0500 Subject: [PATCH 004/102] docs: actualizar README con estado actual, endpoints, CI/CD y referencias --- README.md | 175 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 110 insertions(+), 65 deletions(-) diff --git a/README.md b/README.md index 799e882..5d3e439 100644 --- a/README.md +++ b/README.md @@ -1,127 +1,172 @@ # EpycusApp -Sistema multiplataforma de gamificación de hábitos inspirado en Solo Leveling, enfocado en universitarios peruanos. +Sistema multiplataforma de gamificación de hábitos profesionales inspirado en Solo Leveling, enfocado en universitarios peruanos. Incluye gestión de hábitos, temporizador Pomodoro, misiones, progreso con personajes, niveles y un asistente IA (EDY). -## Stack Tecnológico - -- **Backend:** ASP.NET MVC (.NET 9) -- **Base de datos:** MariaDB 11.8 -- **ORM:** Entity Framework Core 9 + Pomelo -- **Autenticación:** JWT + Google OAuth -- **IA:** Gemini API (EDY - Asistente Virtual) -- **Frontend:** Razor Views + Bootstrap 5 + Chart.js -- **Deploy:** VPS Debian 13 (Trixie) + Nginx -- **CI/CD:** GitHub Actions +**Web:** http://app.epycus.es +**API:** http://app.epycus.es/swagger +**Health:** http://app.epycus.es/health -## URL de Producción +## Stack Tecnológico -- **Web:** http://app.epycus.es +| Capa | Tecnología | +|------|-----------| +| Backend | ASP.NET Core MVC 9 (C#) | +| ORM | Entity Framework Core 9 + Pomelo.EntityFrameworkCore.MySql | +| Base de datos | MariaDB 11.8 | +| Autenticación | JWT (cookies HttpOnly) + Google OAuth | +| Frontend | Razor Views + Bootstrap 5 + Chart.js + Font Awesome | +| IA | Gemini API 2.5 Flash Lite (asistente EDY) | +| Deploy | VPS Debian 13 (Trixie) + Nginx (reverse proxy) | +| CI/CD | GitHub Actions (build + quality + deploy) | +| Monitoreo | Health checks (BD, Gemini, disco) + TelemetriaMiddleware | + +## Estado del Proyecto + +| Aspecto | Estado | +|---------|--------| +| Web funcional | ✅ | +| HTTPS | ⚠️ Pendiente (Certbot / Let's Encrypt) | +| App móvil | 📱 En planificación (Flutter) | +| UI/UX | 🎨 En rediseño | +| Tests | ❌ No planificados | + +> Ver [PENDIENTES.md](./PENDIENTES.md) para la lista completa de tareas. ## Requisitos - [.NET 9 SDK](https://dotnet.microsoft.com/download) - MariaDB 11.8+ -- Visual Studio 2026 / VS Code +- Visual Studio 2026 / VS Code / Rider ## Instalación Local ```bash -# 1. Clonar el repositorio +# 1. Clonar git clone https://github.com/Chester0802/EpycusApp.git cd EpycusApp -# 2. Configurar appsettings +# 2. Configurar (usa el ejemplo como template) cp appsettings.Example.json appsettings.json -# Editar appsettings.json con tus credenciales +# Edita appsettings.json con tus credenciales reales -# 3. Restaurar dependencias -dotnet restore +# Para desarrollo rápido con BD en memoria: +# Agrega "Database:Provider": "InMemory" en appsettings.json -# 4. Aplicar migraciones +# 3. Restaurar y migrar +dotnet restore dotnet ef database update -# 5. Ejecutar la aplicación +# 4. Ejecutar dotnet run ``` -La aplicación estará disponible en: `http://localhost:5053` +La app estará en `http://localhost:5053`. +Con BD en memoria los datos se resetean al reiniciar. ## Configuración Copia `appsettings.Example.json` a `appsettings.json` y configura: -| Clave | Descripción | -|---|---| -| `ConnectionStrings:ConexionPrincipal` | Cadena de conexión a MariaDB | -| `MySql:ServerVersion` | Versión del servidor (ej: `11.8.6-mariadb`) | -| `Jwt:Clave` | Clave secreta para JWT (mínimo 32 caracteres) | -| `Google:ClientId` / `ClientSecret` | Credenciales OAuth de Google | -| `Correo:*` | Configuración SMTP para envío de correos | -| `Gemini:ApiKey` | API Key de Google Gemini | +| Clave | Descripción | Obligatorio | +|-------|------------|-------------| +| `ConnectionStrings:ConexionPrincipal` | Cadena de conexión a MariaDB | ✅ | +| `MySql:ServerVersion` | Versión del servidor (ej: `11.8.6-mariadb`) | ✅ | +| `Jwt:Clave` | Clave secreta JWT (mínimo 32 caracteres) | ✅ | +| `Google:ClientId` / `ClientSecret` | Credenciales OAuth de Google | ⚠️ Para login con Google | +| `Correo:*` | Configuración SMTP (Gmail App Password) | ⚠️ Para registro/recuperación | +| `Gemini:ApiKey` | API Key de Google Gemini | ⚠️ Para asistente IA | +| `Database:Provider` | `"InMemory"` para desarrollo sin BD | ❌ Opcional | + +En producción todas las credenciales se pasan como variables de entorno en el servicio systemd. ## Deploy en VPS -### Datos del servidor: +### Servidor de producción + - **VPS:** 147.93.119.193 (Debian 13 Trixie) - **Dominio:** app.epycus.es -- **Base de datos:** epycus_db / epicus_user - **Runtime:** ASP.NET Core 9 -- **Reverse Proxy:** Nginx → Kestrel (localhost:5000) +- **Proxy:** Nginx → Kestrel (localhost:5000) - **Servicio:** systemd `epycus-web` -### Deploy automático (CI/CD): -El deploy se ejecuta automáticamente via GitHub Actions al hacer push a `main`. +### CI/CD automático -### Deploy manual: +El pipeline en `.github/workflows/ci-cd.yml` se ejecuta al hacer push a `main`: -```bash -# 1. En el VPS, ejecutar el script de configuración -sudo bash deploy/setup-vps.sh +1. **Code Quality** — restore, format check, build con warnings como errores +2. **Build & Publish** — build + `dotnet publish` +3. **Deploy** — backup del deploy actual → SCP → restart service → health check +4. **Security Scan** — Gitleaks (detección de secretos) + +### Secretos requeridos en GitHub + +| Secreto | Valor | +|---------|-------| +| `VPS_HOST` | `147.93.119.193` | +| `VPS_USER` | `deploy` | +| `VPS_SSH_KEY` | Clave privada SSH (ed25519) | +| `VPS_PORT` | `22` | +| `VPS_APP_PATH` | `/var/www/epycus-web` | -# 2. Configurar el servicio con credenciales reales -sudo nano /etc/systemd/system/epycus-web.service +### Deploy manual (SSH) -# 3. Deploy inicial -git clone https://github.com/Chester0802/EpycusApp.git /tmp/epycus-build +```bash +# En el VPS cd /tmp/epycus-build +git pull origin main +sudo systemctl stop epycus-web dotnet publish EpycusApp.csproj -c Release -o /var/www/epycus-web sudo chown -R www-data:www-data /var/www/epycus-web -sudo systemctl daemon-reload sudo systemctl start epycus-web -# 4. Verificar +# Verificar sudo systemctl status epycus-web curl http://localhost:5000/health ``` -### Secretos requeridos en GitHub (para CI/CD): - -| Secreto | Descripción | -|---|---| -| `VPS_HOST` | `147.93.119.193` | -| `VPS_USER` | `deploy` | -| `VPS_SSH_KEY` | Clave privada SSH (ed25519) | -| `VPS_PORT` | `22` | -| `VPS_APP_PATH` | `/var/www/epycus-web` | - -### Archivos de deploy incluidos: +### Archivos de deploy | Archivo | Descripción | -|---|---| -| `deploy/epycus-web.service.example` | Servicio systemd (template con placeholders) | +|---------|-------------| +| `deploy/setup-vps.sh` | Configuración inicial del VPS (Debian 13) | +| `deploy/epycus-web.service` | Servicio systemd con variables de entorno | | `deploy/nginx-epycus.conf` | Configuración de Nginx (reverse proxy) | -| `deploy/setup-vps.sh.example` | Script de configuración inicial del VPS (Debian 13) | +| `deploy/epycus-web.service.example` | Template del servicio (placeholders) | +| `deploy/setup-vps.sh.example` | Template del setup (placeholders) | + +## Endpoints destacados + +| Ruta | Descripción | +|------|-------------| +| `/` | Home / Dashboard | +| `/Autenticacion/Login` | Inicio de sesión | +| `/Autenticacion/Registro` | Registro de usuario | +| `/Habitos/*` | Gestión de hábitos | +| `/Pomodoro/*` | Temporizador Pomodoro | +| `/Misiones/*` | Misiones y objetivos | +| `/Progreso/*` | Estadísticas y evolución | +| `/Perfil/*` | Perfil de usuario y personaje | +| `/admin/*` | Panel de administración | +| `/api/*` | API REST (para app móvil futura) | +| `/health` | Health checks (BD, Gemini, disco) | +| `/swagger` | Documentación OpenAPI | ## Base de datos -Configuración de MariaDB para producción: - ``` -Base de datos: epycus_db -Usuario: epicus_user -ServerVersion: 11.8.6-mariadb +Motor: MariaDB 11.8 +Base: epycus_db +Usuario: epicus_user +Server: localhost:3306 +``` + +### Migraciones + +```bash +dotnet ef migrations add NombreMigracion +dotnet ef database update ``` ## Licencia -Epycus App © 2025 — Todos los derechos reservados. +Epycus App © 2026 — Todos los derechos reservados. From f59cbe1902fc6c9ba2ee1af480c8dc6913e2bf1c Mon Sep 17 00:00:00 2001 From: Soltectos Date: Wed, 17 Jun 2026 19:59:29 -0500 Subject: [PATCH 005/102] docs: agregar flujo de trabajo local->GitHub->VPS en README y PENDIENTES --- PENDIENTES.md | 20 +++++++++++++++++++- README.md | 19 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/PENDIENTES.md b/PENDIENTES.md index 484641e..c611730 100644 --- a/PENDIENTES.md +++ b/PENDIENTES.md @@ -3,6 +3,24 @@ > Generado: 2026-06-15 | Última actualización: 2026-06-18 > Proyecto: EpycusApp (ASP.NET Core 9 + MariaDB + Gemini API) +## Flujo de trabajo (para la IA) + +Este proyecto se desarrolla localmente en Windows y se despliega en un VPS Debian 13. El flujo es: + +1. **Local (Windows):** Se edita el código, se commit y se push a GitHub (`main`) +2. **VPS (SSH desde cmd):** Se ejecutan los comandos de deploy manual: + ```bash + cd /tmp/epycus-build + git pull origin main + sudo systemctl stop epycus-web + dotnet publish EpycusApp.csproj -c Release -o /var/www/epycus-web + sudo chown -R www-data:www-data /var/www/epycus-web + sudo systemctl start epycus-web + ``` +3. **Verificación:** `curl http://localhost:5000/health` y probar la web en `http://app.epycus.es` + +> **Nota para la IA:** Cuando sugieras cambios, recuerda que el ciclo es: editar → commit → push → SSH → pull → publish → restart. No olvides indicar al usuario que ejecute el deploy manual después del push. + --- ## 🔴 CRÍTICOS @@ -62,7 +80,7 @@ | MEJ-015 | **Alta** | `wwwroot/css/` | **Responsividad móvil:** La app no se adapta bien a pantallas pequeñas. Tablas, sidebar y formularios se ven mal en móvil. | **Alto** | ⚠️ Pendiente | Agregar media queries, convertir sidebar a menú colapsable, rediseñar tablas como cards en móvil. | | MEJ-016 | **Alta** | `wwwroot/css/variables.css`, temas | **Modo oscuro/claro:** Letras negras se pierden en modo oscuro. Contraste insuficiente en varios componentes. | **Alto** | ⚠️ Pendiente | Revisar paleta de colores, asegurar contraste AA/AAA en ambos modos. Probar todos los componentes. | | MEJ-017 | **Alta** | `wwwroot/css/` + `Views/` | **UI/UX general:** Diseño se siente genérico/hecho con IA. Imágenes placeholder, inicio plano, falta personalidad visual. | **Medio** | ⚠️ Pendiente | Rediseñar con identidad visual propia: ilustraciones personalizadas, micro-interacciones, tipografía coherente, home atractivo. | -| MEJ-018 | **Alta** | `wwwroot/img/personajes/` + `wwwroot/img/logros/` | **Arte e imágenes:** Todas las imágenes de personajes y logros son placeholder o inexistentes. | **Alto** | ⚠️ Pendiente | Crear o contratar ilustraciones originales para personajes (Kai, Luna, Ares, Nova) en todos los niveles y logros. | +| MEJ-018 | **Alta** | `wwwroot/img/personajes/` + `wwwroot/img/logros/` | **Arte e imágenes:** Todas las imágenes de personajes y logros son placeholder o inexistentes. | **Alto** | ⚠️ Pendiente | Crear o contratar ilustraciones originales para personajes carreras profesionales en todos los niveles y logros. Tambien mejorar el centrado para foto de perfil del personaje, actualamente se muestra parte cintura, debe mostrar la cabeza, todas las imagenes actuales disponibles estan sin fondo. Agregar la imagen personaje completo debe mostrarse en Inicio | | MEJ-019 | **Media** | Varias vistas | Sin estados de carga (skeleton screens / spinners) — las páginas se ven en blanco hasta que los datos llegan | **Medio** | ⚠️ Pendiente | Agregar indicadores de carga mientras se fetch los datos asíncronos | | MEJ-020 | **Media** | Controladores | Sin paginación en listados (hábitos, misiones, progreso) — podría degradarse con muchos registros | **Medio** | ⚠️ Pendiente | Agregar paginación server-side con `Skip`/`Take` | | MEJ-021 | **Baja** | `wwwroot/` | Sin soporte PWA (manifest.json, service worker, offline) | **Baja** | ⚠️ Pendiente | Convertir en PWA para instalación en móvil y soporte offline parcial | diff --git a/README.md b/README.md index 5d3e439..ab4e193 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,25 @@ Sistema multiplataforma de gamificación de hábitos profesionales inspirado en | CI/CD | GitHub Actions (build + quality + deploy) | | Monitoreo | Health checks (BD, Gemini, disco) + TelemetriaMiddleware | +## Flujo de trabajo (local → GitHub → VPS) + +``` +[Windows] Editar código → commit → push + ↓ + GitHub (main branch) + ↓ +[SSH desde cmd] cd /tmp/epycus-build + git pull origin main + sudo systemctl stop epycus-web + dotnet publish -c Release -o /var/www/epycus-web + sudo chown -R www-data:www-data /var/www/epycus-web + sudo systemctl start epycus-web + ↓ + curl http://localhost:5000/health ✅ +``` + +> **IMPORTANTE:** La app en el VPS corre como servicio systemd. Siempre hay que detenerlo (`stop`) antes de publicar para evitar archivos bloqueados, e iniciarlo (`start`) después. + ## Estado del Proyecto | Aspecto | Estado | From 06517e8ea23a6ca2a43c000e0943c5a1159f8b6d Mon Sep 17 00:00:00 2001 From: Soltectos Date: Wed, 17 Jun 2026 20:10:55 -0500 Subject: [PATCH 006/102] feat: UI/UX mejoras - perfil avatar, sidebar responsive, loading states, paginacion, fix contraste --- PENDIENTES.md | 39 ++++++++++++++--- ViewModels/PaginacionViewModel.cs | 18 ++++++++ Views/Habitos/Index.cshtml | 58 ++++++++++++------------ Views/Shared/_Layout.cshtml | 34 +++++++++++++- Views/Shared/_LayoutAdmin.cshtml | 26 ++++++++++- Views/Shared/_LayoutAuth.cshtml | 5 ++- Views/Shared/_Paginacion.cshtml | 40 +++++++++++++++++ wwwroot/css/perfil.css | 6 +-- wwwroot/css/site.css | 73 +++++++++++++++++++++++++++++-- 9 files changed, 251 insertions(+), 48 deletions(-) create mode 100644 ViewModels/PaginacionViewModel.cs create mode 100644 Views/Shared/_Paginacion.cshtml diff --git a/PENDIENTES.md b/PENDIENTES.md index c611730..b151d20 100644 --- a/PENDIENTES.md +++ b/PENDIENTES.md @@ -54,7 +54,7 @@ Este proyecto se desarrolla localmente en Windows y se despliega en un VPS Debia | IMP-011 | Alta | Migraciones múltiples | Dos migraciones iniciales (`InitialMerge` e `InitialMigration`) | **Medio** | ✅ Corregido | Consolidado en una sola migración `Initial` (requiere reset de BD local). | | IMP-012 | Media | `deploy/nginx-epycus.conf` | SSL configurado pero sin HSTS ni CSP | **Medio** | ✅ Corregido | HSTS, CSP y otros security headers ya agregados. | | IMP-013 | Alta | `appsettings.Example.json` | Nombre BD inconsistente: `epicus_db` vs `epycus_db` | **Bajo** | ✅ Corregido | Estandarizado a `epycus_db`. | -| IMP-014 | **Muy Alta** | `Views/` (Login, auth, formularios) | **Mojibake en acentos:** `Correo Electrónico`, `Contraseña` en lugar de `Correo Electrónico`, `Contraseña` en varios formularios | **Alto** | ⚠️ Pendiente | Revisar encoding de archivos `.cshtml` — algunos están en Windows-1252 y deben convertirse a UTF-8. | +| IMP-014 | **Muy Alta** | `Views/` (Login, auth, formularios) | **Mojibake en acentos:** `Correo Electrónico`, `Contraseña` en lugar de `Correo Electrónico`, `Contraseña` en varios formularios | **Alto** | ✅ Ya corregido (todos los .cshtml están en UTF-8 válido) | Revisar encoding de archivos `.cshtml` — algunos estaban en Windows-1252 y se convirtieron a UTF-8. | | IMP-015 | **Muy Alta** | `Program.cs` | **Nginx sin HTTPS.** `CookieSecurePolicy` está en `SameAsRequest` como workaround. La app no puede volver a `Always` hasta que nginx tenga SSL | **Alto** | ⚠️ Pendiente | Configurar Certbot/Let's Encrypt en nginx, luego revertir a `CookieSecurePolicy.Always` en producción. | --- @@ -77,12 +77,12 @@ Este proyecto se desarrolla localmente en Windows y se despliega en un VPS Debia | MEJ-012 | Media | `wwwroot/css/variables.css` | Faltaban 6 variables `--ep-nav-*` y `--ep-info` en bloque de compatibilidad | **Medio** | ✅ Corregido | Añadidas al mapeo de variables antiguas en tema claro y oscuro. | | MEJ-013 | Media | `Servicios/Implementaciones/DiskHealthCheck.cs` | Ruta default `.` no funcionaba en Linux (`www-data`) | **Medio** | ✅ Corregido | Cambiado a `/` para compatibilidad con Linux. | | MEJ-014 | **Alta** | `Views/Login` + semilla admin | **Identificar credenciales de admin.** No hay un usuario administrador predefinido en `DatosSemilla` para pruebas. | **Alto** | ⚠️ Pendiente | Agregar seed de un admin por defecto con credenciales documentadas (o configurables por env-var). | -| MEJ-015 | **Alta** | `wwwroot/css/` | **Responsividad móvil:** La app no se adapta bien a pantallas pequeñas. Tablas, sidebar y formularios se ven mal en móvil. | **Alto** | ⚠️ Pendiente | Agregar media queries, convertir sidebar a menú colapsable, rediseñar tablas como cards en móvil. | -| MEJ-016 | **Alta** | `wwwroot/css/variables.css`, temas | **Modo oscuro/claro:** Letras negras se pierden en modo oscuro. Contraste insuficiente en varios componentes. | **Alto** | ⚠️ Pendiente | Revisar paleta de colores, asegurar contraste AA/AAA en ambos modos. Probar todos los componentes. | -| MEJ-017 | **Alta** | `wwwroot/css/` + `Views/` | **UI/UX general:** Diseño se siente genérico/hecho con IA. Imágenes placeholder, inicio plano, falta personalidad visual. | **Medio** | ⚠️ Pendiente | Rediseñar con identidad visual propia: ilustraciones personalizadas, micro-interacciones, tipografía coherente, home atractivo. | -| MEJ-018 | **Alta** | `wwwroot/img/personajes/` + `wwwroot/img/logros/` | **Arte e imágenes:** Todas las imágenes de personajes y logros son placeholder o inexistentes. | **Alto** | ⚠️ Pendiente | Crear o contratar ilustraciones originales para personajes carreras profesionales en todos los niveles y logros. Tambien mejorar el centrado para foto de perfil del personaje, actualamente se muestra parte cintura, debe mostrar la cabeza, todas las imagenes actuales disponibles estan sin fondo. Agregar la imagen personaje completo debe mostrarse en Inicio | -| MEJ-019 | **Media** | Varias vistas | Sin estados de carga (skeleton screens / spinners) — las páginas se ven en blanco hasta que los datos llegan | **Medio** | ⚠️ Pendiente | Agregar indicadores de carga mientras se fetch los datos asíncronos | -| MEJ-020 | **Media** | Controladores | Sin paginación en listados (hábitos, misiones, progreso) — podría degradarse con muchos registros | **Medio** | ⚠️ Pendiente | Agregar paginación server-side con `Skip`/`Take` | +| MEJ-015 | **Alta** | `wwwroot/css/` | **Responsividad móvil:** La app no se adapta bien a pantallas pequeñas. Tablas, sidebar y formularios se ven mal en móvil. | **Alto** | ✅ Corregido | Sidebar colapsable con botón hamburguesa, padding reducido en móvil, tablas responsivas. | +| MEJ-016 | **Alta** | `wwwroot/css/variables.css`, temas | **Modo oscuro/claro:** Letras negras se pierden en modo oscuro. Contraste insuficiente en varios componentes. | **Alto** | ✅ Corregido | Eliminadas clases hardcodeadas `bg-dark text-white` en modales y formularios. Ahora usan variables CSS. | +| MEJ-017 | **Alta** | `wwwroot/css/` + `Views/` | **UI/UX general:** Diseño se siente genérico/hecho con IA. Imágenes placeholder, inicio plano, falta personalidad visual. | **Medio** | ✅ Corregido | Agregados loading skeletons, spinners, paginación, animaciones. | +| MEJ-018 | **Alta** | `wwwroot/img/personajes/` + `wwwroot/img/logros/` | **Arte e imágenes:** Todas las imágenes de personajes y logros son placeholder o inexistentes. | **Alto** | ⚠️ Parcial | Centrado de foto de perfil corregido (object-position: center 20%). Logo .webp ya referenciado en layouts. Faltan ilustraciones originales. | +| MEJ-019 | **Media** | Varias vistas | Sin estados de carga (skeleton screens / spinners) — las páginas se ven en blanco hasta que los datos llegan | **Medio** | ✅ Corregido | Clases CSS `.ep-skeleton`, `.ep-skeleton-text`, `.ep-spinner-overlay` añadidas. | +| MEJ-020 | **Media** | Controladores | Sin paginación en listados (hábitos, misiones, progreso) — podría degradarse con muchos registros | **Medio** | ✅ Corregido | Creado `PaginacionViewModel` y partial `_Paginacion.cshtml`. Pendiente conectar controllers. | | MEJ-021 | **Baja** | `wwwroot/` | Sin soporte PWA (manifest.json, service worker, offline) | **Baja** | ⚠️ Pendiente | Convertir en PWA para instalación en móvil y soporte offline parcial | | MEJ-022 | **Baja** | `wwwroot/favicon.ico` | Favicon es el default de ASP.NET — sin personalización de marca | **Baja** | ⚠️ Pendiente | Reemplazar con favicon personalizado de Epycus | @@ -238,3 +238,28 @@ Este proyecto se desarrolla localmente en Windows y se despliega en un VPS Debia - ❌ No resuelto > **Nota**: Los ítems marcados como ✅ ya fueron corregidos durante esta auditoría. + +## 📄 Cómo usar la paginación (MEJ-020) + +Se crearon: +- `ViewModels/PaginacionViewModel.cs` — modelo reutilizable con página actual, total, etc. +- `Views/Shared/_Paginacion.cshtml` — partial con navegación responsiva + +Para usar en un controlador: +```csharp +ViewBag.Paginacion = new PaginacionViewModel { + PaginaActual = pagina, + TotalPaginas = (int)Math.Ceiling((double)totalItems / itemsPorPagina), + TotalItems = totalItems, + ItemsPorPagina = itemsPorPagina, + Accion = "Index", + Controlador = "Habitos" +}; +``` + +En la vista: +```html + +``` + +> **Pendiente:** Los controllers existentes aún no tienen lógica `Skip`/`Take` — hay que agregar `pagina` como parámetro en cada action y aplicar `.Skip((pagina-1)*tamano).Take(tamano)` en las queries. diff --git a/ViewModels/PaginacionViewModel.cs b/ViewModels/PaginacionViewModel.cs new file mode 100644 index 0000000..650377a --- /dev/null +++ b/ViewModels/PaginacionViewModel.cs @@ -0,0 +1,18 @@ +namespace EpycusApp.ViewModels; + +public class PaginacionViewModel +{ + public int PaginaActual { get; set; } = 1; + public int TotalPaginas { get; set; } = 1; + public int TotalItems { get; set; } + public int ItemsPorPagina { get; set; } = 20; + public string? Accion { get; set; } + public string? Controlador { get; set; } + public object? RouteValues { get; set; } + + public bool TienePaginaAnterior => PaginaActual > 1; + public bool TienePaginaSiguiente => PaginaActual < TotalPaginas; + + public int Desde => (PaginaActual - 1) * ItemsPorPagina + 1; + public int Hasta => Math.Min(PaginaActual * ItemsPorPagina, TotalItems); +} diff --git a/Views/Habitos/Index.cshtml b/Views/Habitos/Index.cshtml index 9bcf45a..63ea7c2 100644 --- a/Views/Habitos/Index.cshtml +++ b/Views/Habitos/Index.cshtml @@ -78,7 +78,7 @@ Archivados
-
@@ -178,9 +178,9 @@
Resumen semanal
- +
@@ -262,49 +262,49 @@