Compare commits
9
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c9f7754f5f | ||
|
|
43e416a889 | ||
|
|
fefd9b1ad3 | ||
|
|
3b43be3761 | ||
|
|
972d40a75f | ||
|
|
fb942bc871 | ||
|
|
b8ebea1479 | ||
|
|
1e552a55a4 | ||
|
|
fd9df60788 |
@@ -1,3 +1,9 @@
|
||||
## v7.84.5 (2026-10-28) — Corrections console/recherche : texte parasite, onglets, CORS console
|
||||
|
||||
- **Barre (PR #37)** : suppression du texte parasite « Chantier 5 » rendu au-dessus du header.
|
||||
- **Recherche (PR #38)** : onglets visibles après déploiement (base console explicite + purge cache service worker).
|
||||
- **CORS recherche (PR #40)** : la recherche Flowdeck autorise désormais la console Spark (agent prod+dev) en inter-origines.
|
||||
|
||||
## v7.84.4 (2026-10-28) — Alignement recherche console : onglet Console Spark sur /api/v1/recherche
|
||||
|
||||
- **Recherche (#68)** : l'onglet Console Spark de `/recherche` appelle désormais `GET /api/v1/recherche` (au lieu de `/api/search`) et reconstruit les liens profonds console (`?section=…&objet=…`, `disc=`, `activite=`) — les résultats console réels s'affichent enfin dans la page hôte.
|
||||
|
||||
@@ -9,7 +9,10 @@ Ce module n'autorise donc que :
|
||||
- le chemin ``/api/search`` (jamais les autres routes, jamais les
|
||||
écritures) ;
|
||||
- les origines sœurs : les origines officielles **prod ET dev,
|
||||
listées explicitement** (``PROD_ORIGINS | DEV_ORIGINS``), **plus**
|
||||
listées explicitement** (``PROD_ORIGINS | DEV_ORIGINS``), **plus
|
||||
les origines de la console Spark** (``AGENT_ORIGINS`` : agent prod
|
||||
ET dev — fédération de la recherche depuis la console,
|
||||
2026-10-28), **plus**
|
||||
celles résolues par ``app.services.draco_urls.toutes()``
|
||||
(explicite > hôte > dérivation > défaut officiel) — jamais ``*``.
|
||||
Correctif 2026-10-28 (fusion #68/#69, matrice constatée par
|
||||
@@ -49,6 +52,12 @@ DEV_ORIGINS = frozenset({
|
||||
"https://kanbante-dev.dracodev.net",
|
||||
})
|
||||
|
||||
AGENT_ORIGINS = frozenset({
|
||||
"https://agent.dracodev.net",
|
||||
"https://agent-dev.dracodev.net",
|
||||
})
|
||||
|
||||
|
||||
# Clés de draco_urls.toutes() qui sont des applications sœurs.
|
||||
_SOEUR_KEYS = ("obsigate", "flowdeck", "tiktak", "kanbante")
|
||||
|
||||
@@ -113,7 +122,7 @@ def sister_origins(resolved: dict | None = None, request_host: str | None = None
|
||||
# l'environnement de la requête, désormais inclus d'office).
|
||||
# ``resolved`` n'ajoute que des origines de configuration sans
|
||||
# jamais retirer une origine officielle.
|
||||
origins |= PROD_ORIGINS | DEV_ORIGINS
|
||||
origins |= PROD_ORIGINS | DEV_ORIGINS | AGENT_ORIGINS
|
||||
return frozenset(origins)
|
||||
|
||||
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
CSS/JS : /static/css/draco-barre.css, /static/js/vendor/draco-barre.js.
|
||||
v7.82.0 (dev/prod) : les href des onglets ne sont plus figés —
|
||||
l'hôte les injecte depuis sa config (draco_urls(), noms officiels
|
||||
par défaut, noms en -dev déclarés dans le .env de l'environnement). #}
|
||||
Chantier 5 (fusion #69/#71, sans bump) : 5e onglet Console Spark
|
||||
(data-app="agent", draco_urls().agent), après Kanbante ; l'entrée
|
||||
« Console Spark » du menu de la marque est conservée.
|
||||
par défaut, noms en -dev déclarés dans le .env de l'environnement).
|
||||
5e onglet Console Spark (data-app="agent", draco_urls().agent),
|
||||
après Kanbante ; l'entrée « Console Spark » du menu de la marque
|
||||
est conservée (menu construit par draco-barre.js depuis les onglets). #}
|
||||
<link rel="stylesheet" href="/static/css/draco-alertes.css?v={{ asset_version }}">
|
||||
<header class="draco-bar" data-current="flowdeck">
|
||||
<div class="draco-bar-zone draco-bar-gauche">
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
"""Barre d'apps Flowdeck : aucun texte de chantier rendu hors commentaire.
|
||||
|
||||
Defaut 5 : les lignes « Chantier 5 (fusion #69/#71, sans bump) : ... »
|
||||
etaient placees APRES la fermeture `#}` du commentaire Jinja d'en-tete
|
||||
de `app/templates/_draco_bar.html` (lignes 9-11) : elles etaient donc
|
||||
rendues telles quelles, juste au-dessus du <header> de la barre, sur
|
||||
toutes les pages (la barre est incluse par base.html).
|
||||
|
||||
Test sans dependance (lecture du gabarit seul, comme
|
||||
test_draco_alertes.py) : il tourne sans serveur ni base, donc aussi
|
||||
en sandbox. La note documentaire peut vivre DANS le commentaire Jinja
|
||||
(jamais rendu) ; elle ne doit jamais en sortir.
|
||||
"""
|
||||
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
|
||||
|
||||
def _hors_commentaires(texte):
|
||||
"""Texte du gabarit sans les commentaires Jinja {# ... #}."""
|
||||
return re.sub(r"\{#.*?#\}", "", texte, flags=re.S)
|
||||
|
||||
|
||||
def test_aucun_texte_chantier_rendu():
|
||||
gabarit = (ROOT / "app/templates/_draco_bar.html").read_text()
|
||||
rendu = _hors_commentaires(gabarit)
|
||||
assert "Chantier 5 (fusion" not in rendu
|
||||
assert "sans bump" not in rendu
|
||||
# Aucune ligne de texte libre entre le commentaire d'en-tete et <link> :
|
||||
# le rendu doit commencer (apres commentaires) par <link> ou <header>.
|
||||
assert rendu.lstrip().startswith("<link")
|
||||
|
||||
|
||||
def test_barre_intacte_apres_suppression():
|
||||
"""Le 5e onglet Console Spark et la marque survivent a la suppression."""
|
||||
gabarit = (ROOT / "app/templates/_draco_bar.html").read_text()
|
||||
rendu = _hors_commentaires(gabarit)
|
||||
nav = rendu.split('<nav class="draco-apptabs"')[1].split("</nav>")[0]
|
||||
assert nav.index('data-app="kanbante"') < nav.index('data-app="agent"')
|
||||
assert "Console Spark" in nav
|
||||
assert 'data-app="agent"' in nav
|
||||
assert 'class="draco-brand"' in rendu
|
||||
# L'entree « Console Spark » du menu de la marque est construite par
|
||||
# draco-barre.js depuis les onglets : l'onglet agent suffit a l'alimenter.
|
||||
js_barre = (ROOT / "static/js/vendor/draco-barre.js").read_text()
|
||||
assert "Console Spark" in js_barre
|
||||
+16
-1
@@ -38,7 +38,7 @@ def test_origin_of():
|
||||
|
||||
|
||||
def test_sister_origins_dev():
|
||||
# Correctif 2026-10-28 : 8 origines officielles, prod ET dev,
|
||||
# Correctif 2026-10-28 : 10 origines officielles (8 sœurs + 2 agent), prod ET dev,
|
||||
# quelle que soit la résolution.
|
||||
assert sister_origins(RESOLVED_DEV) == {
|
||||
"https://og.dracodev.net",
|
||||
@@ -49,9 +49,24 @@ def test_sister_origins_dev():
|
||||
"https://flowdeck-dev.dracodev.net",
|
||||
"https://tiktak-dev.dracodev.net",
|
||||
"https://kanbante-dev.dracodev.net",
|
||||
"https://agent.dracodev.net",
|
||||
"https://agent-dev.dracodev.net",
|
||||
}
|
||||
|
||||
|
||||
|
||||
def test_cors_headers_agent_console_autorise():
|
||||
# Fédération depuis la console (2026-10-28) : les origines agent
|
||||
# prod ET dev passent, avec credentials ; un tiers reste refusé.
|
||||
for origine in ("https://agent.dracodev.net",
|
||||
"https://agent-dev.dracodev.net"):
|
||||
headers = cors_headers_for(origine, RESOLVED_DEV)
|
||||
assert headers is not None
|
||||
assert headers["Access-Control-Allow-Origin"] == origine
|
||||
assert headers["Access-Control-Allow-Credentials"] == "true"
|
||||
assert cors_headers_for("https://agent.dracodev.net.evil.example",
|
||||
RESOLVED_DEV) is None
|
||||
|
||||
def test_sister_origins_ajoute_env_de_la_requete():
|
||||
# Correctif 2026-10-28 : configuration muette, quel que soit
|
||||
# l'hôte de la requête, prod ET dev passent — l'hôte ne
|
||||
|
||||
Reference in New Issue
Block a user