Klinico — App de Gestión Clínica Hospitalaria
Plataforma móvil para la digitalización del flujo de trabajo médico en los pases de planta hospitalarios.
Tabla de contenidos
- Descripción
- Funcionalidades
- Interfaz de usuario
- Arquitectura
- Estructura del proyecto
- Stack tecnológico
- Primeros pasos
- Roles de usuario
- Repositorio del backend
- Documentación técnica
- Contacto
- License
Descripción
Klinico es una aplicación móvil multiplataforma (Android / iOS) construida con Flutter que digitaliza el flujo de trabajo durante el pase de planta hospitalario. Cubre desde el ingreso del paciente hasta su alta, pasando por la gestión de episodios clínicos, la asignación de nuevos ingresos en cada servicio y la monitorización de KPIs de rendimiento por parte del jefe de servicio.
El sistema distingue dos perfiles de usuario con vistas y permisos diferenciados: médico y jefe de servicio.
Funcionalidades
Médico
- Inicio de sesión seguro con JWT almacenado de forma cifrada.
- Consulta de admisiones activas asignadas a sí mismo.
- Creación y edición de admisiones de pacientes.
- Gestión de episodios clínicos asociados a cada admisión.
- Escalas clínicas integradas: Barthel, Braden, CAM y CHADS₂.
- Alta del paciente.
- Búsqueda y consulta de admisiones activas en el servicio.
Jefe de servicio
- Dashboard de KPIs del servicio con gráficos interactivos.
- Visualización y asignación de nuevas admisiones a médicos del servicio.
- Tabla de carga de trabajo por médico.
- Búsqueda y consulta de admisiones activas en el servicio.
- Creación y edición de admisiones de pacientes.
- Gestión de episodios clínicos asociados a cada admisión.
- Escalas clínicas integradas: Barthel, Braden, CAM y CHADS₂.
- Alta del paciente.
Comunes
- Autenticación con token JWT (expiración y renovación automática).
- Cierre de sesión con limpieza del almacenamiento seguro.
- Redirección automática al login ante sesión caducada (interceptor 401).
- Tema visual personalizado coherente con identidad corporativa.
Interfaz de usuario
Login
- Tablet
- Móvil
Vista principal - Medico
- Tablet
- Móvil
Vista detalle de ingreso
- Tablet
- Móvil
Formulario nuevo ingreso (validación)
- Tablet
- Móvil
Pop-up nuevo ingreso creado
- Tablet
- Móvil
Escalas automatizadas
- Tablet
- Móvil

Carga de trabajo (Jefe de Servicio)
- Tablet
- Móvil
Asignación nuevos ingresos (Jefe de Servicio)
- Tablet
- Móvil
KPIs (Jefe de Servicio)
- Tablet
- Móvil

