Saltar a contenido

Diagramas del sistema

Diagramas Mermaid de los flujos principales del sistema. Renderizados nativamente por el plugin mkdocs-mermaid2-plugin.

Topología de despliegue (modo producción)

InternetCloudflare EdgePC anfitrión (modo prod)DNScustodiam.esTunnelcloudflaredGitHub Pagesdocs.custodiam.esDocker Compose --profile tunnelStack de servicioscustodiam-web(Nginx + PWA Flutter):80custodiam-api:8000Keycloak 26:8080PostgreSQL 15ntfy:80 HTTPSapp/api/auth/ntfy.custodiam.esdocs.custodiam.es cloudflared connectcloudflared connectcloudflared connectcloudflared connectadmin API

Flujo OAuth2 + PKCE (móvil)

sequenceDiagram
    participant U as Usuario
    participant App as Flutter App
(Android/iOS) participant KC as Keycloak participant API as custodiam-api U->>App: Toca "Iniciar sesión" App->>App: Genera code_verifier + code_challenge
(_pendingGrant en memoria) App->>KC: Abre Custom Tab con
authorize?code_challenge=... KC-->>U: Pantalla de login U->>KC: Credenciales (usuario + password) KC-->>App: Redirige a
es.custodiam://callback?code=... Note over App: Deep link captura el code App->>KC: POST /token
code + code_verifier KC-->>App: access_token + refresh_token App->>App: Guarda en flutter_secure_storage App->>API: GET /me
Authorization: Bearer API->>API: Valida JWT localmente con PyJWT
(usa JWKS cacheado) API-->>App: 200 OK + datos del voluntario

Flujo OAuth2 + PKCE (web)

sequenceDiagram
    participant U as Usuario
    participant Web as PWA Web
(Flutter Web) participant SS as sessionStorage participant KC as Keycloak participant API as custodiam-api U->>Web: Click "Iniciar sesión" Web->>Web: Genera code_verifier + code_challenge Web->>SS: Persiste code_verifier
(clave: custodiam.oauth.code_verifier) Web->>KC: window.location = authorize?code_challenge=...
(webOnlyWindowName: '_self') Note over Web: ⚠️ Recarga completa del navegador KC-->>U: Pantalla de login U->>KC: Credenciales KC-->>Web: Redirige a
https://app.custodiam.es/callback?code=... Note over Web: GoRouter (PathUrlStrategy) matcha /callback Web->>SS: Lee code_verifier Web->>KC: POST /token
code + code_verifier KC-->>Web: access_token + refresh_token Web->>SS: Limpia code_verifier
Guarda tokens en sessionStorage Web->>API: GET /me
Authorization: Bearer API-->>Web: 200 OK + datos del voluntario

Asimetría móvil/web — ADR-023

La diferencia clave entre móvil y web: en móvil la app sobrevive la redirección al IdP (deep link vuelve a la misma instancia con el _pendingGrant intacto en memoria); en web, la navegación a Keycloak recarga la PWA completa, perdiendo el estado en memoria. Por eso web necesita persistir el code_verifier en sessionStorage antes de redirigir. Se implementa con dos AuthService distintos seleccionados vía kIsWeb. Detalle completo en ADR-023.

Flujo de notificación de emergencia

sequenceDiagram
    participant Coord as Coordinador
(usuario) participant App as App Coord participant API as custodiam-api participant FCM as Firebase FCM participant NTFY as ntfy participant Volunt as App Voluntario
(N dispositivos) Coord->>App: Crea convocatoria de emergencia App->>API: POST /servicios
tipo=emergencia, voluntarios_filtrados API->>API: Filtra voluntarios disponibles + permisos API->>FCM: Envía push a tokens FCM
(canal principal) alt FCM responde 200 FCM-->>Volunt: Push notification
(notificación + datos del servicio) Note over Volunt: Voluntario toca → abre app en pantalla del servicio else FCM falla o timeout > 5s API->>NTFY: Publica al canal /custodiam-emergencia
(canal de respaldo) NTFY-->>Volunt: Push via ntfy
(canal secundario) Note over API: Log de fallo de FCM
+ telemetría para análisis end Volunt->>API: PATCH /servicios/{id}/voluntarios/{me}
{respuesta: "acepto" | "rechazo"} API-->>App: Notifica al coordinador
(via FCM tambien)

Despliegue del book de documentación

Dev(commit + push)GitHub Actionsworkflow deploy.ymlGitHub Pagesbranch gh-pagesCloudflare DNSCNAME docs → custodiam.github.io(DNS only, sin proxy)Usuario push a mainuv sync + mkdocs buildpeaceiris/actions-gh-pages@v4https://docs.custodiam.esresuelve a IP de GitHub Pages fallback custodiam.github.io/custodiam-book/

Resiliencia vendor-lock-free

El sitio sigue siendo accesible en https://custodiam.github.io/custodiam-book/ aunque Cloudflare desaparezca: solo se perdería el dominio "bonito" docs.custodiam.es. Cloudflare se reserva como CDN opcional futuro (toggle Proxied reversible). Decisión en [ADR-027].

Referencias

  • Stack técnico — tecnologías concretas con versiones.
  • ADRs — decisiones arquitectónicas que sostienen estos diagramas.