Plan de desarrollo
This commit is contained in:
@@ -9,6 +9,7 @@
|
|||||||
* **Google Calendar API:** Gestión e integración de citas de la agenda médica.
|
* **Google Calendar API:** Gestión e integración de citas de la agenda médica.
|
||||||
* **Chatwoot:** Mensajería (redirección y notificaciones básicas).
|
* **Chatwoot:** Mensajería (redirección y notificaciones básicas).
|
||||||
* **Seguridad:** Autenticación por Identity con roles (`Administrador`, `Médico`, `Secretaria`, `Recepcionista`, etc.) y autorización mediante políticas personalizadas.
|
* **Seguridad:** Autenticación por Identity con roles (`Administrador`, `Médico`, `Secretaria`, `Recepcionista`, etc.) y autorización mediante políticas personalizadas.
|
||||||
|
* **Plan de desarrollo:** Consultar siempre las fases y tareas del archivo `plan_desarrollo_sistema_medico.md`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -147,3 +148,4 @@ TuProyecto/
|
|||||||
│ └── Shared/
|
│ └── Shared/
|
||||||
├── Helpers/
|
├── Helpers/
|
||||||
└── Migrations/
|
└── Migrations/
|
||||||
|
```
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ using System.Reflection;
|
|||||||
[assembly: System.Reflection.AssemblyCompanyAttribute("vita-asistente")]
|
[assembly: System.Reflection.AssemblyCompanyAttribute("vita-asistente")]
|
||||||
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
||||||
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+3cfb4bb6f24411cd3e1e84555d8dcd442cc0b560")]
|
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+3b7e629f7516b043e50080d4fda3dec4625b1db8")]
|
||||||
[assembly: System.Reflection.AssemblyProductAttribute("vita-asistente")]
|
[assembly: System.Reflection.AssemblyProductAttribute("vita-asistente")]
|
||||||
[assembly: System.Reflection.AssemblyTitleAttribute("vita-asistente")]
|
[assembly: System.Reflection.AssemblyTitleAttribute("vita-asistente")]
|
||||||
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
e8a48322cb1bbc106a04e3d14a80ea655d7523d601ce39e651b37642e6f08b88
|
68ac8d6c1716eb6f2e80ee2727addb3d6bf2d33e35f9f985b924becf3c1df660
|
||||||
|
|||||||
@@ -1,170 +0,0 @@
|
|||||||
|
|
||||||
<style>
|
|
||||||
.phase { border: 1px solid var(--border); border-radius: 12px; margin-bottom: 20px; overflow: hidden; }
|
|
||||||
.phase-header { display: flex; align-items: center; gap: 12px; padding: 14px 18px; cursor: pointer; user-select: none; }
|
|
||||||
.phase-header:hover { background: var(--surface-0); }
|
|
||||||
.phase-body { padding: 0 18px 16px; display: none; }
|
|
||||||
.phase-body.open { display: block; }
|
|
||||||
.badge { font-size: 11px; font-weight: 500; padding: 2px 8px; border-radius: 20px; }
|
|
||||||
.task { display: flex; align-items: flex-start; gap: 10px; padding: 9px 0; border-bottom: 1px solid var(--border); }
|
|
||||||
.task:last-child { border-bottom: none; }
|
|
||||||
.task-label { font-size: 14px; color: var(--text-primary); line-height: 1.4; }
|
|
||||||
.task-sub { font-size: 12px; color: var(--text-secondary); margin-top: 2px; }
|
|
||||||
.dot { width: 8px; height: 8px; border-radius: 50%; margin-top: 5px; flex-shrink: 0; }
|
|
||||||
.chevron { margin-left: auto; color: var(--text-muted); transition: transform .25s; font-size: 16px; }
|
|
||||||
.chevron.open { transform: rotate(180deg); }
|
|
||||||
.phase-title { font-size: 15px; font-weight: 500; color: var(--text-primary); }
|
|
||||||
.phase-desc { font-size: 12px; color: var(--text-secondary); }
|
|
||||||
.weeks { font-size: 12px; color: var(--text-muted); margin-left: auto; white-space: nowrap; }
|
|
||||||
.progress-bar { height: 4px; border-radius: 2px; margin: 6px 0 14px; }
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<div style="padding: 1rem 0">
|
|
||||||
|
|
||||||
<div style="display:flex;align-items:center;gap:10px;margin-bottom:20px">
|
|
||||||
<i class="ti ti-heart-rate-monitor" style="font-size:22px;color:var(--text-accent)" aria-hidden="true"></i>
|
|
||||||
<div>
|
|
||||||
<div style="font-size:17px;font-weight:500;color:var(--text-primary)">Plan de desarrollo — Sistema médico</div>
|
|
||||||
<div style="font-size:12px;color:var(--text-secondary)">ASP.NET Core + MySQL + Google Calendar + Chatwoot · 6 fases</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- FASE 1 -->
|
|
||||||
<div class="phase">
|
|
||||||
<div class="phase-header" onclick="toggle('f1')">
|
|
||||||
<span style="background:#E6F1FB;color:#0C447C" class="badge">Fase 1</span>
|
|
||||||
<div>
|
|
||||||
<div class="phase-title">Infraestructura base y autenticación</div>
|
|
||||||
<div class="phase-desc">Scaffolding del proyecto, modelos de datos, roles e Identity</div>
|
|
||||||
</div>
|
|
||||||
<span class="weeks">≈ 2 semanas</span>
|
|
||||||
<span class="chevron" id="chev-f1">⌄</span>
|
|
||||||
</div>
|
|
||||||
<div class="progress-bar" style="background:linear-gradient(to right,#378ADD 100%,var(--border) 0%);margin:0 18px 0"></div>
|
|
||||||
<div class="phase-body" id="f1">
|
|
||||||
<div class="task"><div class="dot" style="background:#378ADD"></div><div><div class="task-label">Crear solución ASP.NET Core 6+ con MVC</div><div class="task-sub">Configurar Program.cs, inyección de dependencias, Pomelo MySQL y Migrations base</div></div></div>
|
|
||||||
<div class="task"><div class="dot" style="background:#378ADD"></div><div><div class="task-label">Implementar <code>ApplicationUser</code> con ASP.NET Identity</div><div class="task-sub">Campos: Nombre, Apellido, Documento, Dirección, Teléfono, RolPrincipal</div></div></div>
|
|
||||||
<div class="task"><div class="dot" style="background:#378ADD"></div><div><div class="task-label">Definir roles y políticas de autorización</div><div class="task-sub">Administrador, Médico, Secretaria, Recepcionista — RoleSeeder.cs</div></div></div>
|
|
||||||
<div class="task"><div class="dot" style="background:#378ADD"></div><div><div class="task-label">Construir <code>AccountController</code> (login / logout / registro)</div><div class="task-sub">Views con Bootstrap, validación del lado cliente y servidor</div></div></div>
|
|
||||||
<div class="task"><div class="dot" style="background:#378ADD"></div><div><div class="task-label">Layout compartido y navbar condicional por rol</div><div class="task-sub">_Layout.cshtml con menú adaptado según claims del usuario autenticado</div></div></div>
|
|
||||||
<div class="task"><div class="dot" style="background:#378ADD"></div><div><div class="task-label">Migraciones iniciales y seeder de roles</div><div class="task-sub">Verificar creación de tablas Identity en MySQL y usuario administrador inicial</div></div></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- FASE 2 -->
|
|
||||||
<div class="phase">
|
|
||||||
<div class="phase-header" onclick="toggle('f2')">
|
|
||||||
<span style="background:#E1F5EE;color:#085041" class="badge">Fase 2</span>
|
|
||||||
<div>
|
|
||||||
<div class="phase-title">Gestión de usuarios y pacientes</div>
|
|
||||||
<div class="phase-desc">CRUD completo de personal médico y pacientes</div>
|
|
||||||
</div>
|
|
||||||
<span class="weeks">≈ 2–3 semanas</span>
|
|
||||||
<span class="chevron" id="chev-f2">⌄</span>
|
|
||||||
</div>
|
|
||||||
<div class="progress-bar" style="background:linear-gradient(to right,#1D9E75 100%,var(--border) 0%);margin:0 18px 0"></div>
|
|
||||||
<div class="phase-body" id="f2">
|
|
||||||
<div class="task"><div class="dot" style="background:#1D9E75"></div><div><div class="task-label">Módulo de usuarios (<code>UsuariosController</code>)</div><div class="task-sub">Listar, crear, editar, deshabilitar. Asignación de roles. Perfil de médico (Especialidad, Matrícula, Horario)</div></div></div>
|
|
||||||
<div class="task"><div class="dot" style="background:#1D9E75"></div><div><div class="task-label">Modelo y migración de <code>Paciente</code></div><div class="task-sub">Todos los campos del diseño: DNI único, ObraSocial, FechaRegistro, FK a UsuarioAlta</div></div></div>
|
|
||||||
<div class="task"><div class="dot" style="background:#1D9E75"></div><div><div class="task-label">CRUD de pacientes (<code>PacientesController</code>)</div><div class="task-sub">Alta, baja lógica, modificación, búsqueda por nombre / documento. ViewModels y validaciones</div></div></div>
|
|
||||||
<div class="task"><div class="dot" style="background:#1D9E75"></div><div><div class="task-label">Vista de perfil de paciente</div><div class="task-sub">Resumen de datos, historial de citas y acceso rápido a historia clínica</div></div></div>
|
|
||||||
<div class="task"><div class="dot" style="background:#1D9E75"></div><div><div class="task-label">Autorización por rol en vistas y acciones</div><div class="task-sub">[Authorize(Roles = "...")] en controladores; ocultar botones según claims</div></div></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- FASE 3 -->
|
|
||||||
<div class="phase">
|
|
||||||
<div class="phase-header" onclick="toggle('f3')">
|
|
||||||
<span style="background:#FAEEDA;color:#633806" class="badge">Fase 3</span>
|
|
||||||
<div>
|
|
||||||
<div class="phase-title">Gestión de citas y Google Calendar</div>
|
|
||||||
<div class="phase-desc">Agenda médica con sincronización bidireccional</div>
|
|
||||||
</div>
|
|
||||||
<span class="weeks">≈ 3 semanas</span>
|
|
||||||
<span class="chevron" id="chev-f3">⌄</span>
|
|
||||||
</div>
|
|
||||||
<div class="progress-bar" style="background:linear-gradient(to right,#BA7517 100%,var(--border) 0%);margin:0 18px 0"></div>
|
|
||||||
<div class="phase-body" id="f3">
|
|
||||||
<div class="task"><div class="dot" style="background:#BA7517"></div><div><div class="task-label">Modelo y migración de <code>Cita</code></div><div class="task-sub">FK a Paciente y Médico, estados (Programada / Confirmada / Cancelada / Atendida), GoogleCalendarEventId</div></div></div>
|
|
||||||
<div class="task"><div class="dot" style="background:#BA7517"></div><div><div class="task-label">CRUD de citas (<code>CitasController</code>)</div><div class="task-sub">Crear, editar, cancelar. Vista de agenda diaria/semanal (FullCalendar.js o similar)</div></div></div>
|
|
||||||
<div class="task"><div class="dot" style="background:#BA7517"></div><div><div class="task-label">Configurar OAuth2 con Google</div><div class="task-sub">Credenciales en Google Cloud Console, flujo de autorización, almacenamiento de tokens</div></div></div>
|
|
||||||
<div class="task"><div class="dot" style="background:#BA7517"></div><div><div class="task-label">Implementar <code>GoogleCalendarService</code></div><div class="task-sub">Crear, actualizar y eliminar eventos en Google Calendar. Mapeo de campos Cita ↔ CalendarEvent</div></div></div>
|
|
||||||
<div class="task"><div class="dot" style="background:#BA7517"></div><div><div class="task-label">Sincronización bidireccional</div><div class="task-sub">Webhook o polling para traer cambios externos. Reconciliación de estado por GoogleCalendarEventId</div></div></div>
|
|
||||||
<div class="task"><div class="dot" style="background:#BA7517"></div><div><div class="task-label">Notificaciones y recordatorios de cita</div><div class="task-sub">Envío de invitación por email al paciente al confirmar la cita</div></div></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- FASE 4 -->
|
|
||||||
<div class="phase">
|
|
||||||
<div class="phase-header" onclick="toggle('f4')">
|
|
||||||
<span style="background:#FBEAF0;color:#72243E" class="badge">Fase 4</span>
|
|
||||||
<div>
|
|
||||||
<div class="phase-title">Historia clínica</div>
|
|
||||||
<div class="phase-desc">Registro de consultas, diagnósticos, tratamientos y recetas</div>
|
|
||||||
</div>
|
|
||||||
<span class="weeks">≈ 2–3 semanas</span>
|
|
||||||
<span class="chevron" id="chev-f4">⌄</span>
|
|
||||||
</div>
|
|
||||||
<div class="progress-bar" style="background:linear-gradient(to right,#D4537E 100%,var(--border) 0%);margin:0 18px 0"></div>
|
|
||||||
<div class="phase-body" id="f4">
|
|
||||||
<div class="task"><div class="dot" style="background:#D4537E"></div><div><div class="task-label">Modelo y migración de <code>HistoriaClinica</code></div><div class="task-sub">FK a Paciente y Médico, Diagnóstico (texto o CIE-10), TratamientoIndicado, ProximoControl</div></div></div>
|
|
||||||
<div class="task"><div class="dot" style="background:#D4537E"></div><div><div class="task-label">CRUD de historia clínica (<code>HistoriaClinicaController</code>)</div><div class="task-sub">Crear registro por consulta, edición restringida al médico autor, vista timeline por paciente</div></div></div>
|
|
||||||
<div class="task"><div class="dot" style="background:#D4537E"></div><div><div class="task-label">Vista de historial completo del paciente</div><div class="task-sub">Timeline cronológico de consultas, diagnósticos y evolución. Filtros por fecha y médico</div></div></div>
|
|
||||||
<div class="task"><div class="dot" style="background:#D4537E"></div><div><div class="task-label">Gestión de estados de paciente</div><div class="task-sub">Activo / En tratamiento / Derivado — visible en perfil y dashboard</div></div></div>
|
|
||||||
<div class="task"><div class="dot" style="background:#D4537E"></div><div><div class="task-label">Exportación básica a PDF</div><div class="task-sub">Resumen de historia clínica imprimible para el paciente o para derivación</div></div></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- FASE 5 -->
|
|
||||||
<div class="phase">
|
|
||||||
<div class="phase-header" onclick="toggle('f5')">
|
|
||||||
<span style="background:#EEEDFE;color:#3C3489" class="badge">Fase 5</span>
|
|
||||||
<div>
|
|
||||||
<div class="phase-title">Dashboard e integración Chatwoot</div>
|
|
||||||
<div class="phase-desc">Vista ejecutiva y mensajería embebida</div>
|
|
||||||
</div>
|
|
||||||
<span class="weeks">≈ 1–2 semanas</span>
|
|
||||||
<span class="chevron" id="chev-f5">⌄</span>
|
|
||||||
</div>
|
|
||||||
<div class="progress-bar" style="background:linear-gradient(to right,#7F77DD 100%,var(--border) 0%);margin:0 18px 0"></div>
|
|
||||||
<div class="phase-body" id="f5">
|
|
||||||
<div class="task"><div class="dot" style="background:#7F77DD"></div><div><div class="task-label">Dashboard por rol (<code>DashboardController</code>)</div><div class="task-sub">Citas del día para médicos; resumen de pacientes y agenda para secretaría; métricas globales para admin</div></div></div>
|
|
||||||
<div class="task"><div class="dot" style="background:#7F77DD"></div><div><div class="task-sub">Widgets: próximas citas, pacientes registrados hoy, citas pendientes de confirmación</div></div></div>
|
|
||||||
<div class="task"><div class="dot" style="background:#7F77DD"></div><div><div class="task-label">Implementar <code>ChatwootService</code></div><div class="task-sub">Integración con API REST de Chatwoot: contador de mensajes no leídos, redirect a conversación</div></div></div>
|
|
||||||
<div class="task"><div class="dot" style="background:#7F77DD"></div><div><div class="task-label">Ícono de mensajes en navbar con badge de no leídos</div><div class="task-sub">Polling periódico o SignalR para actualizar el contador sin recargar la página</div></div></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- FASE 6 -->
|
|
||||||
<div class="phase">
|
|
||||||
<div class="phase-header" onclick="toggle('f6')">
|
|
||||||
<span style="background:#F1EFE8;color:#2C2C2A" class="badge">Fase 6</span>
|
|
||||||
<div>
|
|
||||||
<div class="phase-title">Calidad, seguridad y despliegue</div>
|
|
||||||
<div class="phase-desc">Testing, hardening y puesta en producción</div>
|
|
||||||
</div>
|
|
||||||
<span class="weeks">≈ 2 semanas</span>
|
|
||||||
<span class="chevron" id="chev-f6">⌄</span>
|
|
||||||
</div>
|
|
||||||
<div class="progress-bar" style="background:linear-gradient(to right,#888780 100%,var(--border) 0%);margin:0 18px 0"></div>
|
|
||||||
<div class="phase-body" id="f6">
|
|
||||||
<div class="task"><div class="dot" style="background:#888780"></div><div><div class="task-label">Tests unitarios e integración</div><div class="task-sub">xUnit para servicios y controladores críticos (GoogleCalendarService, autenticación, citas)</div></div></div>
|
|
||||||
<div class="task"><div class="dot" style="background:#888780"></div><div><div class="task-label">Auditoría de seguridad</div><div class="task-sub">Validar anti-CSRF, XSS, inyección SQL, rate limiting en login, HTTPS forzado</div></div></div>
|
|
||||||
<div class="task"><div class="dot" style="background:#888780"></div><div><div class="task-label">Logging y manejo de errores</div><div class="task-sub">Serilog o NLog con niveles diferenciados; página de error amigable; alertas por excepción</div></div></div>
|
|
||||||
<div class="task"><div class="dot" style="background:#888780"></div><div><div class="task-label">Optimización de consultas EF Core</div><div class="task-sub">Revisión de N+1 queries, índices en MySQL (DocumentoIdentidad, MedicoId, FechaHoraInicio)</div></div></div>
|
|
||||||
<div class="task"><div class="dot" style="background:#888780"></div><div><div class="task-label">Configuración de entorno productivo</div><div class="task-sub">Secrets/appsettings por entorno, cadena de conexión segura, deploy en servidor Linux o Azure</div></div></div>
|
|
||||||
<div class="task"><div class="dot" style="background:#888780"></div><div><div class="task-label">Documentación técnica y manual de usuario</div><div class="task-sub">README actualizado, guía de roles y permisos, instrucciones de onboarding para el equipo médico</div></div></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
function toggle(id) {
|
|
||||||
const body = document.getElementById(id);
|
|
||||||
const chev = document.getElementById('chev-' + id);
|
|
||||||
const open = body.classList.toggle('open');
|
|
||||||
chev.classList.toggle('open', open);
|
|
||||||
}
|
|
||||||
toggle('f1');
|
|
||||||
</script>
|
|
||||||
@@ -0,0 +1,194 @@
|
|||||||
|
# Plan de Desarrollo — Sistema de Gestión Médica
|
||||||
|
|
||||||
|
> **Stack:** ASP.NET Core 6+ MVC · MySQL (Pomelo EF Core) · Google Calendar API · Chatwoot
|
||||||
|
> **Duración estimada total:** 12–15 semanas
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Resumen de fases
|
||||||
|
|
||||||
|
| Fase | Nombre | Duración estimada |
|
||||||
|
|------|--------|-------------------|
|
||||||
|
| 1 | Infraestructura base y autenticación | ≈ 2 semanas |
|
||||||
|
| 2 | Gestión de usuarios y pacientes | ≈ 2–3 semanas |
|
||||||
|
| 3 | Gestión de citas y Google Calendar | ≈ 3 semanas |
|
||||||
|
| 4 | Historia clínica | ≈ 2–3 semanas |
|
||||||
|
| 5 | Dashboard e integración Chatwoot | ≈ 1–2 semanas |
|
||||||
|
| 6 | Calidad, seguridad y despliegue | ≈ 2 semanas |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Fase 1 — Infraestructura base y autenticación
|
||||||
|
|
||||||
|
**Objetivo:** Scaffolding del proyecto, modelos de datos, roles e Identity.
|
||||||
|
|
||||||
|
- [ ] Crear solución ASP.NET Core 6+ con MVC
|
||||||
|
- Configurar `Program.cs`, inyección de dependencias, Pomelo MySQL y Migrations base
|
||||||
|
|
||||||
|
- [ ] Implementar `ApplicationUser` con ASP.NET Identity
|
||||||
|
- Campos: `Nombre`, `Apellido`, `Documento`, `Dirección`, `Teléfono`, `RolPrincipal`
|
||||||
|
|
||||||
|
- [ ] Definir roles y políticas de autorización
|
||||||
|
- Roles: `Administrador`, `Médico`, `Secretaria`, `Recepcionista`
|
||||||
|
- Implementar `RoleSeeder.cs`
|
||||||
|
|
||||||
|
- [ ] Construir `AccountController` (login / logout / registro)
|
||||||
|
- Views con Bootstrap, validación del lado cliente y servidor
|
||||||
|
|
||||||
|
- [ ] Layout compartido y navbar condicional por rol
|
||||||
|
- `_Layout.cshtml` con menú adaptado según claims del usuario autenticado
|
||||||
|
|
||||||
|
- [ ] Migraciones iniciales y seeder de roles
|
||||||
|
- Verificar creación de tablas Identity en MySQL y usuario administrador inicial
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Fase 2 — Gestión de usuarios y pacientes
|
||||||
|
|
||||||
|
**Objetivo:** CRUD completo de personal médico y pacientes.
|
||||||
|
|
||||||
|
- [ ] Módulo de usuarios (`UsuariosController`)
|
||||||
|
- Listar, crear, editar, deshabilitar
|
||||||
|
- Asignación de roles
|
||||||
|
- Perfil de médico: `Especialidad`, `MatriculaProfesional`, `HorarioAtencion`
|
||||||
|
|
||||||
|
- [ ] Modelo y migración de `Paciente`
|
||||||
|
- Campos: `Nombres`, `Apellidos`, `FechaNacimiento`, `Genero`, `DocumentoIdentidad` (único), `Direccion`, `Telefono`, `Email`, `ObraSocial`, `FechaRegistro`, FK a `UsuarioAlta`
|
||||||
|
|
||||||
|
- [ ] CRUD de pacientes (`PacientesController`)
|
||||||
|
- Alta, baja lógica, modificación
|
||||||
|
- Búsqueda por nombre / documento
|
||||||
|
- ViewModels y validaciones
|
||||||
|
|
||||||
|
- [ ] Vista de perfil de paciente
|
||||||
|
- Resumen de datos, historial de citas y acceso rápido a historia clínica
|
||||||
|
|
||||||
|
- [ ] Autorización por rol en vistas y acciones
|
||||||
|
- `[Authorize(Roles = "...")]` en controladores
|
||||||
|
- Ocultar botones según claims del usuario
|
||||||
|
|
||||||
|
> **Decisión pendiente:** Definir si `Médico` extiende `ApplicationUser` (relación 1:1) o es una entidad separada. Resolverlo antes de las migraciones de Fase 3, ya que afecta todas las FK de `Cita` e `HistoriaClinica`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Fase 3 — Gestión de citas y Google Calendar
|
||||||
|
|
||||||
|
**Objetivo:** Agenda médica con sincronización bidireccional.
|
||||||
|
|
||||||
|
> ⚠️ **Fase de mayor riesgo.** La integración OAuth2 y la sincronización bidireccional son los puntos más propensos a imprevistos. Reservar tiempo adicional.
|
||||||
|
|
||||||
|
- [ ] Modelo y migración de `Cita`
|
||||||
|
- FK a `Paciente` y `Médico`
|
||||||
|
- Estados: `Programada`, `Confirmada`, `Cancelada`, `Atendida`
|
||||||
|
- Campo `GoogleCalendarEventId` para sincronización
|
||||||
|
|
||||||
|
- [ ] CRUD de citas (`CitasController`)
|
||||||
|
- Crear, editar, cancelar
|
||||||
|
- Vista de agenda diaria/semanal (FullCalendar.js o similar)
|
||||||
|
|
||||||
|
- [ ] Configurar OAuth2 con Google
|
||||||
|
- Credenciales en Google Cloud Console
|
||||||
|
- Flujo de autorización y almacenamiento seguro de tokens de refresco
|
||||||
|
|
||||||
|
- [ ] Implementar `GoogleCalendarService`
|
||||||
|
- Crear, actualizar y eliminar eventos en Google Calendar
|
||||||
|
- Mapeo de campos `Cita` ↔ `CalendarEvent`
|
||||||
|
|
||||||
|
- [ ] Sincronización bidireccional
|
||||||
|
- Webhook o polling para traer cambios externos
|
||||||
|
- Reconciliación de estado por `GoogleCalendarEventId`
|
||||||
|
|
||||||
|
- [ ] Notificaciones y recordatorios de cita
|
||||||
|
- Envío de invitación por email al paciente al confirmar la cita
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Fase 4 — Historia clínica
|
||||||
|
|
||||||
|
**Objetivo:** Registro de consultas, diagnósticos, tratamientos y recetas.
|
||||||
|
|
||||||
|
- [ ] Modelo y migración de `HistoriaClinica`
|
||||||
|
- FK a `Paciente` y `Médico`
|
||||||
|
- Campos: `MotivoConsulta`, `Diagnostico` (texto o código CIE-10), `TratamientoIndicado`, `Observaciones`, `ProximoControl`, `EstadoPaciente`
|
||||||
|
|
||||||
|
- [ ] CRUD de historia clínica (`HistoriaClinicaController`)
|
||||||
|
- Crear registro por consulta
|
||||||
|
- Edición restringida al médico autor
|
||||||
|
- Vista timeline por paciente
|
||||||
|
|
||||||
|
- [ ] Vista de historial completo del paciente
|
||||||
|
- Timeline cronológico de consultas, diagnósticos y evolución
|
||||||
|
- Filtros por fecha y médico
|
||||||
|
|
||||||
|
- [ ] Gestión de estados de paciente
|
||||||
|
- `Activo` / `En tratamiento` / `Derivado` — visible en perfil y dashboard
|
||||||
|
|
||||||
|
- [ ] Exportación básica a PDF
|
||||||
|
- Resumen de historia clínica imprimible para el paciente o para derivación
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Fase 5 — Dashboard e integración Chatwoot
|
||||||
|
|
||||||
|
**Objetivo:** Vista ejecutiva por rol y mensajería embebida.
|
||||||
|
|
||||||
|
- [ ] Dashboard por rol (`DashboardController`)
|
||||||
|
- **Médico:** citas del día, próximos controles
|
||||||
|
- **Secretaría:** agenda general, pacientes registrados hoy, citas pendientes de confirmación
|
||||||
|
- **Administrador:** métricas globales del sistema
|
||||||
|
|
||||||
|
- [ ] Widgets del dashboard
|
||||||
|
- Próximas citas, pacientes registrados hoy, citas pendientes de confirmación
|
||||||
|
|
||||||
|
- [ ] Implementar `ChatwootService`
|
||||||
|
- Integración con API REST de Chatwoot
|
||||||
|
- Contador de mensajes no leídos y redirect a conversación
|
||||||
|
|
||||||
|
- [ ] Ícono de mensajes en navbar con badge de no leídos
|
||||||
|
- Polling periódico o SignalR para actualizar el contador sin recargar la página
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Fase 6 — Calidad, seguridad y despliegue
|
||||||
|
|
||||||
|
**Objetivo:** Testing, hardening y puesta en producción.
|
||||||
|
|
||||||
|
- [ ] Tests unitarios e integración
|
||||||
|
- xUnit para servicios y controladores críticos (`GoogleCalendarService`, autenticación, citas)
|
||||||
|
|
||||||
|
- [ ] Auditoría de seguridad
|
||||||
|
- Validar anti-CSRF, XSS, inyección SQL
|
||||||
|
- Rate limiting en login, HTTPS forzado
|
||||||
|
|
||||||
|
- [ ] Logging y manejo de errores
|
||||||
|
- Serilog o NLog con niveles diferenciados
|
||||||
|
- Página de error amigable; alertas por excepción crítica
|
||||||
|
|
||||||
|
- [ ] Optimización de consultas EF Core
|
||||||
|
- Revisión de N+1 queries
|
||||||
|
- Índices en MySQL: `DocumentoIdentidad`, `MedicoId`, `FechaHoraInicio`
|
||||||
|
|
||||||
|
- [ ] Configuración de entorno productivo
|
||||||
|
- `appsettings` por entorno (Development / Production)
|
||||||
|
- Cadena de conexión segura, secrets management
|
||||||
|
- Deploy en servidor Linux o Azure App Service
|
||||||
|
|
||||||
|
- [ ] Documentación técnica y manual de usuario
|
||||||
|
- README actualizado con instrucciones de setup
|
||||||
|
- Guía de roles y permisos
|
||||||
|
- Manual de onboarding para el equipo médico y administrativo
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Dependencias entre fases
|
||||||
|
|
||||||
|
```
|
||||||
|
Fase 1 → Fase 2 → Fase 3 → Fase 4
|
||||||
|
↘
|
||||||
|
Fase 5 (Dashboard consume datos de Fases 2–4)
|
||||||
|
↘
|
||||||
|
Fase 6 (transversal a todo el proyecto)
|
||||||
|
```
|
||||||
|
|
||||||
|
> La **Fase 1** es prerequisito duro para todo lo demás.
|
||||||
|
> La **Fase 6** puede iniciarse parcialmente en paralelo desde la Fase 3 en adelante (testing y logging).
|
||||||
Reference in New Issue
Block a user