feat(stt-client): pages détail enrichies (aperçu portefeuille + alertes) (#59)

Les pages détail du portail HUD affichent désormais un aperçu live des données
du service, pas seulement santé + lien :

- Ghostfolio → portefeuille complet : valeur, performance globale, positions
  (allocation % + P/L par ligne, coloré). Nouvel endpoint serveur
  POST /v1/portfolio/details (jeton client, source unique réutilisée).
- Alertmanager → TOUTES les alertes actives du homelab (total + critiques +
  liste avec sévérité), rendu côté HUD depuis `all_alerts` poussé par le
  StatusPoller (auto-rafraîchi, aucun appel supplémentaire).

Mécanisme extensible (`DETAIL_PROVIDERS` : `server` = requête backend |
`alerts` = liste locale). Cartes de stats + lignes de données génériques.

Client 0.18.0. Vérifié via Playwright (rendu, tons, normalisation des %).

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
ALI YESILKAYA 2026-06-23 23:48:20 +02:00 committed by GitHub
parent 7bfedb0901
commit f47bc36f29
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 288 additions and 13 deletions

View file

@ -68,6 +68,27 @@ class ServerClient:
except requests.RequestException:
return "Je n'arrive pas à joindre le serveur pour Ghostfolio."
def portfolio_details(self) -> dict:
"""Aperçu structuré du portefeuille (page détail du portail HUD).
{value, currency, performance_pct, holdings:[]} ou {error: }. Dégrade en
clair si le serveur est antérieur (pas d'endpoint) ou injoignable.
"""
import requests
try:
r = requests.post(
f"{self.url}/v1/portfolio/details",
json={"token": self.secrets.get("ghostfolio_token")},
timeout=self.timeout,
)
if r.status_code == 404:
return {"error": "Aperçu indisponible (STT-server antérieur)."}
r.raise_for_status()
return r.json()
except requests.RequestException:
return {"error": "Je n'arrive pas à joindre le serveur pour Ghostfolio."}
def contexts(self) -> dict | None:
"""{'default':…, 'contexts':[{id,label,icon,description}]} ; None si indisponible.