Plan de desarrollo

This commit is contained in:
2026-08-10 16:10:47 -03:00
parent 3b7e629f75
commit 5c0cce7c1f
5 changed files with 198 additions and 172 deletions
+2
View File
@@ -9,6 +9,7 @@
* **Google Calendar API:** Gestión e integración de citas de la agenda médica.
* **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.
* **Plan de desarrollo:** Consultar siempre las fases y tareas del archivo `plan_desarrollo_sistema_medico.md`.
---
@@ -147,3 +148,4 @@ TuProyecto/
│ └── Shared/
├── Helpers/
└── Migrations/
```
@@ -13,7 +13,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("vita-asistente")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[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.AssemblyTitleAttribute("vita-asistente")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
@@ -1 +1 @@
e8a48322cb1bbc106a04e3d14a80ea655d7523d601ce39e651b37642e6f08b88
68ac8d6c1716eb6f2e80ee2727addb3d6bf2d33e35f9f985b924becf3c1df660
-170
View File
@@ -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">&#8964;</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">≈ 23 semanas</span>
<span class="chevron" id="chev-f2">&#8964;</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">&#8964;</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">≈ 23 semanas</span>
<span class="chevron" id="chev-f4">&#8964;</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">≈ 12 semanas</span>
<span class="chevron" id="chev-f5">&#8964;</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">&#8964;</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>
+194
View File
@@ -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:** 1215 semanas
---
## Resumen de fases
| Fase | Nombre | Duración estimada |
|------|--------|-------------------|
| 1 | Infraestructura base y autenticación | ≈ 2 semanas |
| 2 | Gestión de usuarios y pacientes | ≈ 23 semanas |
| 3 | Gestión de citas y Google Calendar | ≈ 3 semanas |
| 4 | Historia clínica | ≈ 23 semanas |
| 5 | Dashboard e integración Chatwoot | ≈ 12 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 24)
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).