Buscador de ingresos activos del servicio (por apellidos)
- Tablet
- Móvil
Arquitectura
Klinico sigue el patrón MVVM (Model-View-ViewModel), recomendado por Google para Flutter, combinado con el patrón Repository, lo que permite desacoplar completamente la lógica de negocio de la interfaz de usuario y de la fuente de datos.
flowchart TB
subgraph DI["INYECCIÓN DE DEPENDENCIAS"]
MP["<b>MultiProvider</b><br>(Provider tree en main.dart)"]
end
subgraph Infra["INFRAESTRUCTURA"]
AC["<b>ApiClient</b><br>(Dio + Interceptor JWT + 401)"]
SS["<b>Secure Storage</b><br>(flutter_secure_storage)"]
end
subgraph Data["CAPA DE DATOS"]
direction TB
FR["<b>Repositorios</b><br>(Acceso a datos API)"]
DTO["<b>DTOs</b><br>(*Response, fromJson)"]
DM["<b>Modelos de Dominio</b><br>(Admission, Episode)"]
end
subgraph Domain["CAPA DE SERVICIOS"]
direction TB
FS["<b>AuthService</b><br>(Sesión, JWT decode, Login)"]
EX["<b>AuthException</b><br>(Errores tipados)"]
end
subgraph Presentation["CAPA DE PRESENTACIÓN"]
direction TB
UI["<b>Vistas + Widgets</b><br>(Screens, Cards, Dialogs)"]
VM["<b>ViewModels</b><br>(ChangeNotifier)"]
NAV["<b>AuthWrapper</b><br>(Routing por Rol)"]
TH["<b>AppTheme</b><br>(Tema visual centralizado)"]
end
subgraph Frontend["<b>TABLET (Flutter - MVVM)</b>"]
direction TB
DI
Infra
Data
Domain
Presentation
end
subgraph Comm["COMUNICACIÓN"]
JSON["<b>REST API</b><br>JSON + JWT Header"]
end
MP -.-> VM & FR & FS & AC
AC --> SS
FR --> AC & DTO
FS --> SS & FR
FS -.-> EX
VM --> FS & FR
VM -.-> EX
UI --> VM
NAV --> UI
TH -.-> UI
AC -.-> EX
AC == Petición HTTP / HTTPS ==> JSON
JSON -. Update UI .-> AC
style UI fill:#fff
style DI fill:#f3e5f5,stroke:#6a1b9a,stroke-width:1px
style Infra fill:#fce4ec,stroke:#c62828,stroke-width:1px
style Data fill:#fff8e1,stroke:#f9a825,stroke-width:1px
style Domain fill:#e8f5e9,stroke:#2e7d32,stroke-width:1px
style Presentation fill:#e3f2fd,stroke:#1565c0,stroke-width:1px
style Frontend fill:#e1f5fe,stroke:#01579b,stroke-width:2px
style Comm fill:#f5f5f5,stroke:#333,stroke-dasharray: 5 5
- Views: widgets de pantalla, sin lógica de negocio.
- ViewModels: gestionan el estado de cada pantalla con
ChangeNotifiery son expuestos medianteProvider. - Repositories: única fuente de verdad para cada entidad de dominio; realizan las llamadas HTTP a través de
ApiClient. - ApiClient: cliente
Diocentralizado con interceptores para inyección del token Bearer y gestión global del error 401 (redirige al login sin necesidad deBuildContext). - AuthService: gestiona el ciclo de vida de la sesión (login, logout, decodificación del JWT y comprobación de expiración).
Estructura del proyecto
lib/
├── core/
│ ├── api_client.dart # Cliente Dio: base URL, interceptores Bearer y 401
│ ├── exceptions/ # Excepciones personalizadas (AuthException, etc.)
│ ├── models/ # Modelos de dominio compartidos (Admission, Episode)
│ └── theme/ # Tema Material de la aplicación
├── data/
│ ├── models/ # DTOs de respuesta de la API (JSON → Dart)
│ ├── repositories/ # Lógica de acceso a datos por entidad
│ └── services/
│ └── auth_service.dart # Login, logout, gestión y decodificación del JWT
├── ui/
│ ├── views/
│ │ ├── login_view.dart
│ │ ├── home_view.dart # Enrutamiento por rol tras autenticación
│ │ ├── medico_main_view.dart
│ │ ├── jefeservicio_main_view.dart
│ │ ├── admissions/ # Búsqueda, formulario y detalle de admisiones
│ │ ├── episodes/ # Formulario y detalle de episodios clínicos
│ │ └── servicekpis/ # Dashboard KPIs, nuevas admisiones, carga de trabajo
│ ├── viewmodels/ # Estado y lógica de cada pantalla (ChangeNotifier)
│ └── widgets/ # Componentes reutilizables (tarjetas, escalas, gráficos)
└── main.dart # Punto de entrada: MultiProvider, AuthWrapper, tema
Stack tecnológico
| Categoría | Tecnología |
|---|---|
| Framework UI | Flutter |
| Lenguaje | Dart ^3.11.3 |
| HTTP client | Dio ^5.9.2 |
| Estado | Provider ^6.1.5 |
| Almacenamiento seguro | flutter_secure_storage ^10.0.0 |
| Gráficos | fl_chart ^1.2.0 |
| Testing | mocktail ^1.0.4 |
| Autenticación | JWT (Bearer Token) |
Primeros pasos
Prerrequisitos
- Flutter SDK 3.x o superior → Guía de instalación
- Dart SDK
^3.11.3(incluido con Flutter) - Android Studio o Xcode según la plataforma destino
- JDK 17 (necesario para el backend Spring Boot)
- El backend klinico-api corriendo localmente (ver sección siguiente)
Verifica tu entorno con:
flutter doctor
Configuración del backend
Clona y arranca el servidor antes de lanzar la app:
git clone https://github.com/SergioLM7/klinico-api
cd klinico-api
# Sigue las instrucciones del README del backend para configurar la base de datos y las variables de entorno
./mvnw spring-boot:run
El servidor escucha por defecto en http://localhost:8080/api/v1.
Emulador Android: la app apunta automáticamente a
10.0.2.2:8080cuando detecta la plataforma Android, que es el alias dellocalhostdel host en el emulador de Android Studio.
Instalación y ejecución
# 1. Clona este repositorio
git clone https://github.com/SergioLM7/klinico-front
cd klinico-front
# 2. Instala las dependencias
flutter pub get
# 3. (Opcional) Regenera los iconos del launcher
dart run flutter_launcher_icons
# 4. Ejecuta la app en un emulador o dispositivo conectado
flutter run
# Para Android en modo release
flutter build apk --release
# Para iOS en modo release
flutter build ios --release
Roles de usuario
La app enruta automáticamente a la interfaz correspondiente según el campo role del JWT recibido tras el login:
| Rol | Interfaz | Acceso |
|---|---|---|
MEDICO |
MedicoMainView |
Gestión de admisiones y episodios clínicos |
JEFESERVICIO |
JefeServicioMainView |
Dashboard de KPIs y carga de trabajo del servicio |
Cualquier otro rol reconocido o no por el backend recibe un diálogo de acceso no autorizado, antes de ser redirigido a la vista de login.
Repositorio del backend
La API REST con la que se comunica esta aplicación está desarrollada en Spring Boot y disponible en:
Documentación técnica del frontend
La documentación del código del frontend (clases, métodos, modelos) se genera automáticamente con dartdoc y se publica en GitHub Pages con cada push a main.
Consultar documentación técnica
Para regenerar la documentación en local:
dart doc open doc/api/index.html
👨🏽💻 Contacto
Sergio Lillo, Full Stack Software Developer
- sergiolillom@gmail.com
© CONDITIONAL MIT LICENSE (NON-COMMERCIAL USE ONLY)
Copyright (©) 2026, Sergio Lillo
This project is licensed under a Conditional MIT License. It is open for academic and research purposes, but commercial use is strictly prohibited. See the LICENSE file for full details.
Libraries
- core/api_client
- core/exceptions/auth_exception
- core/models/admission
- core/models/episode
- core/theme/app_theme
- data/models/admission_response
- data/models/admission_update_response
- data/models/auth_response
- data/models/episode_response
- data/models/kpi_doctor_data
- data/models/kpi_month_value
- data/models/paginated_admission_result
- data/models/patient_preview_response
- data/models/patient_response
- data/models/service_response
- data/models/user_response
- data/models/workload_response
- data/repositories/admission_repository
- data/repositories/auth_repository
- data/repositories/episode_repository
- data/repositories/kpis_repository
- data/repositories/patient_repository
- data/repositories/service_repository
- data/repositories/user_repository
- data/services/auth_service
- main
- ui/viewmodels/admission_viewmodel
- ui/viewmodels/episode_viewmodel
- ui/viewmodels/kpis_viewmodel
- ui/viewmodels/login_viewmodel
- ui/viewmodels/workload_viewmodel
- ui/views/admissions/admission_detail_view
- ui/views/admissions/admission_form_view
- ui/views/admissions/admissions_search_view
- ui/views/episodes/episode_detail_view
- ui/views/episodes/episode_form_view
- ui/views/home_view
- ui/views/jefeservicio_main_view
- ui/views/login_view
- ui/views/medico_main_view
- ui/views/servicekpis/service_kpis_dashboard
- ui/views/servicekpis/service_new_admissions_view
- ui/views/servicekpis/service_workload_view
- ui/widgets/admission_card
- ui/widgets/admissions_dashboard
- ui/widgets/barthel_calculator_dialog
- ui/widgets/braden_calculator_dialog
- ui/widgets/cam_calculator_dialog
- ui/widgets/chads2_calculator_dialog
- ui/widgets/episode_info_card
- ui/widgets/glass_container
- ui/widgets/gradient_scaffold