Fusion #69 : Alertes unifiées (panneau + pastille, agrégation à la demande) #39

Closed
bruno wants to merge 5 commits from alertes-unifiees-69 into main
Owner

Fusion #69 (chantier 2) — Alertes unifiées, côté ObsiGate.

Audit (vérifié sur main, pas supposé)

  • ObsiGate n'expose AUCUNE notification entrante consultable par l'utilisateur : ses /api/notify/* (router backend/routers/notify.py) sont des canaux d'envoi sortants (discord/telegram/smtp/webhook, CRUD réservé aux administrateurs, secrets masqués *** + has_secret). Il n'existe ni table ni endpoint de journal de notifications entrantes. La section ObsiGate du panneau le dit honnêtement et renvoie vers l'accueil d'ObsiGate — aucune alerte inventée, aucun faux lien vers un élément.
  • Les autres sources (même audit que les autres PR du chantier) : Flowdeck GET /api/notifications (non lues = actives), TikTak GET /api/notifications (non lues = actives ; lien /?task={id}), Kanbante GET /api/events (aucun état lu/non lu → tout historique, jamais compté actif).
  • Verrou constaté côté ObsiGate comme visualiseur : sa CSP connect-src ne nommait que self/CDN/agent → la lecture des API sœurs depuis og(-dev) était bloquée. ObsiGate n'a pas besoin de CORS (aucune API source à exposer).

Ce qui change (cette PR ObsiGate)

  • frontend/draco-alertes.js (nouveau, module partagé, pas un fichier ui/barre-apps.*) + frontend/draco-alertes.css : panneau Alertes (actives d'abord, puis historique, par application, origine/titre/date/état/lien profond ; textContent uniquement). Pastille via DRACO_BAR.setCounts({alertes: n}). Bases résolues dans l'ordre barre v0.1.6 : config explicite > hôte -dev dérivé > href rendu (window.DRACO_URLS injecté par le backend) > défaut prod.
  • frontend/index.html : branche alertes → DRACO_ALERTES.open() (repli : message honnête « module non chargé », jamais le placeholder) ; le toast « Alertes unifiées : arrive avec la fédération » DISPARAÎT ; chargement du module et de son CSS (servis /static/draco-alertes.* via le montage FRONTEND_DIR existant).
  • backend/main.py (SecurityHeadersMiddleware) : CSP connect-src += origines sœurs résolues par draco_config.urls_publiques() (explicite > dérivation depuis l'hôte de l'agent > défaut officiel).
  • Test : tests/frontend/draco-alertes.test.mjs (4 tests Node, patron des tests frontend existants).

Limites, dites honnêtement

  • Agrégation À LA DEMANDE, pas une fédération temps réel (relecture à l'ouverture + au chargement pour la pastille).
  • Vue unifiée complète seulement quand les 4 PR du chantier sont déployées ; sinon la section manquante affiche « Connexion requise » ou « injoignable » avec son lien natif, jamais de faux contenu.
  • Pastille = Flowdeck non lues + TikTak non lues uniquement. ObsiGate ne contribue ni actives ni historique (aucune source) — c'est un constat d'audit, pas un oubli.
  • Aucun bump de version, aucun merge, aucune fermeture d'issue dans cette PR (coordinateur).

Tests (chiffres réels, sandbox)

  • node tests/frontend/draco-alertes.test.mjs : 4 passed (logique du module + gabarit livré).
  • Vérification isolée de la dérivation CSP (backend/draco_config.py, sans dépendances lourdes) : origines prod exactes flowdeck, kanbante, og, tiktak .dracodev.net.
  • python3 -m py_compile backend/main.py : OK ; node --check frontend/draco-alertes.js : OK.
  • Non fait ici (delta explicite) : la suite pytest ObsiGate n'a pas pu tourner dans la sandbox — l'import de backend.main exige la cascade complète de dépendances du backend (frontmatter, snowballstemmer, …) ; à lancer par la CI / le coordinateur. Le rendu authentifié complet et la pastille inter-apps en conditions réelles restent à valider par Bruno après déploiement des 4 PR.
Fusion #69 (chantier 2) — Alertes unifiées, côté ObsiGate. ## Audit (vérifié sur main, pas supposé) - ObsiGate n'expose AUCUNE notification entrante consultable par l'utilisateur : ses `/api/notify/*` (router `backend/routers/notify.py`) sont des canaux d'envoi sortants (discord/telegram/smtp/webhook, CRUD réservé aux administrateurs, secrets masqués `***` + `has_secret`). Il n'existe ni table ni endpoint de journal de notifications entrantes. La section ObsiGate du panneau le dit honnêtement et renvoie vers l'accueil d'ObsiGate — aucune alerte inventée, aucun faux lien vers un élément. - Les autres sources (même audit que les autres PR du chantier) : Flowdeck `GET /api/notifications` (non lues = actives), TikTak `GET /api/notifications` (non lues = actives ; lien `/?task={id}`), Kanbante `GET /api/events` (aucun état lu/non lu → tout historique, jamais compté actif). - Verrou constaté côté ObsiGate comme visualiseur : sa CSP `connect-src` ne nommait que self/CDN/agent → la lecture des API sœurs depuis og(-dev) était bloquée. ObsiGate n'a pas besoin de CORS (aucune API source à exposer). ## Ce qui change (cette PR ObsiGate) - `frontend/draco-alertes.js` (nouveau, module partagé, pas un fichier `ui/barre-apps.*`) + `frontend/draco-alertes.css` : panneau Alertes (actives d'abord, puis historique, par application, origine/titre/date/état/lien profond ; `textContent` uniquement). Pastille via `DRACO_BAR.setCounts({alertes: n})`. Bases résolues dans l'ordre barre v0.1.6 : config explicite > hôte -dev dérivé > href rendu (`window.DRACO_URLS` injecté par le backend) > défaut prod. - `frontend/index.html` : branche `alertes` → `DRACO_ALERTES.open()` (repli : message honnête « module non chargé », jamais le placeholder) ; le toast « Alertes unifiées : arrive avec la fédération » DISPARAÎT ; chargement du module et de son CSS (servis `/static/draco-alertes.*` via le montage `FRONTEND_DIR` existant). - `backend/main.py` (`SecurityHeadersMiddleware`) : CSP `connect-src` += origines sœurs résolues par `draco_config.urls_publiques()` (explicite > dérivation depuis l'hôte de l'agent > défaut officiel). - Test : `tests/frontend/draco-alertes.test.mjs` (4 tests Node, patron des tests frontend existants). ## Limites, dites honnêtement - Agrégation À LA DEMANDE, pas une fédération temps réel (relecture à l'ouverture + au chargement pour la pastille). - Vue unifiée complète seulement quand les 4 PR du chantier sont déployées ; sinon la section manquante affiche « Connexion requise » ou « injoignable » avec son lien natif, jamais de faux contenu. - Pastille = Flowdeck non lues + TikTak non lues uniquement. ObsiGate ne contribue ni actives ni historique (aucune source) — c'est un constat d'audit, pas un oubli. - Aucun bump de version, aucun merge, aucune fermeture d'issue dans cette PR (coordinateur). ## Tests (chiffres réels, sandbox) - `node tests/frontend/draco-alertes.test.mjs` : 4 passed (logique du module + gabarit livré). - Vérification isolée de la dérivation CSP (`backend/draco_config.py`, sans dépendances lourdes) : origines prod exactes `flowdeck, kanbante, og, tiktak .dracodev.net`. - `python3 -m py_compile backend/main.py` : OK ; `node --check frontend/draco-alertes.js` : OK. - Non fait ici (delta explicite) : la suite pytest ObsiGate n'a pas pu tourner dans la sandbox — l'import de `backend.main` exige la cascade complète de dépendances du backend (frontmatter, snowballstemmer, …) ; à lancer par la CI / le coordinateur. Le rendu authentifié complet et la pastille inter-apps en conditions réelles restent à valider par Bruno après déploiement des 4 PR.
bruno added 5 commits 2026-10-28 12:13:36 -04:00
Author
Owner

Remplacée par la PR #41 (rebase sur main post-#70 : conflit frontend/index.html résolu en conservant la suppression du bouton ••• et du relais menu, bouton natif #header-menu-btn inchangé, ajouts #69 appliqués, contenu par ailleurs identique). Cette PR est fermée sans merge.

Remplacée par la PR #41 (rebase sur main post-#70 : conflit frontend/index.html résolu en conservant la suppression du bouton ••• et du relais menu, bouton natif #header-menu-btn inchangé, ajouts #69 appliqués, contenu par ailleurs identique). Cette PR est fermée sans merge.
bruno closed this pull request 2026-10-28 12:50:47 -04:00

Pull request closed

Please reopen this pull request to perform a merge.
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Projets/ObsiGate#39