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

@ -25,7 +25,7 @@ from stt_server.contexts import CONTEXTS, assemble, get_context
from stt_server.knowledge import Knowledge
from stt_server.longterm import LongTermMemory
from stt_server.memory import SessionStore
from stt_server.sources import fetch_blocks, ghostfolio_phrase
from stt_server.sources import fetch_blocks, ghostfolio_details, ghostfolio_phrase
log = logging.getLogger("stt_server")
# uvicorn ne configure que ses propres loggers : on attache notre handler en INFO
@ -126,6 +126,16 @@ async def v1_portfolio(req: PortfolioRequest) -> dict:
return {"summary": summary}
@app.post("/v1/portfolio/details")
async def v1_portfolio_details(req: PortfolioRequest) -> dict:
"""Aperçu structuré du portefeuille (page détail du portail HUD).
Même source de jeton que /v1/portfolio (client prioritaire, sinon env serveur).
"""
async with httpx.AsyncClient() as c:
return await ghostfolio_details(c, req.token)
@app.post("/v1/reset")
async def v1_reset(req: AskRequest) -> dict:
if req.session_id: