Files
vita_asistente/plan_desarrollo_medico.html
T

171 lines
14 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<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>