Flujos de Datos y Procesos¶
Documentación de los flujos clave de datos y procesos en SmallCountry: autenticación, telemetría de sensores, backups y despliegue. Cada flujo está representado con un diagrama de secuencia Mermaid.
1. Flujo de autenticación¶
Cómo una persona accede a un servicio protegido. El camino completo desde el navegador hasta la aplicación.
sequenceDiagram
actor Persona as 👤 Persona
participant Caddy as 🔒 Caddy (proxy TLS)
participant Authentik as 🛡️ Authentik (IdP)
participant Servicio as 📦 Servicio
Persona->>Caddy: GET https://servicio.sc
Caddy->>Authentik: forward_auth /outpost.goauthentik.io/auth
alt Sin sesión
Authentik->>Caddy: 302 Redirect → /login
Caddy->>Persona: Redirige a login.authentik.sc
Persona->>Authentik: POST credenciales + TOTP
Authentik->>Authentik: Valida credenciales
Authentik->>Authentik: Valida TOTP/WebAuthn
Authentik->>Caddy: Set-Cookie + 302 → servicio.sc
end
Caddy->>Authentik: Valida cookie de sesión
Authentik->>Caddy: 200 OK + cabeceras X-Authentik-*
alt Usuario autorizado (grupo correcto)
Caddy->>Servicio: Proxy + cabeceras de auth
Servicio->>Servicio: Autorización por grupo
Servicio->>Caddy: 200 OK (contenido)
Caddy->>Persona: Contenido del servicio
else Usuario no autorizado
Caddy->>Persona: 403 Forbidden
end
Dónde ocurre: Ra, LXC caddy.sc y authentik.sc
Tiempo típico: <200ms con sesión activa, <2s con login nuevo
ADR: ADR-014 (Authentik), ADR-015 (Caddy)
2. Flujo de datos de sensor¶
El recorrido de un dato desde un ESP32 en el campo hasta el dashboard de Grafana que ve Melissa.
sequenceDiagram
participant ESP32 as 📡 ESP32 (campo)
participant Mosquitto as 📨 Mosquitto (MQTT broker)
participant NodeRED as 🔄 Node-RED
participant InfluxDB as 💾 InfluxDB
participant Victoria as 📊 VictoriaMetrics
participant Grafana as 📈 Grafana
participant ntfy as 🔔 ntfy
actor Melissa as 👩🌾 Melissa
ESP32->>ESP32: Lectura del sensor BME280<br/>temp=34.2°C, hum=58%, peso=45.3kg
ESP32->>Mosquitto: PUBLISH colmenas/03/sensores<br/>QoS 1, retain: true
Mosquitto->>NodeRED: Mensaje entregado (suscriptor)
NodeRED->>NodeRED: Transformación:<br/>extraer temp, hum, peso<br/>añadir timestamp y ubicación
par Almacenamiento en paralelo
NodeRED->>InfluxDB: WRITE serie temporal<br/>colmena_03, temp=34.2
NodeRED->>Victoria: WRITE vía Prometheus remote write<br/>sc_colmena_temp{id="03"} 34.2
end
NodeRED->>NodeRED: Evalúa reglas de alerta:<br/>¿peso bajó >20% en 24h?
alt Alerta detectada
NodeRED->>ntfy: POST tópico sc-campo<br/>"⚠️ Colmena 03: pérdida de peso"
ntfy->>Melissa: Push notification al móvil
end
Grafana->>Victoria: QUERY PromQL<br/>sc_colmena_temp{id="03"}[24h]
Victoria->>Grafana: Serie temporal (8640 puntos)
Grafana->>Melissa: Dashboard de colmenas actualizado
Dónde ocurre: ESP32 en campo → Ra (Mosquitto LXC + Node-RED LXC)
Latencia: <500ms desde lectura hasta dashboard
ADR: ADR-001 (MQTT), ADR-008 (ESP32)
3. Flujo de backup¶
Cómo se protegen los datos: del snapshot ZFS automático al backup offsite verificado.
sequenceDiagram
participant ZFS as 💾 ZFS (rpool)
participant PBS as 📦 PBS (Proxmox Backup Server)
participant Restic as 🔐 Restic
participant Thoth as 🗄️ Thoth (offsite)
participant n8n as ⚙️ n8n (verificación)
actor Mnemosine as 📋 Mnemósine
Note over ZFS: Cada 15 minutos (automático)
ZFS->>ZFS: zfs snapshot rpool/datos/*@auto-$(date +%H%M)
Note over PBS: Diario 02:00
PBS->>ZFS: Backup de todos los CT y VM
ZFS->>PBS: Datos incrementales (solo bloques modificados)
PBS->>PBS: Verificación de integridad SHA-256
Note over Restic: Diario 03:00
Restic->>ZFS: restic backup /datos/*
ZFS->>Restic: Datos cifrados y deduplicados
Restic->>Restic: Snapshot con ID único
Restic->>Thoth: restic copy → repositorio remoto (NetBird)
Thoth->>Thoth: Almacena snapshot cifrado
Note over n8n: Semanal, domingo 02:00
n8n->>Restic: restic check --read-data
Restic->>Thoth: Verifica integridad de todos los blobs
Thoth->>Restic: Checksums válidos
Restic->>n8n: ✅ Verificación OK
n8n->>Mnemosine: Matrix: "Backup semanal verificado correctamente"
alt Verificación fallida
Restic->>n8n: ❌ Corrupción detectada en blob X
n8n->>Mnemosine: ntfy CRÍTICO: "Backup corrupto. Recuperar de snapshot anterior"
end
Dónde ocurre: Ra (ZFS, PBS, Restic, n8n) → Thoth (offsite vía NetBird)
Estrategia: Backup 3-2-1. Tres copias, dos medios (SSD + HDD), una externa (Thoth)
ADR: ADR-006 (ZFS), ADR-016 (Backup 3-2-1)
4. Flujo de despliegue¶
Cómo un cambio en el código llega a producción de forma segura y automatizada.
sequenceDiagram
actor Hefesto as 👷 Hefesto (admin)
participant Forgejo as 🔧 Forgejo (repositorio)
participant Actions as ⚡ Forgejo Actions (CI/CD)
participant Lint as ✅ Lint & Test (LXC)
participant Ansible as 📜 Ansible
participant SSH as 🔑 SSH
participant LXC as 📦 LXC destino
participant Semaphore as 🎛️ Semaphore (registro)
actor Argos as 👁️ Argos (observabilidad)
Hefesto->>Forgejo: git push → rama main<br/>(cambio en rol Ansible de Immich)
Forgejo->>Actions: Trigger workflow: `.forgejo/workflows/deploy.yml`
Actions->>Lint: Job 1: Lint
Lint->>Lint: ansible-lint, yamllint, shellcheck
Lint->>Actions: ✅ Lint OK
Actions->>Lint: Job 2: Test (entorno aislado)
Lint->>Lint: ansible-playbook --check --diff
Lint->>Actions: ✅ Test OK (dry-run sin errores)
Actions->>Actions: Job 3: Deploy (requiere aprobación)
Actions->>Hefesto: Solicita aprobación manual
Hefesto->>Actions: ✅ Aprobado
Actions->>Ansible: ansible-playbook deploy-immich.yml
Ansible->>SSH: Conexión SSH a LXC immich (10.10.10.42)
SSH->>LXC: Ejecuta tareas del rol:
LXC->>LXC: 1. Backup pre-deploy (ZFS snapshot)
LXC->>LXC: 2. docker-compose pull (nueva versión)
LXC->>LXC: 3. docker-compose up -d
LXC->>LXC: 4. Healthcheck: curl localhost:8080/health
LXC->>Ansible: ✅ Deploy OK
Ansible->>Actions: ✅ Playbook completado
Actions->>Semaphore: Registra despliegue (auditoría)
Actions->>Argos: Notifica por Matrix: "Immich v1.125 desplegado"
Argos->>Argos: Verifica métricas post-deploy:<br/>sin errores 5xx, latencia normal
Dónde ocurre: Forgejo Actions → Ansible → LXC destino
Tiempo típico: <3 min desde push hasta deploy (más aprobación manual)
ADR: ADR-018 (LXC aislamiento)
Resumen de flujos¶
| Flujo | Gatillo | Latencia | Criticidad |
|---|---|---|---|
| Autenticación | GET a servicio protegido | <200ms (sesión), <2s (login) | Tier A |
| Datos de sensor | Lectura de ESP32 cada 60s | <500ms extremo a extremo | Tier B |
| Backup automático | CRON (cada 15 min / diario) | 5-45 min según dataset | Tier A |
| Despliegue | Push a main en Forgejo | <3 min + aprobación | Tier B |