Klinico Logo

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.

Flutter Dart Platform License


Tabla de contenidos


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.

(volver arriba)


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.

(volver arriba)


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

(volver arriba)


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 ChangeNotifier y son expuestos mediante Provider.
  • Repositories: única fuente de verdad para cada entidad de dominio; realizan las llamadas HTTP a través de ApiClient.
  • ApiClient: cliente Dio centralizado con interceptores para inyección del token Bearer y gestión global del error 401 (redirige al login sin necesidad de BuildContext).
  • AuthService: gestiona el ciclo de vida de la sesión (login, logout, decodificación del JWT y comprobación de expiración).

(volver arriba)


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

(volver arriba)


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)

(volver arriba)


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:8080 cuando detecta la plataforma Android, que es el alias del localhost del 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

(volver arriba)


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.

(volver arriba)


Repositorio del backend

La API REST con la que se comunica esta aplicación está desarrollada en Spring Boot y disponible en:

Klinico API


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

(volver arriba)


👨🏽‍💻 Contacto

Sergio Lillo, Full Stack Software Developer LinkedIn - 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.

(back to top)

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
ui/widgets/scale_button