up
This commit is contained in:
@@ -0,0 +1,574 @@
|
||||
================================================================================
|
||||
PLAN DE EVOLUCIÓN: BOT WHATSAPP → ERP MULTI-MÓDULO
|
||||
Proyecto: Panel de Laboratorio + WhatsApp Bot Manager
|
||||
Fecha: Abril 2026
|
||||
================================================================================
|
||||
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
1. ESTADO ACTUAL — QUÉ TENEMOS
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
MÓDULOS YA OPERATIVOS:
|
||||
✔ WhatsApp Bot – respuestas automáticas, menús, plantillas Meta
|
||||
✔ Conversaciones – bandeja de entrada, operadores asignados
|
||||
✔ Mensajes Programados – campañas por fecha/hora
|
||||
✔ Pacientes – ficha clínica, historial
|
||||
✔ Domicilios – agenda de servicios a domicilio con flujo de estados
|
||||
✔ Enfermeras/Personal – portal propio, agenda diaria
|
||||
✔ Órdenes Médicas – PDF adjunto, autorización
|
||||
✔ Formularios – builder drag-drop, firma digital, enlace público
|
||||
✔ Reportes – ingresos, rendimiento de enfermeros, pagos
|
||||
✔ Actividad/Auditoría – log de cambios por usuario
|
||||
✔ Usuarios & Roles – RBAC completo (roles + role_modules)
|
||||
✔ Configuración – tarifas, laboratorio, WhatsApp
|
||||
|
||||
ARQUITECTURA ACTUAL:
|
||||
• Todos los archivos PHP en la raíz del proyecto (lab_*.php, index.php…)
|
||||
• API separada en /api/ y /api/lab/
|
||||
• Clases en /classes/ y /services/
|
||||
• Base de datos: 34 tablas, una sola BD "usite_whatsapp_bot"
|
||||
• RBAC: tabla roles + role_modules + SYSTEM_MODULES en config.php
|
||||
• Sesiones PHP nativas (login en admin_users)
|
||||
|
||||
PROBLEMA PRINCIPAL PARA CRECER:
|
||||
• Sin sistema de enrutamiento → cada módulo es un archivo suelto en raíz
|
||||
• SYSTEM_MODULES hardcodeado en config.php (hay que editarlo cada vez)
|
||||
• No hay separación de carpetas por módulo (todo mezclado)
|
||||
• Navegación duplicada en cada .php del módulo lab
|
||||
• Sin un punto de entrada único (todo camino directo al .php)
|
||||
|
||||
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
2. VISIÓN TARGET — ERP MULTI-MÓDULO
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
CONCEPTO:
|
||||
Un sistema central con un panel unificado donde cada "módulo" es un paquete
|
||||
autocontenido. El core gestiona: autenticación, routing, menú lateral,
|
||||
RBAC, notificaciones y eventos. Los módulos se enchufan al core sin
|
||||
modificar archivos existentes.
|
||||
|
||||
MÓDULOS PLANIFICADOS (oleadas):
|
||||
|
||||
OLEADA 0 – Ya en producción (refactorizar para que usen la nueva estructura)
|
||||
- whatsapp_bot → Bot + Conversaciones + Plantillas
|
||||
- lab_domicilios → Agenda de domicilios
|
||||
- lab_pacientes → Pacientes y fichas
|
||||
- lab_formularios → Builder de formularios
|
||||
- lab_reportes → Reportes e indicadores
|
||||
- lab_ordenes → Órdenes médicas
|
||||
- lab_enfermeras → Gestión de personal clínico
|
||||
- sistema → Usuarios, Roles, Configuración
|
||||
|
||||
OLEADA 1 – Nuevos módulos solicitados
|
||||
- turnero → Sistema de turnos presenciales en recepción
|
||||
|
||||
OLEADA 2 – Módulos futuros probables
|
||||
- registro_exams → Registro directo de exámenes de laboratorio
|
||||
(sin domicilio: paciente llega a la sede)
|
||||
- facturacion → Facturación electrónica / DIAN (Colombia)
|
||||
- inventario → Reactivos, insumos, stock mínimo
|
||||
- citas → Agenda de citas con calendario visual
|
||||
- resultados → Entrega digital de resultados (portal paciente)
|
||||
- crm_pacientes → Campañas, seguimientos, cohortes
|
||||
|
||||
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
3. NUEVA ESTRUCTURA DE CARPETAS
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
/
|
||||
├── core/ ← Núcleo del ERP (NO tocar por módulos)
|
||||
│ ├── App.php ← Bootstrap, registro de módulos
|
||||
│ ├── Router.php ← Enrutador simple (mapea URL→módulo/acción)
|
||||
│ ├── Auth.php ← Login/logout/sesión (extraído de config.php)
|
||||
│ ├── Rbac.php ← hasModule(), requireModule(), permisos
|
||||
│ ├── ModuleRegistry.php ← Catálogo dinámico de módulos instalados
|
||||
│ ├── Layout.php ← Renderiza sidebar, navbar, footer
|
||||
│ └── Helpers.php ← Funciones globales (esc, jsonOk, etc.)
|
||||
│
|
||||
├── modules/ ← Un subdirectorio por módulo
|
||||
│ ├── whatsapp_bot/
|
||||
│ │ ├── module.php ← Descriptor: nombre, slug, icono, permisos
|
||||
│ │ ├── views/ ← Las páginas (ex lab_*.php migradas)
|
||||
│ │ └── api/ ← Endpoints REST propios del módulo
|
||||
│ │
|
||||
│ ├── domicilios/
|
||||
│ │ ├── module.php
|
||||
│ │ ├── views/
|
||||
│ │ └── api/
|
||||
│ │
|
||||
│ ├── turnero/ ← NUEVO ★ (Oleada 1)
|
||||
│ │ ├── module.php
|
||||
│ │ ├── views/
|
||||
│ │ │ ├── dashboard.php ← Pantalla administrador
|
||||
│ │ │ ├── display.php ← Pantalla TV/recepción (sin login)
|
||||
│ │ │ └── kiosko.php ← Pantalla táctil toma de turno
|
||||
│ │ └── api/
|
||||
│ │ ├── create_turno.php
|
||||
│ │ ├── llamar_turno.php
|
||||
│ │ ├── get_estado.php
|
||||
│ │ └── sse_turno.php ← Server-Sent Events para la pantalla TV
|
||||
│ │
|
||||
│ ├── registro_exams/ ← PENDIENTE — Oleada 2
|
||||
│ │ ├── module.php
|
||||
│ │ ├── views/
|
||||
│ │ │ ├── registrar.php
|
||||
│ │ │ ├── lista.php
|
||||
│ │ │ └── detalle.php
|
||||
│ │ └── api/
|
||||
│ │ ├── save_examen.php
|
||||
│ │ ├── get_examenes.php
|
||||
│ │ ├── cambiar_estado.php
|
||||
│ │ └── imprimir_etiqueta.php
|
||||
│ │
|
||||
│ └── sistema/
|
||||
│ ├── module.php
|
||||
│ ├── views/
|
||||
│ │ ├── usuarios.php ← lab_usuarios.php migrado
|
||||
│ │ └── configuracion.php
|
||||
│ └── api/
|
||||
│
|
||||
├── shared/ ← Componentes reutilizables entre módulos
|
||||
│ ├── components/
|
||||
│ │ ├── sidebar.php ← Menú lateral dinámico (según módulos del rol)
|
||||
│ │ ├── navbar.php
|
||||
│ │ ├── page_header.php
|
||||
│ │ └── modal_confirm.php
|
||||
│ └── js/
|
||||
│ ├── erp-core.js ← fetch wrapper, toasts, eventos globales
|
||||
│ └── erp-table.js ← Tablas con filtro, paginación, export
|
||||
│
|
||||
├── classes/ ← (ya existe, mantener)
|
||||
├── services/ ← (ya existe, mantener)
|
||||
├── api/ ← API global (ya existe, mantener para bot)
|
||||
├── config/
|
||||
│ └── config.php ← Simplificado: SOLO BD y constantes base
|
||||
│
|
||||
├── public/ ← (opcional futuro) assets compilados
|
||||
│ └── assets/
|
||||
│
|
||||
└── index.php ← Punto de entrada único → instancia App.php
|
||||
|
||||
|
||||
NOTA SOBRE MIGRACIÓN SIN ROMPER NADA:
|
||||
Los archivos lab_*.php actuales permanecen en raíz mientras se migran.
|
||||
Se crea un alias: cada modules/X/views/Y.php incluye el legacy si aún no
|
||||
se ha reescrito. No hay "big bang rewrite".
|
||||
|
||||
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
4. SISTEMA DE ROLES Y PERMISOS (RBAC EXPANDIDO)
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
MODELO ACTUAL:
|
||||
roles (id, name, slug, color, is_system)
|
||||
└── role_modules (role_id, module_slug) ← solo read/write implícito
|
||||
|
||||
MODELO PROPUESTO — RBAC con acciones:
|
||||
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ roles │
|
||||
│ id | name | slug | description | color | is_system │
|
||||
└──────────────────┬──────────────────────────────────────────┘
|
||||
│ 1:N
|
||||
┌──────────────────▼──────────────────────────────────────────┐
|
||||
│ role_permissions (reemplaza role_modules con más granularidad)
|
||||
│ id | role_id | module_slug | can_view | can_create │
|
||||
│ can_edit | can_delete | can_export | extra_json │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
|
||||
extra_json ejemplos:
|
||||
turnero → {"puede_llamar": true, "puede_reasignar": false}
|
||||
reportes → {"rango_max_dias": 90}
|
||||
whatsapp → {"puede_broadcast": true}
|
||||
|
||||
ROLES DEL SISTEMA A DEFINIR:
|
||||
|
||||
Slug Nombre Descripción
|
||||
─────────────────────────────────────────────────────────────────
|
||||
superadmin Super Admin Acceso total, configura el sistema
|
||||
admin Administrador Acceso total sin configuración técnica
|
||||
recepcionista Recepcionista Turnero + Pacientes (Oleada 1)
|
||||
bacteriologo Bacteriólogo Registro exámenes + Resultados (Oleada 2)
|
||||
enfermero Enfermero Portal domicilios (ya existe)
|
||||
supervisor Supervisor Reportes + sin acceso a config
|
||||
operador_bot Operador WhatsApp Solo bandeja de conversaciones
|
||||
readonly Solo lectura Ver dashboards sin editar
|
||||
|
||||
REGLA: is_system=1 en superadmin y admin → no se pueden borrar.
|
||||
Los demás roles son personalizables por el cliente.
|
||||
|
||||
FLUJO DE VERIFICACIÓN EN UNA VISTA:
|
||||
1. ¿Está logueado? → sino → login
|
||||
2. ¿El rol tiene module_slug? → sino → 403 sin módulo
|
||||
3. ¿La acción requiere can_edit? → verificar permiso específico
|
||||
4. ¿Hay restricción extra_json? → verificar campo relevante
|
||||
|
||||
HELPER PROPUESTO (core/Rbac.php):
|
||||
hasModule($slug) → bool (ya existe en helpers)
|
||||
canDo($slug, $action) → bool (nuevo, $action = view/create/edit/delete/export)
|
||||
requireAction($slug, $action) → lanza 403 si no tiene permiso
|
||||
|
||||
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
5. MÓDULO TURNERO — DISEÑO DETALLADO
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
CONCEPTO:
|
||||
Sistema de turnos para pacientes que llegan presencialmente a la sede.
|
||||
Tres pantallas distintas:
|
||||
A) Kiosko (tablet/touch en recepción) → el paciente toma su turno
|
||||
B) TV/Display (pantalla grande) → muestra turno actual + cola
|
||||
C) Dashboard admin → el operador llama turnos, gestiona
|
||||
|
||||
TABLAS BD NUEVAS:
|
||||
|
||||
turnero_servicios
|
||||
id, nombre, prefijo (ej. "A"), color, tiempo_estimado_min, activo
|
||||
|
||||
turnero_sesiones
|
||||
id, fecha, abierto_por INT FK admin_users, cerrado_por, inicio_at, fin_at
|
||||
(una sesión = un día de atención)
|
||||
|
||||
turnero_turnos
|
||||
id, sesion_id,
|
||||
numero INT, ← número correlativo de la sesión
|
||||
codigo VARCHAR(10), ← "A001", "B012"
|
||||
servicio_id,
|
||||
paciente_nombre VARCHAR(150),
|
||||
paciente_cel VARCHAR(20),
|
||||
estado ENUM(espera, llamado, en_atencion, atendido, ausente, cancelado),
|
||||
modulo_atencion INT, ← puesto/ventanilla que atiende
|
||||
llamado_at, inicio_at, fin_at, creado_at
|
||||
|
||||
turnero_modulos
|
||||
id, nombre (ej. "Ventanilla 1"), activo, usuario_actual INT FK admin_users
|
||||
|
||||
FLUJO:
|
||||
1. Recepcionista / kiosko crea turno → estado "espera"
|
||||
2. Operador en dashboard hace clic "Llamar siguiente"
|
||||
→ estado "llamado", pantalla TV muestra "A-001 → Ventanilla 2"
|
||||
→ (opcional) SMS/WhatsApp al paciente con su turno
|
||||
3. El paciente llega → operador pasa a "en_atención"
|
||||
4. Al terminar → "atendido"
|
||||
5. Si no aparece → "ausente" (puede regresar al final de la cola)
|
||||
|
||||
PANTALLA TV (display.php):
|
||||
• Sin login
|
||||
• Se actualiza por SSE (Server-Sent Events) cada vez que se llama un turno
|
||||
• Muestra: turno actual por cada ventanilla + próximos 5 en espera
|
||||
• Diseño visual grande, colores por servicio
|
||||
|
||||
INTEGRACIÓN CON WHATSAPP (OPCIONAL):
|
||||
Cuando se llama el turno → enviar mensaje al paciente si dejó celular
|
||||
Usar WhatsAppService ya existente.
|
||||
|
||||
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
6. MÓDULO REGISTRO DE EXÁMENES — DISEÑO DETALLADO [OLEADA 2 — pendiente]
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
CONCEPTO:
|
||||
Registrar exámenes de análisis clínico cuando el paciente llega a la sede
|
||||
(a diferencia de lab_domicilios que es a domicilio).
|
||||
Incluye: recepción de muestra, trazabilidad, estado de procesamiento,
|
||||
y eventualmente entrega de resultados.
|
||||
|
||||
TABLAS BD NUEVAS:
|
||||
|
||||
exam_tipos
|
||||
id, codigo (ej. "HEM", "GLU"), nombre, categoria, precio_base,
|
||||
requiere_ayunas TINYINT, instrucciones TEXT, activo
|
||||
|
||||
exam_ordenes (la "orden de trabajo" del laboratorio)
|
||||
id, paciente_id FK lab_pacientes,
|
||||
numero_orden VARCHAR(20) UNIQUE, ← ej. "ORD-2026-00123"
|
||||
origen ENUM(presencial, domicilio, whatsapp, referido),
|
||||
medico_remitente VARCHAR(150),
|
||||
entidad_pagadora VARCHAR(150),
|
||||
tipo_pago ENUM(particular, eps, convenio),
|
||||
total_cobrado DECIMAL(10,2),
|
||||
estado ENUM(pendiente, en_proceso, parcial, completado, entregado, anulado),
|
||||
observaciones TEXT,
|
||||
recibido_por INT FK admin_users,
|
||||
creado_at, actualizado_at
|
||||
|
||||
exam_items (los exámenes individuales dentro de una orden)
|
||||
id, orden_id FK exam_ordenes,
|
||||
tipo_id FK exam_tipos,
|
||||
estado ENUM(pendiente, muestra_tomada, en_analisis, resultado_listo, entregado),
|
||||
muestra_tipo VARCHAR(50), ← sangre, orina, hisopado...
|
||||
muestra_recibida_at,
|
||||
resultado TEXT,
|
||||
resultado_pdf VARCHAR(300),
|
||||
procesado_por INT FK admin_users,
|
||||
entregado_at
|
||||
|
||||
exam_etiquetas (para imprimir en los tubos)
|
||||
id, item_id FK exam_items,
|
||||
codigo_barras VARCHAR(50) UNIQUE,
|
||||
impreso_at, impreso_por INT FK admin_users
|
||||
|
||||
FLUJO:
|
||||
1. Recepcionista busca/crea paciente (reutiliza lab_pacientes)
|
||||
2. Crea orden → agrega exámenes de la lista exam_tipos
|
||||
3. Sistema genera número de orden y código de barras por tubo
|
||||
4. Se imprime etiqueta (ZPL o PDF)
|
||||
5. Bacteriólogo cambia estado → en_análisis → resultado_listo
|
||||
6. Administrador entrega resultados (descarga PDF / enlace portal)
|
||||
|
||||
RELACIÓN CON MÓDULOS EXISTENTES:
|
||||
• Paciente → usa lab_pacientes (ya existe)
|
||||
• Si viene de un domicilio → exam_ordenes.origen = 'domicilio',
|
||||
vincular con lab_domicilios (campo opcional domicilio_id)
|
||||
• Si tiene orden médica adjunta → vincular con lab_ordenes_medicas
|
||||
|
||||
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
7. BASE DE DATOS — PLAN DE MIGRACIONES
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
REGLA: todas las migraciones son ADITIVAS (ALTER ADD, CREATE TABLE).
|
||||
NUNCA DROP COLUMN ni RENAME en producción sin respaldo previo.
|
||||
|
||||
Migración 001 – RBAC expandido
|
||||
ALTER TABLE role_modules ADD COLUMN can_view TINYINT(1) DEFAULT 1;
|
||||
ALTER TABLE role_modules ADD COLUMN can_create TINYINT(1) DEFAULT 0;
|
||||
ALTER TABLE role_modules ADD COLUMN can_edit TINYINT(1) DEFAULT 0;
|
||||
ALTER TABLE role_modules ADD COLUMN can_delete TINYINT(1) DEFAULT 0;
|
||||
ALTER TABLE role_modules ADD COLUMN can_export TINYINT(1) DEFAULT 0;
|
||||
ALTER TABLE role_modules ADD COLUMN extra_json JSON NULL;
|
||||
RENAME TABLE role_modules TO role_permissions; ← (o alias)
|
||||
|
||||
Migración 002 – Nuevos roles
|
||||
INSERT INTO roles (name, slug, description, color, is_system) VALUES
|
||||
('Super Admin', 'superadmin', 'Acceso total al sistema', '#dc3545', 1),
|
||||
('Recepcionista', 'recepcionista', 'Turnero y recepción de muestras', '#198754', 0),
|
||||
('Bacteriólogo', 'bacteriologo', 'Análisis y resultados', '#0dcaf0', 0),
|
||||
('Supervisor', 'supervisor', 'Solo reportes y consultas', '#fd7e14', 0),
|
||||
('Operador Bot', 'operador_bot', 'Gestión de conversaciones', '#6f42c1', 0);
|
||||
|
||||
Migración 003 – Turnero [Oleada 1]
|
||||
CREATE TABLE turnero_servicios (...)
|
||||
CREATE TABLE turnero_sesiones (...)
|
||||
CREATE TABLE turnero_turnos (...)
|
||||
CREATE TABLE turnero_modulos (...)
|
||||
|
||||
Migración 004 – SYSTEM_MODULES dinámica (mover de config.php a BD) [Oleada 1]
|
||||
CREATE TABLE system_modules (
|
||||
slug VARCHAR(100) PK,
|
||||
name VARCHAR(150),
|
||||
icon VARCHAR(50), ← "fas fa-vials"
|
||||
category VARCHAR(50), ← "lab", "bot", "sistema", "clinico"
|
||||
route VARCHAR(200), ← URL base del módulo
|
||||
is_active TINYINT(1),
|
||||
sort_order INT,
|
||||
created_at TIMESTAMP
|
||||
)
|
||||
|
||||
Poblar con los módulos actuales + turnero.
|
||||
registro_exams se agrega en Migración 005 (Oleada 2).
|
||||
config.php mantiene el array como fallback hasta que la BD esté lista.
|
||||
|
||||
Migración 005 – Registro de exámenes [Oleada 2]
|
||||
CREATE TABLE exam_tipos (...)
|
||||
CREATE TABLE exam_ordenes (...)
|
||||
CREATE TABLE exam_items (...)
|
||||
CREATE TABLE exam_etiquetas(...)
|
||||
|
||||
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
8. ROUTER Y PUNTO DE ENTRADA
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
OPCIÓN RECOMENDADA (sin framework, compatible con estructura actual):
|
||||
|
||||
index.php → incluye core/App.php
|
||||
App.php → lee $_GET['m'] (módulo) y $_GET['v'] (vista)
|
||||
→ verifica sesión + permisos via Rbac.php
|
||||
→ incluye modules/{m}/views/{v}.php
|
||||
→ si no existe → 404 amigable
|
||||
|
||||
URLS LIMPIAS con .htaccess:
|
||||
/turnero/dashboard → ?m=turnero&v=dashboard
|
||||
/turnero/display → ?m=turnero&v=display (sin login)
|
||||
/lab/domicilios → ?m=domicilios&v=index
|
||||
/lab/pacientes → ?m=lab_pacientes&v=index
|
||||
|
||||
.htaccess ya existe en el proyecto → solo agregar RewriteRules.
|
||||
|
||||
COMPATIBILIDAD:
|
||||
Los lab_*.php en raíz siguen funcionando directamente.
|
||||
El router añade una capa adicional, no reemplaza lo existente.
|
||||
Migración gradual: mover módulos uno a uno al nuevo sistema.
|
||||
|
||||
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
9. LAYOUT Y NAVEGACIÓN UNIFICADA
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
PROBLEMA ACTUAL:
|
||||
Cada lab_*.php repite el mismo sidebar a mano (>50 líneas duplicadas).
|
||||
Si se agrega un módulo hay que editar todos los archivos.
|
||||
|
||||
SOLUCIÓN:
|
||||
shared/components/sidebar.php → se genera dinámicamente desde:
|
||||
1. La tabla system_modules (activos)
|
||||
2. Filtrado por los módulos que tiene el rol del usuario logueado
|
||||
3. Agrupados por "category" (Bot, Laboratorio, Clínico, Sistema)
|
||||
|
||||
Cada layout nueva vista incluye:
|
||||
<?php include APP_ROOT . '/shared/components/sidebar.php'; ?>
|
||||
|
||||
El sidebar detecta la URL activa y resalta el elemento correspondiente.
|
||||
|
||||
GRUPOS DEL MENÚ LATERAL:
|
||||
🤖 WhatsApp
|
||||
Conversaciones | Bot & Menús | Plantillas | Programados
|
||||
🏥 Laboratorio
|
||||
Dashboard | Domicilios | Pacientes | Enfermeras | Órdenes
|
||||
🧪 Clínico (Oleada 2)
|
||||
Registro Exámenes | Resultados
|
||||
🎟️ Turnero (Oleada 1)
|
||||
Dashboard | Configurar Servicios
|
||||
📊 Reportes
|
||||
Ingresos | Rendimiento | Exportar
|
||||
⚙️ Sistema
|
||||
Usuarios & Roles | Configuración | Actividad
|
||||
|
||||
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
10. PLAN DE IMPLEMENTACIÓN — FASES
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
── BASE DEL SISTEMA ─────────────────────────────────────────────────────────
|
||||
|
||||
FASE 0 – Preparación (1-2 días) [SIN impacto en producción] ✅ COMPLETADA
|
||||
✓ Crear carpetas: core/, modules/, shared/
|
||||
✓ Extraer Auth.php y Rbac.php desde config.php y _helpers.php
|
||||
✓ Crear shared/components/sidebar.php unificado
|
||||
✓ Migración 001: expandir role_permissions (columnas can_*)
|
||||
✓ Migración 002: insertar nuevos roles
|
||||
✓ Agregar nuevos slugs a SYSTEM_MODULES en config.php
|
||||
|
||||
FASE 1 – Core: Router y estructura modular (1 semana) ✅ COMPLETADA
|
||||
✓ Crear core/Router.php y core/App.php
|
||||
✓ Crear core/Layout.php, core/Helpers.php (core/Rbac.php ya existía de FASE 0)
|
||||
✓ Punto de entrada erp.php (coexiste con index.php legacy)
|
||||
✓ Activar .htaccess con URLs limpias (/modulo/vista → erp.php?m=&v=)
|
||||
✓ Mover módulos existentes a modules/ (module.php + views/index.php stubs para 11 módulos)
|
||||
|
||||
FASE 2 – SYSTEM_MODULES dinámica (2 días) ✅ COMPLETADA
|
||||
✓ Migración 004: tabla system_modules (con INSERT IGNORE, oleada, sort_order)
|
||||
✓ core/ModuleRegistry.php: lee BD → module.php → SYSTEM_MODULES (fallback en cascada)
|
||||
✓ Sidebar lee desde ModuleRegistry en lugar de config.php (dinámico por categoría)
|
||||
✓ Interfaz /erp.php?m=usuarios&v=modulos (toggle activo + sort_order)
|
||||
|
||||
── MÓDULOS NUEVOS ────────────────────────────────────────────────────────────
|
||||
|
||||
FASE 3 – Turnero MVP — Oleada 1 (3-5 días)
|
||||
□ Migración 003: tablas turnero_*
|
||||
□ modules/turnero/module.php + views/ + api/
|
||||
□ Pantalla kiosko (toma turno, sin login)
|
||||
□ Pantalla display TV (SSE, sin login)
|
||||
□ Dashboard admin (llamar, gestionar)
|
||||
□ Registrar slug turnero en system_modules
|
||||
|
||||
FASE 4 – Oleada 2 (Registro de Exámenes + futuros)
|
||||
□ Migración 005: tablas exam_*
|
||||
□ Catálogo de tipos de examen (CRUD admin)
|
||||
□ Flujo de recepción: buscar paciente → crear orden → agregar ítems
|
||||
□ Vista bacteriólogo: lista del día, cambiar estados
|
||||
□ Impresión de etiquetas (PDF A6)
|
||||
□ Conectar con lab_pacientes (reutilizar buscador existente)
|
||||
□ Facturación, Inventario, CRM, Portal Paciente…
|
||||
□ API pública con tokens (para integraciones)
|
||||
□ App móvil (portal enfermero actual → Progressive Web App)
|
||||
|
||||
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
11. CONVENCIONES TÉCNICAS A SEGUIR
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
NOMENCLATURA:
|
||||
• Tablas BD: snake_case, prefijadas por módulo (turnero_, exam_, lab_)
|
||||
• Archivos PHP: snake_case (save_turno.php, get_examenes.php)
|
||||
• Clases PHP: PascalCase (TurneroService.php, ExamOrder.php)
|
||||
• Slugs: siempre lowercase con guiones (turnero, registro-exams)
|
||||
• API endpoints: REST-ish, verbos en el nombre (get_, save_, delete_)
|
||||
|
||||
SEGURIDAD:
|
||||
• Toda API: requireMethod() + verificar sesión + verificar permiso
|
||||
• Parámetros: siempre sanitizar y tipificar antes de usar en SQL
|
||||
• Queries: siempre PDO preparado (ya implementado en Database.php)
|
||||
• Pantallas sin login (kiosko, display): NUNCA exponer datos sensibles,
|
||||
solo número de turno y servicio.
|
||||
• Subida de archivos: misma lógica de /upload.php (validar MIME + ext)
|
||||
• CSRF: para formularios de mutación, incluir token en sesión
|
||||
|
||||
ESTILO DE CÓDIGO:
|
||||
• Frontend: Bootstrap 5 + Font Awesome 6 (ya en uso, mantener)
|
||||
• Sin jQuery nuevo; usar fetch() nativo (ya en uso)
|
||||
• Toasts de notificación: usar patrón ya existente en index.php
|
||||
• Responsive: mobile-first (portal enfermero se usa desde celular)
|
||||
|
||||
API RESPONSE FORMAT (ya establecido, mantener):
|
||||
Éxito: { "ok": true, "data": {...}, "message": "..." }
|
||||
Error: { "ok": false, "error": "...", "code": 4XX }
|
||||
|
||||
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
12. DECISIONES CLAVE A CONFIRMAR CON EL CLIENTE
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
1. ¿El turnero es para UNA sede o múltiples sedes?
|
||||
(Multi-sede requiere añadir sede_id a las tablas)
|
||||
|
||||
2. ¿Facturación electrónica (DIAN) es obligatorio desde el inicio
|
||||
o puede dejarse para Oleada 2?
|
||||
|
||||
3. ¿El portal de entrega de resultados es para los pacientes directamente
|
||||
(requiere login/token para pacientes) o solo descarga interna?
|
||||
|
||||
4. ¿Se quiere app móvil nativa o es suficiente con PWA/responsive?
|
||||
|
||||
5. ¿Los exámenes tienen que integrar con algún analizador automático
|
||||
(interfaz LIS) o el resultado se digita manual?
|
||||
|
||||
6. ¿El turno se puede tomar ANTES de llegar (turno virtual por WhatsApp)?
|
||||
Esto conecta el módulo Turnero con el Bot.
|
||||
|
||||
7. ¿El sistema será multi-tenant (varios laboratorios/clientes en el mismo
|
||||
servidor) o siempre una instalación por cliente?
|
||||
|
||||
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
13. RESUMEN EJECUTIVO
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
Lo que TENEMOS es una base sólida:
|
||||
✓ BD bien estructurada con 34 tablas
|
||||
✓ RBAC funcional (roles + módulos)
|
||||
✓ API consistente con helpers reutilizables
|
||||
✓ Autenticación robusta con bcrypt
|
||||
✓ Integración WhatsApp activa
|
||||
✓ Módulos de laboratorio maduros
|
||||
|
||||
Lo que HAY QUE CONSTRUIR para el ERP:
|
||||
→ Estructura de carpetas por módulo (core/ + modules/)
|
||||
→ Router centralizado y sidebar dinámico
|
||||
→ RBAC con granularidad de acciones (can_view/create/edit/delete/export)
|
||||
→ Módulo Turnero — Oleada 1 (3-5 días)
|
||||
→ SYSTEM_MODULES en BD (en lugar de hardcoded en config.php)
|
||||
→ Módulo Registro de Exámenes — Oleada 2 (5-7 días, pendiente)
|
||||
|
||||
Estrategia: EVOLUCIÓN INCREMENTAL, no reescritura.
|
||||
El sistema sigue funcionando en producción mientras se construyen
|
||||
los nuevos módulos en paralelo. Solo se migra lo viejo al nuevo
|
||||
sistema cuando el nuevo está validado y estable.
|
||||
|
||||
================================================================================
|
||||
Documento preparado por GitHub Copilot — Abril 2026
|
||||
Próxima revisión: tras confirmar decisiones de la sección 12
|
||||
================================================================================
|
||||
Reference in New Issue
Block a user