Sistema de gestión hospitalaria para el Hospital de Clínicas. Interfaz Web 2.0 retro estilo Old Facebook + Windows Classic.
- Funcionalidades
- Stack tecnológico
- Arquitectura
- Estructura del proyecto
- Base de datos
- Roles y permisos
- Instalación
- Desarrollo
- API de rutas
- Tema visual
- Acerca de
- Roadmap
- Hero con imagen del hospital y overlay oscuro.
- Secciones: Noticias, Servicios del sistema, Acerca de (Elyra, Lain, equipo, herramientas), Contacto.
- Navbar con enlaces de navegación interna y acceso al login.
- Carga y clasificación de documentos informativos por categorías.
- Acceso público mediante código QR por paciente.
- Panel de administración con búsqueda por cédula, filtros y paginación.
- Vista pública de documentos asociados al paciente.
- Creación de encuestas con preguntas de opción múltiple, escala (1–5) y texto libre.
- Respuesta anónima o vinculada a paciente mediante token QR.
- Visualización de resultados con gráficos estadísticos (Chart.js):
- Barras horizontales para opción múltiple.
- Doughnut + promedio para escala.
- Lista de respuestas para texto libre.
- Registro de traslados (origen, destino, paciente, conductor, vehículo).
- Seguimiento de estados: pendiente → en curso → completado / cancelado.
- Historial de traslados con filtros.
- Gestión de conductores y rutas nacionales.
- Autogestión de email, teléfono y contraseña.
- Foto de perfil con validación de tipo, tamaño y contenido (imagen real).
- Cédula de identidad (editable una sola vez).
- Dashboard con acceso diferenciado por rol.
- Vistas para gestión de documentos, encuestas, traslados, conductores y rutas.
| Capa | Tecnología |
|---|---|
| Lenguaje | PHP 8.1+ |
| Base de datos | MySQL / MariaDB |
| Frontend | HTML5, CSS3, JavaScript (ES6+) |
| CSS framework | Bootstrap 5 |
| Gráficos | Chart.js 4 |
| Iconos | Bootstrap Icons |
| Arquitectura | Hexagonal (Puertos y Adaptadores) + DDD |
El proyecto sigue una arquitectura hexagonal (puertos y adaptadores) con principios de Domain-Driven Design.
┌─────────────────────────────────────────────────┐
│ Infrastructure │
│ ┌──────────────┐ ┌────────────────────────┐ │
│ │ Persistence │ │ Web (Controllers) │ │
│ │ (MySQL PDO) │ │ Views / Middleware │ │
│ └──────┬───────┘ └───────────┬────────────┘ │
│ │ │ │
├─────────┴──────────────────────┴─────────────────┤
│ Application │
│ (Puertos / Casos de uso) │
├──────────────────────┬───────────────────────────┤
│ Domain │
│ Entidades · Value Objects · Repositorios │
└──────────────────────────────────────────────────┘
Las vistas se renderizan con PHP plano (sin motor de templates) y están separadas de la lógica de dominio.
/
├── database/
│ ├── schema.sql → Esquema completo de la base de datos
│ └── seeds/seed.php → Datos de prueba iniciales
├── public/
│ ├── index.php → Punto de entrada (front controller)
│ ├── router.php → Router para el servidor embebido
│ ├── css/web20.css → Tema Web 2.0 retro (Old Facebook + Windows Classic)
│ └── js/
│ ├── elyra.js → Funciones generales
│ └── components/ui.js → Componentes reutilizables
├── src/
│ ├── Domain/
│ │ ├── Entity/ → Usuario, Paciente, Funcionario, Documento,
│ │ │ Encuesta, Pregunta, Respuesta, Traslado, etc.
│ │ ├── ValueObject/ → RolUsuario, TipoPregunta, etc.
│ │ └── Repository/ → Interfaces de repositorio
│ ├── Application/ → Casos de uso / servicios de aplicación
│ └── Infrastructure/
│ ├── Persistence/MySQL/ → Implementaciones PDO de repositorios
│ ├── Web/
│ │ ├── Controller/ → Controladores
│ │ ├── Middleware/ → CSRF, rate limiting
│ │ ├── Router.php → Enrutador simple
│ │ └── Routes/web.php → Definición de rutas
│ └── Service/ → SessionManager, RateLimiter, ErrorHandler
├── storage/
│ ├── logs/ → Logs de errores
│ └── rate-limit/ → Archivos de rate limiting
├── vendor/ → Dependencias (Composer)
├── views/
│ ├── layout/base.php → Layout principal
│ ├── auth/ → Login, registro
│ ├── dashboard/ → Panel principal
│ ├── perfil/ → Perfil de usuario
│ ├── documentos/ → Gestión de documentos
│ ├── encuestas/ → Encuestas y resultados
│ ├── traslados/ → Ambulancias
│ ├── conductores/ → Conductores
│ ├── rutas/ → Rutas
│ ├── publico/ → Vistas públicas (QR, encuestas)
│ └── errors/ → 404, 500
├── .env → Configuración local
├── .env.example → Template de configuración
└── composer.json
usuario— Tabla base (tipo: funcionario | paciente, nombre, apellido, email, documento_identidad, foto).funcionario— Administradores, superadmins y conductores (username, password_hash, rol, licencia, activo).paciente— Pacientes (token_acceso, codigo_qr_id, username opcional).documento— Documentos informativos (título, descripción, archivo, categoría, paciente asociado).categoria— Categorías de documentos con tipo (tipo_documento | tipo_formulario).encuesta— Encuestas de satisfacción (título, descripción, activa, creada_por).pregunta— Preguntas (tipo, texto, opciones JSON, orden).respuesta— Respuestas (sesion_token, valor_opcion, valor_texto, valor_numerico).traslado— Traslados en ambulancia (origen, destino, paciente, conductor, estado).conductor— Conductores registrados (nombre, licencia, activo).ruta— Rutas nacionales (origen, destino, distancia_km, duracion_estimada).
Para migrar una base existente sin la columna
foto:ALTER TABLE usuario ADD COLUMN foto LONGBLOB NULL AFTER documento_identidad;
| Rol | Acceso |
|---|---|
admin |
Gestión completa: documentos, encuestas, traslados, conductores, rutas. |
superadmin |
Acceso total, incluyendo administración de usuarios. |
conductor |
Visión limitada a traslados asignados y rutas. |
paciente |
Acceso público vía QR: ver documentos propios, responder encuestas. |
El middleware de autenticación redirige a /login si no hay sesión activa, excepto en rutas públicas (/publico/*, /login, /registro).
# 1. Clonar
git clone <repo-url>
cd elyra
# 2. Dependencias
composer install
# 3. Configurar entorno
cp .env.example .env
# Editar .env con credenciales de base de datos:
# DB_HOST=127.0.0.1
# DB_PORT=3306
# DB_DATABASE=elyra
# DB_USERNAME=elyra
# DB_PASSWORD=elyra_pass
# 4. Crear base de datos e importar schema
mysql -u elyra -p elyra < database/schema.sql
# 5. (Opcional) Poblar con datos de prueba
# Crea un admin (admin/admin) y datos de ejemplo
php database/seeds/seed.php
# 6. Iniciar servidor de desarrollo
php -S 127.0.0.1:8084 -t publicNota: usá
php8.5si tu sistema tiene múltiples versiones y la default no incluyepdo_mysql.
git checkout -b <nombre>-features
# Trabajar en commits pequeños y descriptivos
git commit -m "tipo: descripción breve"
git push origin <nombre>-features
# Al finalizar, abrir Pull Request contra mainphp8.5 -S 127.0.0.1:8084 -t public
# El servidor recarga automáticamente los cambios en PHP.Los errores se registran en storage/logs/YYYY-MM-DD.log. El nivel de detalle se controla con APP_DEBUG en .env.
| Método | Ruta | Controlador | Descripción |
|---|---|---|---|
| GET | / |
PublicController | Página de inicio (home público) |
| GET | /login |
AuthController | Formulario de inicio de sesión |
| POST | /login |
AuthController | Procesar login |
| GET | /registro |
AuthController | Formulario de registro |
| POST | /registro |
AuthController | Procesar registro |
| GET | /publico/doc |
PublicController | Ver documento vía QR |
| GET | /publico/archivo |
PublicController | Descargar archivo vía QR |
| GET | /publico/mis-documentos |
PublicController | Documentos del paciente (vía QR) |
| GET | /publico/encuesta |
PublicController | Mostrar encuesta |
| POST | /publico/encuesta |
PublicController | Responder encuesta |
| Método | Ruta | Controlador | Descripción |
|---|---|---|---|
| GET | /dashboard |
DashboardController | Panel principal según rol |
| GET | /logout |
AuthController | Cerrar sesión |
| GET | /perfil |
PerfilController | Ver perfil propio |
| POST | /perfil |
PerfilController | Actualizar perfil |
| GET | /documentos |
DocumentoController | Listado general |
| GET | /documentos/subir |
DocumentoController | Formulario de carga |
| POST | /documentos/subir |
DocumentoController | Procesar carga |
| GET | /documentos/editar |
DocumentoController | Formulario de edición |
| POST | /documentos/editar |
DocumentoController | Procesar edición |
| GET | /documentos/eliminar |
DocumentoController | Eliminar documento |
| GET | /documentos/ver |
DocumentoController | Ver detalle |
| GET | /documentos/archivo |
DocumentoController | Descargar archivo |
| GET | /documentos/generales |
DocumentoController | Documentos generales |
| GET | /documentos/paciente |
DocumentoController | Buscar por CI de paciente |
| GET | /encuestas |
EncuestaController | Listado de encuestas |
| GET | /encuestas/crear |
EncuestaController | Formulario de creación |
| POST | /encuestas/crear |
EncuestaController | Procesar creación |
| GET | /encuestas/resultados |
EncuestaController | Resultados con gráficos |
| GET | /traslados |
TrasladoController | Listado de traslados |
| GET | /traslados/nuevo |
TrasladoController | Formulario de nuevo traslado |
| POST | /traslados/nuevo |
TrasladoController | Procesar nuevo traslado |
| GET | /traslados/ver |
TrasladoController | Detalle del traslado |
| POST | /traslados/actualizar-estado |
TrasladoController | Cambiar estado |
| GET | /traslados/historial |
TrasladoController | Historial con filtros |
| GET | /conductores |
ConductorController | Listado de conductores |
| GET | /conductores/crear |
ConductorController | Formulario de creación |
| POST | /conductores/crear |
ConductorController | Procesar creación |
| GET | /rutas |
RutaController | Listado de rutas |
| GET | /rutas/crear |
RutaController | Formulario de creación |
| POST | /rutas/crear |
RutaController | Procesar creación |
La interfaz usa un estilo Web 2.0 retro mezcla de Old Facebook + Windows Classic. CSS unificado en public/css/web20.css:
- Paleta: Azul Facebook
#3B5998, fondos gris claro#E9EAED, tipografía Tahoma/Verdana. - Navbar público: barra azul (
#3B5998) con logo y navegación, padding 20px vertical. - Header interno:
.web20-header— barra azul oscuro estilo Windows titlebar, 20px padding. - Hero: Imagen de fondo del Hospital de Clínicas con overlay oscuro y título grande.
- Sidebar:
.web20-sidebar— 240px, azul con links blancos, estilo portal 2000s. - Secciones:
.sectioncon padding 70px vertical para espaciado generoso. - Paneles:
.panelcon cabezal azul degradado (.panel-heading), similar a Facebook wall boxes. - Botones:
.btncon gradiente 3D,.btn-primaryazul Facebook. - Tablas:
.table thead thfondo azul, texto blanco — estilo Windows ListView. - Modales:
.modal-boxcon borde azul oscuro, como ventanas de diálogo clásicas. - Iconos: Bootstrap Icons y FamFamFam Silk icons (16×16) para acciones.
- Login: Card centrada sobre fondo del hospital, 480px de ancho.
- Modo oscuro: Toggle en navbar con clase
dark-modeen<body>.
| Sprint | Estado | Descripción |
|---|---|---|
| S0 | ✅ Completo | Fundación & Seguridad: entities, VOs, auth, CSRF, rate limit, session, CSP, protocolos |
| S1 | 🔄 En curso | Capa Aplicación, Repos y Servicios faltantes. Application Layer vacía, faltan TrasladoRepo, ConductorRepo, QRGeneratorService, FileStorageService. Stubs: ConductorController y RutaController. |
| S2 | ⬜ Pendiente | Gestión de Usuarios: CRUD funcionarios, baja lógica. Refinar dashboard paciente y perfil. |
| S3 | ⬜ Pendiente | Reportes & Gráficos: Chart.js avanzado, export CSV/PDF, filtros fecha. |
| S4 | ⬜ Pendiente | UX Avanzado: calendario traslados, mapa Leaflet, búsqueda global, drag & drop. |
| S5 | ⬜ Pendiente | PWA & Mobile: manifest, service worker, responsive final. |
| S6 | ⬜ Pendiente | Polish & Accesibilidad: animaciones, WCAG AA, lazy loading. |
| S7 | ⬜ Pendiente | Testing, Seguridad Producción & Despliegue: HTTPS, bloqueo cuentas, auditoría, fail2ban, Docker. |
Ver docs/planificacion-sprints.md para detalle completo.
Elyra es desarrollado por Lain, colectivo de estudiantes del Instituto Tecnologico De Paysandu..
Equipo: Alan, Kevin, Tom.
PHP 8.1+, MySQL, JavaScript (ES6+), Bootstrap 5, HTML5/CSS3, Apache/Nginx, Git/GitHub, Chart.js, Leaflet.
CC BY-NC 4.0 — Creative Commons Atribución-NoComercial 4.0 Internacional. Podés usar, modificar y compartir el código siempre que no sea con fines comerciales y se dé crédito al equipo original.
Ver LICENSE para el texto completo.