83 lines
4.2 KiB
Markdown
83 lines
4.2 KiB
Markdown
# #229 — HUB-21 : consommation des réglages généraux du Hub par ObsiGate
|
|
|
|
**Carte :** propagation de HUB-21 (fusion #135) — le pilote TikTak
|
|
(0.61.22, en production) a posé le patron de client ; ObsiGate le
|
|
consomme à son tour, comme les autres hôtes de la suite.
|
|
**Version cible :** 2.85.2 (branche depuis le main 2.85.1).
|
|
|
|
## Contrat consommé (liste fermée D6(a))
|
|
|
|
- `GET {hub}/api/reglages/effectifs` — endpoint **public** (aucun
|
|
cookie relayé), `Accept: application/json`, délai **2 s** ;
|
|
- réponse 200, forme figée : `{"recherche_partout": bool,
|
|
"banniere": str, "domaine_defaut": "pro"|"famille"|"perso"|null,
|
|
"ttl_secondes": 60}`, `Cache-Control: public, max-age=60` ;
|
|
- **URL du Hub** : `draco_config.app_url("hub")`, la résolution de la
|
|
barre commune (#223) — variable explicite d'abord, dérivation par
|
|
l'hôte sœur ensuite, défaut officiel enfin. Jamais d'URL dev figée.
|
|
|
|
## Client — `backend/hub_reglages.py`
|
|
|
|
Sur le patron du pilote TikTak (`app/hub_reglages.py`, httpx → urllib
|
|
comme `backend/hub_roles.py`) :
|
|
|
|
- cache mémoire **60 s** ; horodatage posé **avant** l'appel : un
|
|
échec conserve l'ancien cache et ne déclenche pas de rafale vers un
|
|
Hub en panne ;
|
|
- forme validée strictement ; toute erreur (réseau, délai, statut
|
|
≠ 200, JSON illisible, forme hors contrat) → **repli intégral** sur
|
|
les défauts actuels (`recherche_partout: true`, `banniere: ""`,
|
|
`domaine_defaut: null`) — le comportement d'ObsiGate avant HUB-21.
|
|
Le module ne lève jamais ; aucun appel au démarrage.
|
|
|
|
## Consommation
|
|
|
|
1. **`banniere`** — `backend/main.py::_fragment_banniere_hub()`
|
|
construit le fragment (texte **échappé** via `html.escape`, jamais
|
|
de HTML injecté), injecté sous la barre commune par `_index_html`
|
|
(page principale, juste avant le rappel de la barre) et par
|
|
`serve_recherche_page` (page /recherche, après l'en-tête de la
|
|
barre). Le script inline (nonce CSP ajouté par `inject_csp_nonce`)
|
|
révèle le bandeau sauf si le même texte a été fermé dans la
|
|
session du navigateur (`sessionStorage`, clé
|
|
`obsigate_banniere_masquee`) : une nouvelle annonce réapparaît.
|
|
Bannière vide = aucun fragment rendu, zéro changement visuel.
|
|
Styles `.banniere-hub*` dans `frontend/style.css`, sur les
|
|
variables du thème (`var(--accent)`).
|
|
2. **`recherche_partout`** — `serve_recherche_page` remplace le jeton
|
|
`{{RECHERCHE_PARTOUT}}` de `frontend/recherche.html`, rendu en
|
|
attribut `data-recherche-partout` du `<main id="recherche">`. Le
|
|
JS vendangé `frontend/js/recherche.js` (modification identique
|
|
dans les 4 hôtes applicatifs : fonction pure
|
|
`federationAutorisee`) n'interroge plus les applications sœurs ni
|
|
la console quand la valeur est `false` — leurs sections affichent
|
|
« Recherche fédérée désactivée… » — tandis que la recherche locale
|
|
ObsiGate (même origine) continue. Attribut absent ou illisible =
|
|
fédération active (repli).
|
|
3. **`domaine_defaut` — non consommé.** ObsiGate n'a pas de notion
|
|
de domaine (Pro/Famille/Perso) propre à ses vues : le sélecteur de
|
|
domaine de la barre commune pilote le panneau Spark, pas
|
|
ObsiGate. La valeur est lue et validée par le client, sans effet
|
|
local. Seul l'hôte console (agent) applique ce réglage.
|
|
|
|
## i18n
|
|
|
|
Aucun texte d'interface du SPA n'est ajouté : la bannière est un
|
|
contenu d'annonce servi par le Hub (texte libre de l'administrateur),
|
|
et le libellé « Fermer l'annonce » est l'attribut d'accessibilité du
|
|
fragment injecté côté serveur, sur le même patron que les autres
|
|
hôtes. Pas de clé `frontend/locales/*` ajoutée.
|
|
|
|
## Tests
|
|
|
|
- `tests/test_hub_reglages.py` (nouveau) : contrat exact de l'appel
|
|
(URL, aucun cookie, délai 2 s), formes inattendues → repli, erreur
|
|
HTTP / Hub injoignable / JSON illisible → repli, cache 60 s,
|
|
ancien cache conservé sans rafale ; intégration TestClient :
|
|
bannière présente et échappée sur `/` et `/recherche`, absente si
|
|
vide ou Hub muet, `data-recherche-partout` selon la valeur du
|
|
drapeau (faux / vrai / Hub muet).
|
|
- `tests/frontend/recherche.test.mjs` : assertions ajoutées pour
|
|
`federationAutorisee` (seules les valeurs explicitement négatives
|
|
désactivent ; absent/illisible = actif).
|