feat: HUB-21 — réglages généraux du Hub consommés par ObsiGate (bannière + drapeau recherche_partout) #229
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
# #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).
|
||||
Reference in New Issue
Block a user