From 0950e5c37568182966f563d83548a3ce17f783df Mon Sep 17 00:00:00 2001 From: Colin Maudry Date: Thu, 9 Jul 2026 16:15:10 +0200 Subject: [PATCH] =?UTF-8?q?docs(plan):=20plan=20d'impl=C3=A9mentation=20de?= =?UTF-8?q?=20la=20migration=20Dash=204.4=20(#101)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 --- .../plans/2026-07-09-migration-dash-4.md | 266 ++++++++++++++++++ 1 file changed, 266 insertions(+) create mode 100644 docs/superpowers/plans/2026-07-09-migration-dash-4.md diff --git a/docs/superpowers/plans/2026-07-09-migration-dash-4.md b/docs/superpowers/plans/2026-07-09-migration-dash-4.md new file mode 100644 index 0000000..065a4ce --- /dev/null +++ b/docs/superpowers/plans/2026-07-09-migration-dash-4.md @@ -0,0 +1,266 @@ +# Migration Dash 3.4 → 4.4 Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Faire passer l'application de `dash==3.4.0` à Dash 4.4.x sans changement fonctionnel, en acceptant le nouveau style des composants DCC. + +**Architecture:** Bump groupé des dépendances de l'écosystème Dash dans un worktree isolé basé sur `dev`, puis on laisse la suite de tests et le smoke test manuel révéler les cassures, qu'on corrige au fil de l'eau. Une seule PR vers `dev`. + +**Tech Stack:** Dash 4.4, `uv` (gestion des dépendances), pytest + Selenium (`dash[testing]`), `dash-leaflet` + `dash-extensions` (cartes), `dash-bootstrap-components`. + +**Spec de référence:** `docs/superpowers/specs/2026-07-09-migration-dash-4-design.md` + +## Global Constraints + +- **Base worktree :** créer le worktree depuis `dev` (PAS `origin/main`, qui est en retard sur `dev`). +- **Version cible :** `dash` épinglé en **exact** sur la dernière 4.4.x (style d'épinglage existant `dash==3.4.0`). +- **DataTable reste :** ne PAS toucher aux `dash_table.DataTable` ni à `src/figures.py`/`src/utils/table_sql.py` (relève de #41). +- **Régressions visuelles :** accepter le look Dash 4 ; ne corriger que les cassures fonctionnelles ; **retirer** le CSS custom en conflit plutôt que le patcher. +- **Bump libs tierces :** seulement si la compat Dash 4 l'exige. +- **Tests :** toujours via `uv run pytest` (l'activation du venv dans le shell n'est pas fiable ici). +- **Avant chaque commit :** exécuter `pre-commit` (ruff + prettier) — cf. CLAUDE.md. +- **Imports :** modules de l'app toujours préfixés `src.` (ne pas régresser vers `utils.`/`pages.`). + +--- + +### Task 1: Bump Dash et résoudre les dépendances (portail de compat) + +C'est le portail de risque : la résolution `uv` et le démarrage de l'app révèlent immédiatement toute incompatibilité de `dash-leaflet` / `dash-extensions` / `dbc` avec Dash 4. + +**Files:** + +- Modify: `pyproject.toml` (bloc `dependencies` et groupe `dev`) +- Modify: `uv.lock` (régénéré par `uv`) + +**Interfaces:** + +- Produces: environnement résolu sur Dash 4.4.x avec l'app qui démarre. Les tâches suivantes s'appuient sur cet état. + +- [ ] **Step 1: Déterminer la dernière version 4.4.x** + +Run: `uv run python -c "import urllib.request, json; d=json.load(urllib.request.urlopen('https://pypi.org/pypi/dash/json')); print([v for v in d['releases'] if v.startswith('4.4.')][-1])"` +Expected: une version type `4.4.x`. Noter cette valeur (ci-après ``). + +- [ ] **Step 2: Consolider la déclaration `dash` dans `pyproject.toml`** + +Dans le bloc `dependencies`, remplacer les DEUX lignes actuelles : + +```toml + "dash==3.4.0", + "dash[compress]", +``` + +par une seule ligne épinglée : + +```toml + "dash[compress]==", +``` + +Dans le groupe `[dependency-groups].dev`, remplacer : + +```toml + "dash[testing]", +``` + +par : + +```toml + "dash[testing]==", +``` + +- [ ] **Step 3: Résoudre l'environnement** + +Run: `uv sync` +Expected: résolution réussie. **Si** échec de résolution mentionnant `dash-leaflet`, `dash-extensions` ou `dash-bootstrap-components` (peer-deps React/Dash) : bumper la lib en cause vers sa dernière version (`uv add 'dash-leaflet@latest'` et/ou `uv add 'dash-extensions@latest'`) puis relancer `uv sync`. + +- [ ] **Step 4: Vérifier l'import et la version** + +Run: `uv run python -c "import dash, dash_leaflet, dash_extensions, dash_bootstrap_components as dbc; print(dash.__version__, dash_leaflet.__version__, dash_extensions.__version__, dbc.__version__)"` +Expected: `dash.__version__` commence par `4.4`, aucun ImportError. + +- [ ] **Step 5: Vérifier le démarrage de l'app** + +Run: `DEVELOPMENT=true uv run run.py` puis attendre le log de démarrage et arrêter (Ctrl-C). +Expected: l'app démarre sans traceback (le serveur écoute). Un warning de dépréciation sur `DataTable` est attendu et normal. + +- [ ] **Step 6: Commit** + +```bash +pre-commit run --files pyproject.toml || true +git add pyproject.toml uv.lock +git commit -m "build: bump dash 3.4 -> 4.4 et résolution des dépendances (#101)" +``` + +--- + +### Task 2: Rendre la suite de tests verte sur Dash 4 + +Le restyling DCC de Dash 4 peut casser des sélecteurs Selenium (classes CSS changées) ou des assertions. On fait passer toute la suite. + +**Files:** + +- Modify: fichiers de `tests/` dont les assertions/sélecteurs cassent (inconnus a priori) + +**Interfaces:** + +- Consumes: environnement Dash 4.4 de la Task 1. +- Produces: `uv run pytest` intégralement vert. + +- [ ] **Step 1: Lancer la suite complète pour cartographier les cassures** + +Run: `uv run pytest` +Expected: soit tout vert (idéal → aller directement au Step 4), soit des échecs. Noter chaque test en échec et sa cause (sélecteur introuvable, timeout, assertion). + +- [ ] **Step 2: Corriger chaque test en échec** + +Pour chaque échec, appliquer la correction minimale : + +- **Sélecteur Selenium cassé** (une classe/structure DCC a changé en Dash 4) : mettre à jour le sélecteur pour cibler la nouvelle structure rendue. Inspecter le DOM réel via `DEVELOPMENT=true uv run run.py` si besoin. +- **Assertion sur du texte/markup restylé** : ajuster l'attendu à la sortie Dash 4. +- **Ne PAS** contourner un échec qui révèle une vraie régression fonctionnelle : le noter pour la Task 3/4. + +- [ ] **Step 3: Relancer les tests corrigés** + +Run: `uv run pytest ` +Expected: PASS pour les tests corrigés. + +- [ ] **Step 4: Confirmer la suite complète** + +Run: `uv run pytest` +Expected: intégralement vert. + +- [ ] **Step 5: Commit** + +```bash +pre-commit run --files || true +git add tests/ +git commit -m "test: adapter la suite au rendu Dash 4 (#101)" +``` + +Si aucun test n'a nécessité de modification, ne pas créer de commit vide — passer directement à la Task 3. + +--- + +### Task 3: Vérifier le comportement des Dropdown et nettoyer le CSS en conflit + +Dash 4 change deux défauts de `dcc.Dropdown` (`optionHeight='auto'`, `closeOnSelect=False` en multi-select) et restyle les DCC. On vérifie les 11 Dropdown et on retire les overrides CSS devenus inutiles/cassants. + +**Files:** + +- Modify (si nécessaire) : `src/pages/recherche.py`, `src/pages/tableau.py`, et autres pages contenant des `dcc.Dropdown` +- Modify: `src/assets/css/style.css` (et autres fichiers de `src/assets/css/`) — retrait des overrides en conflit + +**Interfaces:** + +- Consumes: environnement Dash 4.4, suite verte (Tasks 1-2). +- Produces: Dropdown fonctionnels, CSS sans override cassant. + +- [ ] **Step 1: Lister les Dropdown et repérer ceux en multi-select** + +Run: `grep -rn "dcc.Dropdown" src/ | grep -v __pycache__` +Puis pour le contexte multi : `grep -rn "multi=True" src/ | grep -v __pycache__` +Expected: la liste des 11 emplacements ; identifier ceux en `multi=True` (impactés par le changement `closeOnSelect`). + +- [ ] **Step 2: Vérifier visuellement les Dropdown impactés** + +Run: `DEVELOPMENT=true uv run run.py` et ouvrir les pages concernées (notamment `/` recherche et `/tableau` filtres/sélecteur de colonnes). +Expected: les Dropdown s'ouvrent, filtrent, et se ferment correctement. Un multi-select qui reste ouvert après sélection est le nouveau défaut Dash 4 — **acceptable** (ne pas corriger sauf si réellement cassé). Ne corriger (ex. forcer `optionHeight` numérique) que si l'affichage est rompu. + +- [ ] **Step 3: Repérer les overrides CSS en conflit avec le restyling DCC** + +Run: `grep -rn "Select\|dropdown\|Checklist\|RadioItems\|dash-loading\|input" src/assets/css/` +Expected: liste des règles ciblant les DCC. Pour chacune, juger via le rendu (Step 2) si elle entre en conflit avec le nouveau style Dash 4. + +- [ ] **Step 4: Retirer les overrides devenus inutiles ou cassants** + +Supprimer (pas commenter) les règles CSS qui cassent ou déforment un composant DCC restylé. Conserver celles qui restent utiles et sans conflit. Ne PAS toucher au bloc CSS lié à `dash_table`/DataTable (hors périmètre, cf. `style.css:512`). + +- [ ] **Step 5: Re-vérifier le rendu après nettoyage** + +Run: `DEVELOPMENT=true uv run run.py` et re-parcourir les pages modifiées. +Expected: aucun composant cassé ; le rendu adopte le style Dash 4. + +- [ ] **Step 6: Commit** + +```bash +pre-commit run --files || true +git add src/ +git commit -m "style: accepter le rendu DCC Dash 4 et retirer le CSS en conflit (#101)" +``` + +Si aucune modification n'a été nécessaire, ne pas créer de commit vide. + +--- + +### Task 4: Smoke test complet et ouverture de la PR + +Vérification finale (definition of done) : suite verte + parcours manuel des 6 pages + cartes Leaflet + exports. + +**Files:** aucun a priori (corrections de dernière minute possibles selon findings). + +**Interfaces:** + +- Consumes: état des Tasks 1-3. +- Produces: PR vers `dev`. + +- [ ] **Step 1: Suite de tests finale** + +Run: `uv run pytest` +Expected: intégralement vert. + +- [ ] **Step 2: Smoke test manuel des 6 pages** + +Run: `DEVELOPMENT=true uv run run.py` et parcourir : `/` (recherche), `/acheteur`, `/titulaire`, `/tableau`, `/marche`, `/observatoire`. +Expected: chaque page se charge sans erreur console/serveur ; les tableaux DataTable s'affichent et filtrent ; les graphiques Plotly s'affichent. + +- [ ] **Step 3: Vérifier spécifiquement les cartes Leaflet et le clustering** + +Sur `/acheteur` et `/titulaire` (pages avec cartes), vérifier que la carte Leaflet s'affiche et que le clustering de marqueurs fonctionne (zoom/dézoom regroupe/éclate les marqueurs). +Expected: cartes rendues et interactives. **Si cassé** : bumper `dash-leaflet`/`dash-extensions` (cf. Task 1 Step 3), re-`uv sync`, re-tester, et amender le commit de la Task 1. + +- [ ] **Step 4: Vérifier les exports** + +Depuis `/tableau`, déclencher un export xlsx et un export csv. +Expected: fichiers téléchargés et ouvrables, contenu cohérent. + +- [ ] **Step 5: Corriger les cassures résiduelles éventuelles** + +Pour toute cassure trouvée aux Steps 2-4, appliquer la correction minimale et commiter séparément : + +```bash +pre-commit run --files || true +git add +git commit -m "fix: sur Dash 4 (#101)" +``` + +- [ ] **Step 6: Ouvrir la PR vers `dev`** + +```bash +git push -u origin +gh pr create --base dev --title "Migration Dash 3.4 → 4.4 (#101)" --body "$(cat <<'EOF' +Migration de `dash==3.4.0` vers Dash 4.4.x (pure montée de version, cf. spec `docs/superpowers/specs/2026-07-09-migration-dash-4-design.md`). + +## Périmètre +- Bump `dash` + libs écosystème si nécessaire +- Acceptation du look DCC Dash 4, retrait du CSS en conflit +- DataTable inchangées (→ #41), MCP hors périmètre (→ #111) + +## Vérification +- `uv run pytest` vert +- Smoke manuel : 6 pages + cartes Leaflet + exports xlsx/csv + +Closes #101 + +🤖 Generated with [Claude Code](https://claude.com/claude-code) +EOF +)" +``` + +Expected: PR créée vers `dev`. Le merge déclenchera l'auto-deploy vers test.colibre.fr. + +--- + +## Notes d'exécution + +- La migration est **réactive** : les Tasks 2-4 corrigent ce que le bump casse. Si le bump ne casse rien (plausible vu que les ruptures Dash 3.0 sont déjà absorbées), plusieurs tasks se réduisent à leur étape de vérification, sans commit. +- Le point de bascule risqué est concentré dans la Task 1 (résolution/boot) et la Task 4 Step 3 (cartes). En cas de blocage dur d'une lib tierce sans release Dash 4 : arrêter et réévaluer avec le mainteneur du plan.