feat(stt-client): pages détail par service + santé live (probe + Prometheus + Alertmanager) (#36)

Transforme le portail (tuiles ouvrant un lien) en mini-pages par service, avec état
de santé temps réel — comme demandé.

Page détail (clic sur une tuile) : icône+nom, pilule d'état (en ligne/dégradé/hors
ligne + latence), description, composants (pastilles), alertes actives, infos (URL),
bouton « Ouvrir ». Tuiles : pastille de santé live + badge global d'alertes.

- registry.py : Service enrichi (description, health_url, components[{name,prom}],
  alerts_match) — toujours config-driven.
- health.py : StatusPoller en thread. Probe HTTP (up/down+latence) + Prometheus
  /api/v1/query (composants via up{}/kube-state-metrics) + Alertmanager /api/v2/alerts
  (hors Watchdog). Parallélisé (ThreadPoolExecutor), pousse portal-status au HUD.
- config.py : métadonnées homelab vérifiées en live (7 services ; traefik retiré —
  URL injoignable) + section [portal] (intervalle, URLs, timeouts).
- app.py : démarre le poller, diffuse portal-status (+ dernier état au connect).
- HUD : vues liste⟷détail, pastilles, badge alertes, mise à jour live.
- bump 0.9.0 → 0.10.0.

Validé : StatusPoller en direct contre le homelab (cycle 0.12s, 7 services ok,
composants Prometheus résolus, 0 alerte) ; HUD via Playwright (pastilles ok/dégradé/
hors-ligne, page détail complète, alerte rendue, bouton Ouvrir → open-service).

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
ALI YESILKAYA 2026-06-20 23:17:27 +02:00 committed by GitHub
parent 3b6099ffa0
commit d4b053622c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 600 additions and 50 deletions

View file

@ -34,14 +34,13 @@ enabled = true # cache local de conversation (brut, gitigno
local_db = "~/.local/share/stt/memory.sqlite"
# ---------------------------------------------------------------------------
# Portail de services — tuiles du HUD + commande vocale « ouvre <service> ».
# Portail de services — tuiles + pages détail (santé live) + voix « ouvre <x> ».
# Définir [[services]] ici REMPLACE entièrement la liste par défaut (homelab Funk).
# Ajouter un service = un bloc de plus. Champs :
# id : identifiant unique (interne)
# name : libellé affiché sur la tuile
# url : ouverte dans ton navigateur normal au clic / à la voix
# icon : emoji de la tuile
# aliases : mots déclencheurs pour la voix (« ouvre les métriques » → grafana)
# Champs : id, name, url, icon, aliases (voix) ; + pour la page détail (optionnel) :
# description : phrase « ce que fait le service »
# health_url : endpoint sondé (up/down + latence) ; défaut = url
# components : briques dont dépend le service ; prom = PromQL renvoyant 1/0
# alerts_match: labels Alertmanager — alerte affichée si TOUS matchent
# ---------------------------------------------------------------------------
# [[services]]
# id = "grafana"
@ -49,10 +48,18 @@ local_db = "~/.local/share/stt/memory.sqlite"
# url = "http://grafana.lab.local"
# icon = "📊"
# aliases = ["graphana", "metriques", "monitoring", "dashboard"]
# description = "Tableaux de bord et visualisation des métriques."
# health_url = "http://grafana.lab.local/api/health"
# alerts_match = { namespace = "monitoring" }
#
# [[services]]
# id = "ghostfolio"
# name = "Ghostfolio"
# url = "http://ghostfolio.lab.local"
# icon = "💰"
# aliases = ["portefeuille", "bourse"]
# [[services.components]]
# name = "Pod"
# prom = 'kube_pod_status_ready{namespace="monitoring",pod=~".*grafana.*",condition="true"}'
# Santé live des pages détail (sondage non bloquant côté client) :
# [portal]
# status_enabled = true
# status_interval_sec = 15
# probe_timeout_sec = 4
# prometheus_url = "http://prometheus.lab.local"
# alertmanager_url = "http://alertmanager.lab.local"