Dashboard personal de glucosa para usuarios de FreeStyle Libre. Lee datos automáticamente desde la API de LibreLinkUp y los muestra en un panel visual con gráficas, estadísticas y alertas.
- Lectura actual — valor en tiempo real con flecha de tendencia
- Gráfica temporal — glucosa a lo largo del tiempo con ejes alineados al calendario (hoy, semana, mes, trimestre)
- Modo overlay — superponer días/semanas/meses para comparar patrones
- Time in Range — porcentaje en rango, alto y bajo
- Patrones por hora — promedio de glucosa por hora del día
- Eventos — episodios de hipoglucemia e hiperglucemia con duración
- Thresholds dinámicos — los límites
TARGET_LOW/TARGET_HIGHse configuran en.envy se reflejan en todas las gráficas
| Componente | Tecnología |
|---|---|
| Backend | Python 3.12, FastAPI, aiosqlite |
| Frontend | React, TypeScript, Recharts, TanStack Query |
| Base de datos | SQLite (volumen persistente) |
| Reverse proxy | Nginx (dev) / Caddy (prod, HTTPS automático) |
| Contenedores | Docker Compose |
- Copiar
.env.examplea.envy rellenar credenciales:
cp .env.example .env- Editar
.env:
LIBRE_EMAIL=tu-email@libreview.com
LIBRE_PASSWORD=tu-password
TARGET_LOW=60
TARGET_HIGH=180- Levantar:
docker compose up -d --build- Abrir http://localhost:3000
El stack de producción añade Caddy (HTTPS + basic auth) y DuckDNS (DNS dinámico gratuito).
- VM con Docker (ej: Oracle Cloud Free Tier, Hetzner, cualquier VPS)
- Subdominio en DuckDNS (gratuito)
DOMAIN=tusubdominio.duckdns.org
DUCKDNS_SUBDOMAIN=tusubdominio
DUCKDNS_TOKEN=tu-token
DASH_USER=usuario
DASH_PASSWORD_HASH=$$2a$$14$$hash_generado_por_caddyPara generar el hash de la contraseña:
docker run --rm caddy:2-alpine caddy hash-password --plaintext 'tu-password'Nota: En el
.env, reemplazar cada$del hash por$$para evitar interpolación de Docker Compose.
docker compose -f docker-compose.prod.yml up -d --buildCaddy obtiene el certificado HTTPS automáticamente vía Let's Encrypt.
Un cron diario copia el SQLite y mantiene los últimos 7 días:
crontab -e
# Añadir:
0 3 * * * /ruta/al/proyecto/scripts/backup.sh >> /var/log/glucose-backup.log 2>&1├── api/ # Backend FastAPI
│ ├── main.py # App entry point
│ ├── config.py # Settings desde .env
│ ├── database.py # Queries SQLite
│ ├── poller.py # Background task que lee LibreLinkUp
│ ├── libre_client.py # Cliente HTTP para la API de Libre
│ └── routers/ # Endpoints REST
├── web/ # Frontend React + Vite
│ └── src/
│ ├── components/ # Componentes visuales
│ ├── hooks/ # React Query hooks
│ └── api/ # Cliente API tipado
├── scripts/ # Deploy y backup
├── docker-compose.yml # Stack de desarrollo
└── docker-compose.prod.yml # Stack de producción (Caddy + DuckDNS)
cd api && pip install -r requirements.txt && pytestMIT