Files
nav-carte/JOURNAL-V2.md
2026-05-14 06:05:48 +02:00

75 KiB
Raw Blame History

type, note_J8, project, created, status
type note_J8 project created status
journal Phase 8.G LIVREE 2026-05-14 - voir PILOTE-RAG-PE.md pour details NAV V2 2026-04-14 actif

NAV V2 — Journal de développement

Journal technique de la V2. Décisions, anomalies, points bloquants, TODOs.


2026-05-08 — Fix mobile + chatbot prod (cause racine résolue)

Commits : session loggée sur main (pushé sur gitea) Pattern : pilote direct, 2 batches successifs, ~3h, 11 fichiers

Cause racine bug "chatbot Carte 1 == Carte 2"

/api/chatbot-reseaux était 404 en prod (jamais déployé) — explique pourquoi 5 cycles de fix précédents (ChatbotReseaux.vue prop endpoint, useRoute fallback, useMarkdown direct, etc.) n'ont rien donné : le code source était correct depuis le début. Le rebuild + redeploy de cette session résout le bug.

Verif : curl -s -X POST https://aep.trans-former.fr/api/chatbot-reseaux → 200 + réponse distincte de /api/chatbot.

Batch 1 — fixes mobile principaux

  • Hamburger app.vue : ajout Jobs + Manifeste + Soutenir, ré-ordonnancement (Manifeste dans 2e groupe avec À propos/Soutenir/Signaler)
  • BandeauBas.vue : FAB cœur jaune mobile retiré (Soutenir migré dans hamburger via lien Liberapay direct)
  • agences.vue mobile : 3e onglet "Graphe" ajouté + masquage MobileSheet en mode graphe (canvas fullscreen)
  • a-propos.vue : section 1 "Mission" retirée (devient pop-up Carte 1) + overflow-x: hidden sur .apropos-page + retrait white-space: nowrap problématique sur .badge-detail
  • pages/manifeste.vue : nouvelle page (texte version manifeste-page-carto-V1.md, sans le diagramme ASCII pour V1 web)
  • components/MissionPopup.vue : nouveau composant générique (props title, ctaLabel, storageKey, slot pour contenu, :slotted() pour styles)
  • index.vue : intégration MissionPopup + bouton (i) position:fixed bottom-left + auto-show 1ère visite via localStorage.aep_mission_seen
  • trouver-du-taf.vue : toggle "Filtres [N] [chevron]" mobile-only (@media max-width: 767px) avec taff-filters-collapsible max-height transition
  • FicheModal.vue + FicheModalV2.vue : sur mobile top: 76px + max-height: calc(100dvh - 92px) au lieu de top: 50% translate(-50%, -50%) + max-height: 90vh qui mordait sur le header

Batch 2 — pop-up Carte 2, logo, intro Jobs, labels graphe

  • agences.vue : pop-up Réseaux AEP avec MissionPopup (storageKey aep_reseaux_seen, ctaLabel "Explorer les 120 réseaux") + bouton (i) flottant
  • app.vue logo header : badge AEP + 2 spans logo-line-1 ("Architecture") / logo-line-2 ("d'Écologie Politique") avec font-size responsive (0.7rem mobile → 0.85rem ≥1024)
  • trouver-du-taf.vue : <details class="taff-pedago" open> avec 3 blocs (deux onglets, trois étiquettes, cinq axes) + onglet "Plateformes B2C" → "Pour archi indépendants"
  • GraphView.vue : d3NodeSelection.filter(type==='structure').append('text') avec class graph-struct-label, dy: -(d.r + 5), font-size 9.5px, halo via paint-order: stroke; stroke: var(--nav-bg) (style global non-scoped pour piercer D3)

Bug d'opération à retenir

Lors du 1er déploiement batch 2, bash deploy.sh semblait OK (HTTP 200) mais le HTML en prod ne contenait pas les modifs. Cause : Dropbox sync a effacé .output/ entre npm run build et le tar SCP — le tar a uploadé un .output quasi-vide. Solution : 2e cycle clean (Remove-Item .nuxt/dist + .output) + rebuild + redeploy avec yes y | (skip confirm interactif .env diff).

Réflexe à intégrer : après build, vérifier grep -o "<un-fragment-de-modif>" .output/public/_nuxt/*.js | head AVANT le deploy. Si 0 match → ne pas deploy, rebuild.

Bug de communication à retenir

Jules a signalé "le logo n'a pas marché", "B2C pas renommé", "hamburger pas modifié" alors que le HTML en prod contenait bien les modifs (vérifié curl avec ?nc=$(date +%s)). Cause : cache navigateur / service worker Nuxt. Réflexe à mettre en place pour /done de toute session web : si Jules dit "ça n'apparaît pas", vérifier curl en bypass cache AVANT de chercher un bug. Si match curl → demander hard refresh (Ctrl+Shift+R).

Reste à faire (batch 3)

Voir 0 INBOX/PROMPTS/cascade-megaboum/REPRISE-aep-carto-fix-batch3.md :

  • Bouton "+" → sélecteur 3 cartes (Entraide/Réseaux/Jobs)
  • Pop-up explication 5 axes Jobs (paragraphe par axe)
  • Pop-up Carte 1 visibilité (option à clarifier avec Jules)
  • GraphView Carte 1 (centres = hashtags, couche échelle activable) — gros chantier session dédiée

2026-04-27 — Session V3 : Finition mobile + Blog Liberapay + 3 deploys

Commit : a02a555 — feat(mobile): accordéon outremer, hamburger nav, logo AEP, fiches cliquables, chatbot fullscreen Pattern : agents parallèles (3 × Sonnet) pour les 3 SSH indépendants — ~90s total vs ~20min séquentiel

Changements implémentés

B — OutremerMap.vue : accordéon vertical DOM-TOM

  • Template : row horizontale → accordéon <button> + v-show par territoire
  • Lazy-init Leaflet : initSingleMap(domName) appelé au 1er clic (plus de initMaps() en onMounted)
  • invalidateSize() sur ré-ouverture d'une carte déjà initialisée

E — app.vue : hamburger mobile

  • Bouton lg:hidden tout à droite de <!-- Actions droite -->
  • Dropdown v-if : 5 liens (/, /agences, /rag, /a-propos, /signaler)
  • z-index: 9999 en inline style sur le dropdown
  • watch(() => route.path) → ferme le menu à chaque navigation
  • Fix stacking context : header → relative z-[9999] (sans position, le z-index Tailwind n'avait pas d'effet → dropdown passait sous Leaflet)

F — app.vue : badge "A" → "AEP"

  • w-7 h-7h-7 px-2, text-smtext-xs tracking-tight

G — pages/index.vue : fiches ouvrables mobile

  • onSelectOrgMobile : ajout storeFiltersForBack() + router.push('/fiche/${id}')
  • NB : router.push était déjà là (modif pilote antérieure) — seul storeFiltersForBack ajouté

H — ChatbotSheet.vue : fullscreen + scroll lock iOS

  • 92dvh → 100dvh, border-radius: 16px 16px 0 0 → 0
  • definePropsconst props = defineProps (fix "can't find variable: props" en prod)
  • watch(props.modelValue) → lock document.body.style.overflow + document.documentElement.style.overflow
  • onUnmounted → cleanup overflow

A — Blog trans-former.fr : Liberapay retiré

  • VPS /opt/astro-site/src/layouts/PostLayout.astro : import + <DonateButton /> supprimés
  • Docker rebuild → 31 pages, HTTP 200

C — Website pro deploy

  • index.astro SCP → /opt/astro-pro/, Docker rebuild → 13 pages, HTTP 200

TODOs ouverts AEP

  • Valider visuellement les 8 fixes sur tel (Jules)
  • Pousser nav-carte sur Gitea (git.trans-former.fr/jules/nav-carte)

2026-04-15 — Session 5 : Corrections post Phase 2 (11 retours Jules)

Exécutant : Sonnet (agent autonome full auto) Durée : ~45min Commits : 7 commits atomiques (8ae4be3 → d30ee2c)

Retours implémentés

#1 — Barre de recherche

  • Desktop : supprimée du header (doublon avec sidebar NavSidebar.vue)
  • Mobile : ajoutée dans le header (app.vue, visible <lg)

#2 — Sheet swipable mobile

  • Nouveau composant MobileSheet.vue — 3 états : collapsed (56px) / half (50dvh) / full (92dvh)
  • Touch events natifs (pas de @vueuse/core — implémentation vanilla pour 0 dépendance)
  • Drag handle + cycle d'états au clic header + snap-back si delta < 60px
  • Vue mobile index.vue : carte pleine hauteur en fond + sheet en overlay
  • Décision d'exécution : vanilla touch events choisis vs useSwipe (pas installé)

#3 — Onglets header desktop

  • 3 onglets centrés remplacent la barre de recherche desktop : Écosystème / Agences Inspirantes / RAG
  • Active state via route.path + underline --nav-primary-solid
  • Badge "en construction" sous les 2 onglets inactifs

#4 — Supprimer "+ Ajouter carte"

  • Bouton retiré du header app.vue
  • Route pages/ajouter-carte.vue supprimée

#5 — Report/modif participatif via Resend

  • server/api/report.post.ts : rate limit 5/IP/jour, validation email + message, envoi Resend API
  • FicheDetail.vue : bouton "Signaler une erreur" → form inline dépliable (message + email, compteur 500 chars)
  • Email envoyé à jules@trans-former.fr (fallback Resend, pas NocoDB)

#6 — Texte intro commentaires

  • CommentSection.vue : intro italique avant la liste

#7 — DOM-TOM row horizontale pleine largeur (Option A)

  • OutremerMap.vue : layout row flex 5 colonnes égales, hauteur 140px
  • Desktop index.vue : layout vertical (Métropole flex-1 + DOM-TOM row 140px fixe en bas)
  • Suppression de l'encart 1/3 droit

#8 — Supprimer layer control carte

  • NavMap.vue : L.control.layers(...) supprimé, seul CartoDB Positron reste

#9 — Dark mode switch tuile

  • NavMap.vue + OutremerMap.vue : MutationObserver sur html.classListsetUrl() light_all/dark_all
  • Initialisation correcte dès le premier rendu (lire document.documentElement.classList)

#10 — Bandeau bas : logique inversée

  • BandeauBas.vue : isCollapsed = ref(true) par défaut
  • onMouseLeave : repli immédiat (suppression du timer 3s)
  • Opacité bandeau déployé : 70%

#11 — Bouton Soutenir recentré

  • bandeau-col--center : padding-top: 8px pour décaler vers le bas dans la hauteur du bandeau

Cleanup

  • Supprimés : TerritoireTabs.vue, TerritoireToggle.vue (composants morts)
  • Supprimée : pages/ajouter-carte.vue
  • Créées : pages/agences.vue, pages/rag.vue (placeholders)
  • Créé : components/MobileSheet.vue

Décisions d'exécution S5

  • #2 useSwipe : @vueuse/core absent du package.json — vanilla touch events choisis pour éviter d'ajouter une dépendance. Même résultat, 0 dép supplémentaire.
  • #5 NocoDB vs Resend : fallback Resend appliqué conformément aux décisions Jules pré-tranchées. Pas de table NocoDB créée.
  • DOM-TOM desktop : layout du index.vue passé de flex row (2/3 + 1/3) à flex col (Métropole flex-1 + DOM-TOM row 140px) pour intégrer l'Option A cohéremment.

Build & deploy

  • Build : npx nuxt build (223 modules client, 134 modules serveur)
  • Deploy : tar → SSH → systemctl restart nav-carte
  • Vérif : curl https://aep.trans-former.fr/ → 200, service active

2026-04-15 — Session 4 : Phase 2 UX (10 features)

Exécutant : Sonnet (agent délégué Opus) Durée : ~1h30

Réalisé

Feature 1 — Modal fiche sidebar desktop

  • Composant FicheModal.vue : overlay centré max-w-3xl (768px), 90vh scroll interne
  • Backdrop semi-transparent, fermeture Esc / clic backdrop / bouton croix
  • Lien "Ouvrir" → /fiche/[id] (URL partageable préservée)
  • Fetch $fetch('/api/fiche/X') avec watch sur orgId
  • onSelectOrg desktop (≥1024px) → ouvre modal
  • Mobile : comportement inchangé (navigation vers /fiche/[id])

Feature 2 — Fusion Outre-mer (suppression TerritoireTabs)

  • Desktop : layout flex flex:2 Métropole + flex:1 bandeau DOM-TOM (max 340px, OutremerMap réutilisé)
  • Mobile : section DOM-TOM scroll horizontal avec compteurs par territoire
  • TerritoireTabs retiré du template (composant conservé, non utilisé)

Feature 3 — CartoDB Positron + layer control + maxBounds

  • NavMap.vue : fond par défaut CartoDB Positron (light_all), layer control 3 fonds (Clair / Schématique Stamen / Standard OSM)
  • maxBounds France métr. [41-51.5°N, -5.5-10°E], minZoom: 5, maxZoom: 18
  • OutremerMap.vue : fond CartoDB Positron par défaut (sans layer control)

Feature 4 — Bandeau bas rétractable desktop

  • bg-opacity-80 (rgba 0.8)
  • Auto-collapse après 3s, déploie au hover ou mouvement souris < 80px du bas
  • Barre fine 32px en état rétracté avec label "AEP · Transparence IA"

Features 5+6 — Textes bandeau corrigés + lien Liberapay

  • "Coût IA ce mois : X.XX €" + "Tokens : X" (sans ratio budget)
  • Tooltip "1 € = 30 fiches mises en ligne" au hover bouton Soutenir
  • Lien Liberapay → https://liberapay.com/trans-former.fr/donate
  • Mobile : BandeauBas absent, remplacé par FAB coeur (gauche) → bottom sheet

Feature 7 — Logo AEP tooltip

  • Sous-titre "Architecture d'Écologie Politique" visible en lg:
  • Tooltip au hover pour sm: (sans le sous-titre)
  • Attribut title sur le lien pour accessibilité

Feature 8 — Header desktop refonte + barre de recherche

  • Barre de recherche ~500px centrée dans le header desktop (≥1024px)
  • Sync URL ?q= via watch, fonctionne depuis toutes les pages
  • Boutons "+ Proposer" et "+ Ajouter carte" en haut à droite
  • Route /ajouter-carte créée (placeholder)

Feature 9 — Dark mode

  • Toggle soleil/lune en top nav, persistance localStorage clé aep_theme
  • Variables CSS .dark dans main.css : fonds sombres, texte clair
  • Overrides Leaflet (popup, control layers)
  • Note : tuile CartoDB dark (dark_all) non switchée automatiquement — à améliorer en S5

Feature 10 — /a-propos CTA Contribuer + lien Liberapay

  • Section "Contribuer" existante améliorée (lien /donate)
  • Liens Liberapay unifiés sur /donate

Commits

Hash Message
46b6051 feat(aep-s4): CartoDB Positron + layer control + maxBounds France
3c036db feat(aep-s4): logo AEP + tooltip nom complet + dark mode toggle
775ec64 feat(aep-s4): dark mode CSS variables + Leaflet overrides
9736ba7 feat(aep-s4): bandeau bas — rétractable desktop + FAB mobile + textes corrigés
d092fd0 feat(aep-s4): /a-propos — liens Liberapay corrigés (/donate)
955a561 feat(aep-s4): page /ajouter-carte (placeholder bientôt disponible)
b406cc9 feat(aep-s4): fusion outremer — suppression TerritoireTabs + vue 2/3+1/3
2b43e90 feat(aep-s4): modal fiche sidebar desktop

Build & Deploy

  • npm run build : ✓ 2.84 MB bundle
  • Deploy VPS : ✓ systemctl is-active = active
  • curl -sI https://aep.trans-former.fr/ : HTTP/2 200

Points d'attention pour S5

  • Dark mode tuile Leaflet : switcher automatiquement vers dark_all CartoDB quand .dark est actif
  • BandeauBas détection mobile avec isMobile ref côté client : SSR safe (montage) mais risque blink. Envisager useWindowSize ou classe CSS média
  • TerritoireTabs et TerritoireToggle non utilisés → à archiver ou supprimer en S5
  • Barre de recherche header : sur les pages /fiche/[id] et /a-propos, la recherche navigue vers /?q=X — comportement acceptable mais pas élégant
  • Modal fiche : pas de CommentForm affiché côté SSR (correctement client-only via watch)

2026-04-14 — Session 3a : Chatbot API (Étape 5bis)

Exécutant : Sonnet (agent chatbot) Durée : ~30 min

Réalisé

ChatbotSheet.vue — Déjà complet (S2) : onboarding exact E-spec §Détails chatbot, bulles user/assistant, fiches recommandées avec lien, erreurs 429/503, animation slide-up mobile.

API POST /api/chatbot (nouveau) :

  • Rate limit : 10 req/IP/jour via rateLimitJson.ts (JSON + SHA-256 RGPD, spec F §8)
  • Circuit breaker : vérification budget 20€/mois via circuitBreaker.ts → HTTP 503 si dépassé
  • Keyword scoring : extraction mots-clés question → score sur nom+description+tags → top 20 fiches
  • Filtrage optionnel par fonction et echelle si fournis dans le body
  • Appel Mistral Small (mistral-small-latest, temp 0.3, max 600 tokens, json_object)
  • Parse JSON → { reponse_texte, fiches_recommandees: [{ id, nom, explication }] }
  • Log asynchrone stats_usage (non bloquant)

Helpers nouveaux :

  • server/utils/rateLimitJson.ts — fichier JSON par IP hashée SHA-256 dans /tmp/nav-ratelimit/
  • server/utils/circuitBreaker.ts — budget check NocoDB stats_usage + calcul coût Mistral Small/Nemo
  • nuxt.config.ts — ajout statsTableId (défaut mbbq7n47ixy19mc)

Décisions

Décision Détail
rateLimitJson vs Redis existant JSON fichier créé séparément (spec F §8 + RGPD SHA-256). Redis existant conservé pour submit/comment. Les deux coexistent.
Prompt Mistral Small Construit depuis E-spec-frontend.md §Détails chatbot — pas de prompt verbatim dans F-spec §3 (qui est Nemo enrichissement). Checkpoint Jules requis avant deploy prod.
circuitBreaker.ts Worker absent → créé dans server/utils/ (source unique, réutilisable par le futur worker)
statsTableId Défaut hardcodé mbbq7n47ixy19mc + env var STATS_TABLE_ID en override

Commits

  • 718e9f6 — feat(chatbot): API /api/chatbot + rate limit JSON SHA-256 + circuit breaker

Build

  • npm run build : ✓ sans erreur, 2.78 MB bundle

TODO avant deploy (S3b)

  • STATS_TABLE_ID=mbbq7n47ixy19mc/opt/nav-carte/.env (confirmer ou corriger l'ID)
  • Vérifier que /tmp/nav-ratelimit/ est accessible en écriture sur VPS (droits node)
  • Cron journalier reset /tmp/nav-ratelimit/ (0h UTC) → à ajouter en S3b
  • Tester chatbot 2-3 requêtes réelles sur VPS après deploy
  • Checkpoint Jules : valider prompt Mistral Small (construit, pas copié-collé de F-spec)

2026-04-14 — Session 2 Ajustements UX v3

Pilote : Sonnet
Durée : ~30 min

Réalisé

A) Search desktop déplacé top nav → sidebar (haut)

  • TopSearchBar retiré du header app.vue — top nav épuré (logo + Contribuer + Aléatoire)
  • Barre recherche inline ajoutée en haut de NavSidebar.vue : toujours visible, pleine largeur sidebar, styles scoped sidebar-search-*
  • Focus ring var(--nav-primary), bouton clear intégré
  • Mobile inchangé (search sticky bandeau entre filtres et liste)
  • URL sync ?q= conservé via pages/index.vue
  • Commit : 3f88e86

B) Chatbot desktop cliquable + expand/collapse

  • ChatbotPlaceholder.vue refactorisé : état replié (56px) → étendu (45vh) au clic
  • Header entier cliquable + chevron dédié avec rotation SVG 180° animée
  • transition: max-height 0.3s ease — animation fluide
  • Zone étendue : placeholder conversation S3, overflow-y auto
  • Mobile ChatbotSheet.vue inchangé
  • Commit : 88d0319

Build

  • npm run build clean (0 erreurs, 0 warnings TS)

2026-04-14 — Session 1 : Setup + Fondations

Pilote : Opus
Exécutants : Sonnet-1 (VPS/NocoDB), Sonnet-2 (seed parsing)
Durée estimée session : 4-5h

Décisions validées

Décision Détail Source
Palette A (sobre institutionnel) + bleu nuit #1a2238 à 60% opacité partout (bandeau, pins, chips, surlignages) Jules 2026-04-14
Texte Bleu plein pour titres/courant (lisibilité > esthétique) Déduction palette
Liberapay liberapay.com/trans-former.fr (pas nav-archi) Jules
Seed Bypass modération pour 94 fiches, 2-3 réservées pour test pipe IA (doc de la pipe → skill Mistral Nemo futur) Jules
Liberapay transparence Section dédiée dans /a-propos (étape 8), pas dans le bandeau Jules
Circuit breaker dépassé Bandeau "manque de fonds" + CTA Liberapay + pédagogie "1€ = N requêtes" + transparence origine Liberapay Jules
From email modération contact@trans-former.fr (existant Resend) Jules
Session stratégie 3 sessions dédiées (S1 fondations, S2 front, S3 IA+deploy) — préserve jauge Opus, use Sonnet pour exécution Jules
Tokens Mistral key stockée dans /opt/nav-carte/.env, jamais committée Standard

Réalisé

Sonnet-1 — Setup VPS + schéma NocoDB :

  • Token NocoDB nav-v2-worker créé : R-Yhd_0KgfW0ZjFxIl5iNyLS1ca7VpP8dNbo4OOa
  • /opt/nav-carte/.env créé (chmod 600) avec MISTRAL_API_KEY, NOCODB_TOKEN, NOCODB_BASE, NOCODB_TABLE_*, RESEND_FROM, NOCODB_URL
  • crawl4ai 0.8.6 installé via pip (--ignore-installed pour conflit lib rich)
  • Table organisations (m08t7g5v4wch6wb) étendue : 19 champs ajoutés
    • Contenus : url, description_user, description_enrichie, points_cles, localisation_ville, submitted_by_email, moderator_note, ai_raw_output, scrape_content
    • Taxonomie : echelle (SingleSelect), territoire (SingleSelect), tags_fonction (MultiSelect)
    • État : scrape_status, moderation_status, ai_processed (Checkbox)
    • Géo : latitude, longitude
    • Meta : submitted_at, moderated_at
  • Table stats_usage créée : mbbq7n47ixy19mc (model, endpoint, tokens_in/out, cout_eur, timestamp, orga_id)
  • Table scrape_queue skippée : F§2 n'en définit pas, la pipe utilise scrape_status sur organisations
  • Tests insert/update OK sur les deux tables avec nouveau token

Sonnet-2 — Parsing biblio + géocodage seed :

  • 93 entités parsées (A-biblio annonçait 94, erreur de comptage source)
  • 72 géocodées via Nominatim, 21 sans ville (lat/lon null, pas de fallback centre France pour éviter bruit carte)
  • Correction manuelle Saint-Ouen (93) vs Saint-Ouen-l'Aumône (Picardie)
  • 3 fiches réservées test pipe IA : CNOA, Archireport, Collectif Fil

Sonnet-3 — Re-tag + CROA + import NocoDB :

  • Re-tag : 32 Prospection → Développement, 17 RH → Gestion d'agence
  • Formation détecté et ajouté à 9 fiches (Réseau des MA, Cité de l'Archi, MAJ, CFAA, REFC'A, DU Dauphine, UNAID, FFP, Cité Archi Formation continue)
  • 13 CROA régionaux : 6 créés + 7 existants enrichis (tous avec "Gestion d'agence")
  • CNOA National isolé et réservé aux 3 fiches test pipe IA
  • 96 fiches importées dans NocoDB (99 v2 3 test pipe)
  • Apostrophe typographique U+2019 appliquée pour compat NocoDB
  • Anomalie : 8 anciens records V1 présents (IDs 1-8, moderation_status null) → à purger avant mise en prod

Anomalies & points à surveiller

  1. Taxonomie moderation_status — divergence F/G

    • F§2 définit : approved / rejected
    • G mentionne : published / approved
    • Front V1 existant utilise : approved
    • Décision Session 2 : rester sur approved/rejected partout, retirer published du prompt G si la doc est mise à jour. Le statut pending (avant modération) existe de fait comme absence de validation.
  2. Endpoint NocoDB 0.301.5

    • L'endpoint correct pour ajouter des colonnes est /api/v1/db/meta/tables/{id}/columns
    • L'endpoint /api/v2/meta/tables/{id}/fields n'existe PAS dans cette version
    • Le MCP nocodb n'était pas configuré avec la bonne URL de base → contournement direct par SSH + curl
    • TODO : reconfigurer le MCP nocodb pour qu'il pointe correctement (utile pour sessions futures)
  3. Disque VPS : 72,4% (était 69,8% avant install crawl4ai)

    • crawl4ai a pris ~2,6 GB
    • Hypothèse : Playwright + Chromium embarqué (crawl4ai utilise Playwright pour les pages JS)
    • Marge : OK pour Sessions 2-3. À surveiller quand on commencera à scraper et stocker du contenu dans scrape_content
    • Alternative si problème disque : remplacer crawl4ai par httpx + BeautifulSoup pour le scraping statique (bien plus léger, mais perd le rendu JS)
    • TODO : vérifier via du -sh le poids exact de crawl4ai et ses deps Playwright, décider si on garde ou on allège
  4. Conflit lib Python rich

    • Résolu avec pip install --ignore-installed
    • Risque : peut casser un autre outil Python VPS qui utilise rich (lightrag, formations, etc.)
    • TODO : vérifier que lightrag et autres services Python tournent toujours

Fichiers produits

  • /opt/nav-carte/.env (VPS, chmod 600)
  • Tables NocoDB : organisations étendue + stats_usage nouvelle
  • 0 INBOX/NAV-V2-recherches/palette-nav-v2.md — palette finale CSS
  • 0 INBOX/NAV-V2-recherches/palettes-preview.html — mockup validé
  • 0 INBOX/NAV-V2-recherches/seed-94-fiches.json (à produire par Sonnet-2)
  • 0 INBOX/NAV-V2-recherches/seed-94-rapport.md (à produire par Sonnet-2)

Prochaines étapes

  • Sonnet-2 finit le parsing + géocoding
  • Import seed NocoDB (bypass modération, 2-3 fiches réservées test pipe IA)
  • Rédaction des prompts Sessions 2 et 3 (livrable fin Session 1)

Taxonomie finale NAV V2 (validée 2026-04-14)

Échelle (3 niveaux) : National / Régional (inclut Départemental) / Local

Territoire : Métropole + 5 DOM-TOM (Guadeloupe, Martinique, Guyane, La Réunion, Mayotte)

Fonctions (10 tags, multi 1-5, ordre = priorité) :

  1. Juridique
  2. Technique
  3. Économique (strictement finance : aides, fiscalité, rentabilité, tarification)
  4. Administratif (démarches externes : permis, OA, déclarations)
  5. Chantier
  6. Comptabilité
  7. Développement (ex-Prospection — AO, concours, réseaux pro, acquisition clients)
  8. Formation (NOUVEAU — école, MOOC, organisme, formation continue)
  9. Gestion d'agence (ex-RH — élargi : RH + management + pilotage + orga interne)
  10. Santé mentale

Renommages appliqués :

  • Prospection → Développement
  • RH → Gestion d'agence (élargi)
  • Ajout : Formation

Cas particuliers :

  • CNOA → éclaté en 1 fiche National (siège Paris) + 13 fiches CROA Régional (préfectures de région)
  • Option 3 (antennes pins secondaires via champ multi-coords) → backlog V3

Points ouverts (à trancher en amont des prochaines sessions)

  • Session 2 : choix rate limit chatbot (fichier JSON vs Redis)
  • Session 3 : seuil email modération (N fiches en attente → envoi)
  • Facteur CO2eq : confirmer 0.052 kg CO2/kWh (RTE FR) ou utiliser valeur plus récente (ADEME 2024 ≈ 0.055)
  • Nominatim policy : user-agent NAV-V2/1.0 (contact@trans-former.fr) → OK ?
  • UX Session 2 : options échelle vides (Local) + onglet Outre-mer vide → afficher avec compteur "0" pour inviter à contribuer (cohérent esprit collaboratif)

Enrichissement DOM-TOM (post V2)

Session d'enrichissement à lancer après déploiement V2 :

  • Recherche ciblée par territoire (Guadeloupe, Martinique, Guyane, La Réunion, Mayotte)
  • Sources : CROA locaux, maisons de l'archi outre-mer, réseaux pro insulaires
  • Agent Sonnet-research 1-2h → complément seed

Piste externe : team.archi

Contacter le fondateur de team.archi (forum entraide archi) pour :

  • Lui présenter NAV V2 (esprit, périmètre)
  • Demander si team.archi documente d'autres réseaux d'entraide qu'on pourrait intégrer
  • Proposer un échange / listing mutuel

Brouillon email à préparer (requiert nom + email fondateur de Jules).



2026-04-14 — Session 2 : Front — Carte + Sidebar Filtres

Exécutant : Sonnet (agent) Durée : ~1h

Décisions prises

Décision Détail
Leaflet sans plugin Nuxt @nuxtjs/leaflet a une compat instable avec Nuxt 3.15 — import dynamique direct dans onMounted() + <ClientOnly> wrapper. Plus fiable, zéro config SSR à gérer.
Cluster seuil 15 (spec dit 15+) disableClusteringAtZoom: 14 — au-delà de zoom 14 les pins se défiltrent, cohérent avec la granularité ville/rue
@headlessui/vue installé mais non utilisé pour le drawer Le drawer implémenté en Vue natif (Teleport + transition) est plus léger et sans dépendance. @headlessui/vue reste disponible pour l'étape 3 (modales commentaires).
Seed JSON : Id fictif 1000+ Pour éviter collision avec les IDs NocoDB réels (1-96+). Les URLs /fiche/1000+ ne seront pas résolues en prod — comportement attendu en dev.
moderation_status=approved Confirmé — retirer published du filtre comme résolu en Session 1
Compteurs calculés sur orgs non filtrées Les (0) montrent les options sans aucune fiche dans la base totale, pas dans la sélection courante. Plus honnête vis-à-vis de l'invitation à contribuer.

Composants créés

  • NavMap.vue — Leaflet + OSM + clusters + pins personnalisés
  • EchelleFilter.vue — chips exclusifs National/Régional/Local
  • FonctionFilter.vue — multi-sélect 10 fonctions (max 5)
  • TerritoireToggle.vue — Métropole + 5 DOM-TOM sous-onglets
  • NavSidebar.vue — wrapper desktop
  • FilterDrawer.vue — drawer mobile (Teleport + transition Vue native)

Fichiers modifiés

  • assets/css/main.css — tokens CSS palette NAV V2 + surcharges Leaflet/clusters
  • tailwind.config.js — couleurs nav.* ajoutées
  • nuxt.config.ts — optimizeDeps Leaflet pour Vite
  • server/routes/api/organisations.get.ts — V2 champs + fallback seed JSON
  • pages/index.vue — refonte complète layout + filtres + URL sync

Commits Session 2

  • 64f5b0a — feat(deps): installer leaflet, markercluster, headless UI
  • dc849ef — feat(style): palette NAV V2 — tokens CSS + tailwind
  • 799d8fc — feat(api): GET /api/organisations V2 avec fallback seed JSON
  • 450a45c — feat(components): carte Leaflet + sidebar filtres (étape 2)
  • 3f486df — feat(page): index.vue V2 — carte + sidebar + URL sync

Validation build

  • npm run build : ✓ sans erreur, 2.09 MB bundle

Notes pour Sonnet 2 (étape 3 — fiche détail)

  • @headlessui/vue installé et disponible si besoin pour la modale commentaires
  • Interface Org définie dans pages/index.vue — à extraire dans types/org.ts si partagée (étape 3 en aura besoin)
  • Route API existante : GET /api/organisations/[id] dans server/routes/api/organisations/[id].get.ts — fonctionne, utiliser tel quel
  • Champ description_enrichie prévu mais absent du seed — prévoir fallback sur description
  • Champ points_cles : chaîne ou JSON array ? Vérifier dans NocoDB avant d'afficher

Notes pour Sonnet 3 (étape 6 — formulaire contribuer)

  • Route POST /api/organisations existe déjà en V1 (server/routes/api/organisations.post.ts) — à adapter pour V2 (nouveaux champs + moderation_status: pending)
  • Zod non encore installé — à ajouter dans package.json
  • Rate limit : trancher JSON simple (recommandé pour MVP) vs Redis

Points ouverts

  • 8 anciens records V1 (IDs 1-8, moderation_status null) à purger en prod
  • Vérifier type de points_cles dans NocoDB avant rendu fiche (string ou JSON)
  • Tester carte sur VPS avec données NocoDB réelles (96 fiches)


2026-04-14 — Session 2 (suite) : Spec définitive — Top nav + chatbot + filtres

Exécutant : Sonnet 2/3
Durée : ~1h

Décisions prises

Décision Détail
app.vue = layout global Refondu avec top nav (logo + TopSearchBar + Contribuer + Aléatoire). Supprime le header V1 (vert sage). NuxtPage prend le flex-1 restant.
Recherche top nav → URL ?q= TopSearchBar émet vers app.vue → router.replace ?q=. pages/index.vue watch route.query.q. Pas de prop passée via NuxtPage (non supporté simplement).
Sidebar sans recherche Input recherche retiré de NavSidebar — redondant avec top nav.
Sidebar sans chatbot Zone chatbot déplacée dans la zone carte (bas).
ChatbotPlaceholder sous carte Input désactivé 52px, fond --nav-bg. Présent sous Métropole ET Outre-mer.
Échelle multi-select (string[]) EchelleFilter + NavSidebar + FilterDrawer + pages/index.vue tous adaptés en string[]. Plus de string | null.
Fiche aléatoire ?random=1 dans l'URL → pages/index.vue redirige vers /fiche/[id] aléatoire.
shadcn Écarté — Vue+Tailwind+CSS scoped suffit, zéro complexité d'intégration.
Bonus "ouvrir chatbot" Skippé — pas de valeur avant S3.

Composants créés

  • TopSearchBar.vue — barre recherche animée (compact 44px → 280px au focus), CSS scoped
  • ChatbotPlaceholder.vue — zone bas carte, input désactivé, réserve espace S3

Composants modifiés

  • app.vue — refonte complète layout global (V1 sage vert → V2 bleu nuit)
  • pages/index.vue — supprime header dupliqué, intègre ChatbotPlaceholder, échelle string[]
  • EchelleFilter.vue — single-select → multi-select (string[])
  • NavSidebar.vue — supprime input recherche + zone chatbot, prop echelle string[]
  • FilterDrawer.vue — prop echelle string[], activeCount adapté

Commits Session 2 (suite)

  • 33fbd3b — feat(nav): top nav global avec barre de recherche animée
  • 1d5d9ab — feat(ux): chatbot placeholder sous la carte + sidebar sans chatbot
  • 905f338 — feat(filtres): échelle multi-select + sidebar sans recherche ni chatbot

Validation build

  • npm run build : ✓ sans erreur, 2.12 MB bundle

Points en attente / non implémentés

  • TerritoireTabs dans le drawer mobile — non dupliqué (à faire si besoin)
  • Fiche aléatoire nécessite que les orgs soient chargées — si orgs vides au moment du ?random=1, pas de redirect. Acceptable pour MVP.


2026-04-14 — Session 2 (Sonnet 2) : Fiche détail + Commentaires

Exécutant : Sonnet 2 (agent NAV V2) Durée : ~1h

Décisions prises

Décision Détail
types/org.ts Interface Org canonique extraite — suppression des 2 déclarations dupliquées dans index.vue et fiche/[id].vue
Route API dédiée GET /api/fiche/[id] dans server/api/fiche/ (distinct de server/routes/api/organisations/[id]) — meilleure séparation des responsabilités
Table commentaires commentTableId = COMMENT_TABLE_ID ?? AVIS_TABLE_ID (fallback table V1 si pas de table dédiée configurée)
Mistral Nemo timeout 2s via AbortController — fallback safe_check: 'pending' si timeout ou clé absente
Retour filtres sessionStorage nav_back_filters (pas de query param _back) — plus simple, pas de fuite dans URL partagée
mini-carte Leaflet non-interactif dans FicheDetail — zoom:10, dragging:false, toutes interactions désactivées
points_cles Tente JSON.parse d'abord, fallback découpage par lignes si format texte
Rate limit Redis Posé par Sonnet 3 — server/utils/rateLimit.ts avec fallback mémoire si Redis KO

Composants créés

  • components/FicheDetail.vue — affichage complet avec mini-carte Leaflet
  • components/CommentSection.vue — liste commentaires publiés + refresh prop
  • components/CommentForm.vue — formulaire soumission + gestion 429

Routes API créées

  • server/api/fiche/[id].get.ts — proxy NocoDB champs V2 complets
  • server/api/comment/index.post.ts — filtre éthique Mistral Nemo (timeout 2s, fallback pending)
  • server/api/comment/[orgId].get.ts — commentaires publiés triés chronologiquement

Fichiers modifiés

  • pages/fiche/[id].vue — refonte complète SSR (FicheDetail + CommentSection + CommentForm + SEO)
  • pages/index.vue — ajout storeFiltersForBack() pour sessionStorage + import type Org
  • types/org.ts — CRÉÉ : interface canonique V2
  • nuxt.config.ts — ajout mistralApiKey + commentTableId

Commits Session 2 (Sonnet 2)

  • a653336 — refactor(types): extraire interface Org canonique dans types/org.ts
  • 89bd22a — feat(api): GET /api/fiche/[id] + POST/GET /api/comment avec filtre Mistral Nemo
  • 06c44cd — feat(components): FicheDetail + CommentSection + CommentForm
  • 420f534 — feat(page): /fiche/[id] SSR complète — FicheDetail + comments + SEO + retour filtres

Validation build

  • npm run build : ✓ sans erreur, 2.74 MB bundle

Coordination Sonnet 3 (rate limit Redis)

Posé par Sonnet 3 : server/utils/rateLimit.ts (ioredis + fallback mémoire) importé dans POST /api/comment. Sonnet 3 a modifié server/api/comment/index.post.ts pour brancher checkRateLimit(ip, 'comment', 5). Configuration : REDIS_URL dans .env, fallback mémoire si Redis KO (dev sans Docker).

Points ouverts pour Session 3

  • public/og-default.png à créer (logo par défaut pour og:image) — actuellement référencé, pas encore créé
  • COMMENT_TABLE_ID à ajouter dans .env VPS si table dédiée à part de AVIS_TABLE_ID
  • MISTRAL_API_KEY à vérifier dans /opt/nav-carte/.env — la clé est dans le .env VPS (Session 1), juste s'assurer du nom de variable exact
  • Vérifier type de points_cles dans NocoDB (JSON array stringifié ou texte brut ?)
  • Tester sur VPS avec données NocoDB réelles (96 fiches seed)

2026-04-14 — Session 2 (parallèle) : Étape 6 — Formulaire /contribuer + Redis rate limit

Exécutant : Sonnet 3 (agent)

Redis VPS

  • redis-server absent au départ (pas mentionné dans VPS-check.md)
  • Installé : apt-get install redis-serversystemctl enable + start
  • Bind : 127.0.0.1 -::1 uniquement (localhost, sécurisé)
  • Test : redis-cli ping → PONG ✓
  • En prod : ajouter REDIS_URL=redis://127.0.0.1:6379 dans /opt/nav-carte/.env
  • En dev local : fallback compteur en mémoire (ioredis lazyConnect — pas de crash si Redis absent)

Fichiers produits

Fichier Description
server/utils/rateLimit.ts Helper Redis générique — checkRateLimit(ip, action, maxPerDay) avec fallback mémoire
server/api/submit/index.post.ts POST /api/submit — Zod + Nominatim + NocoDB pending + rate limit 3/IP/j
server/api/comment/index.post.ts Rate limit Redis 5/IP/j ajouté en tête (base Sonnet 2)
pages/contribuer.vue Page dédiée — 8 champs, validation Zod client+serveur, 422/429, succès + trackingUrl

Décisions

Décision Détail
Page vs modal Page dédiée /contribuer — plus simple pour MVP. Route duale desktop (redirect ?contribute=1 + modale) en backlog V2.1
description_user K-prompt (50-500) > E-spec (20-200) — tranché : 50-500 chars
Champ ville Optionnel (K-prompt) — moins de friction, fallback fiche sans coords prévu
NOCODB_BASE_ID Valeur fallback p_nav_v2 dans le code. À confirmer : ssh vps-hetzner "grep -i base /opt/nav-carte/.env"

Rate limits posés (Redis)

  • /api/submit : 3 soumissions / IP / jour
  • /api/comment : 5 commentaires / IP / jour

Commits

  • d9b6a31 — feat(deps): ajouter zod + ioredis + REDIS_URL runtime config
  • e81625f — feat(server): helper rate limit Redis avec fallback mémoire
  • 5c24c06 — feat(api): POST /api/submit — validation Zod + geocoding + NocoDB pending
  • fc0c52c — feat(page): /contribuer — formulaire V2 Zod client + UX mobile-first
  • (rate limit /api/comment dans commit Sonnet 2 420f534)

Build

  • npm run build : ✓ sans erreur, 2.74 MB bundle

TODO avant prod

  • REDIS_URL=redis://127.0.0.1:6379/opt/nav-carte/.env (VPS)
  • Confirmer NOCODB_BASE_ID : ssh vps-hetzner "grep -i base /opt/nav-carte/.env"
  • Tester submit valide → fiche pending dans NocoDB
  • Tester 4ème submit → vérifier HTTP 429

2026-04-14 — Session 2 (Étape 2) : Mobile UX

Exécutant : Sonnet 1.8 (agent NAV V2 Mobile) Durée : ~1h

Décisions prises

Décision Détail
FilterDrawer supprimé L'ancien drawer filtres (bouton flottant gauche, slide depuis gauche) est supprimé. Les filtres sont désormais inline dans le flow mobile.
ChatbotSheet nouveau composant ChatbotSheet.vue — bottom sheet plein écran, Teleport + transition slide-up, 92dvh, input désactivé (S3), fermeture backdrop + bouton Retour.
Carte mobile 45dvh height: 45dvh sur mobile, min-height: 180px. dvh pour éviter le bug clavier mobile.
Tagging compact inline Bandeau entre carte et liste : échelle 3 checkboxes 16px avec labels courts (Nat/Rég/Loc) + fonctions scroll horizontal overflow-x: auto.
Tap card → centre carte onSelectOrgMobileselectedId change → NavMap.vue réagit via watch selectedId → mapInstance.panTo.
Bouton chatbot flottant 56×56px, bottom: 1.5rem; right: 1rem, opacity: 0.88, z-[1000], lg:hidden.
Multi-Leaflet Outre-mer Grille 5 mini-cartes existante conservée — build clean, à tester en conditions réelles.
Poignée draggable Skippé — estimé > 30 min, noté pour Session 3.
Interface Org Sonnet 2 a extrait types/org.ts, linter auto-appliqué l'import dans pages/index.vue.

Composants créés

  • ChatbotSheet.vue — bottom sheet chatbot plein écran (92dvh, slide-up, backdrop, poignée visuelle, input désactivé)

Composants supprimés

  • FilterDrawer.vue — drawer filtres mobile (remplacé par tagging inline + ChatbotSheet)

Fichiers modifiés

  • pages/index.vue — refonte complète zone mobile + bouton chatbot flottant + ChatbotSheet

Commits Session 2 (Mobile)

  • d39e7be — feat(mobile): ChatbotSheet — bottom sheet plein écran avec animation slide-up
  • 0843301 — feat(mobile): supprimer FilterDrawer — remplacé par tagging inline + ChatbotSheet
  • pages/index.vue — inclus dans refacto Sonnet 2 (a653336 → import types/org.ts)

Validation build

  • npm run build : ✓ sans erreur, 2.12 MB bundle

Backlog mobile S3

  • Poignée draggable entre carte et liste (drag resize)
  • Multi-Leaflet Outre-mer mobile à tester en conditions réelles → fallback dropdown si trop lourd
  • Animation léger zoom pin au tap card (spec F)
  • Chatbot IA branché (Session 3)


2026-04-14 — Session S2 Ajustements finaux v2 (correctif branding + polish)

Exécutant : Sonnet 1.9b (agent AEP V2)

Contexte

L'agent précédent avait commis une erreur de spec sur le renommage : "NAV" avait été remplacé par "Écosystème Architecture" dans les textes visibles. La bonne règle est : "NAV" (texte visible) → "AEP" (Architecture d'Écologie Politique).

Corrections branding (commit fix)

Fichier Avant Après
app.vue logo icône N A
app.vue logo texte Écosystème Archi. AEP
components/ChatbotSheet.vue aria-label="Assistant Écosystème Architecture" aria-label="Assistant AEP"
pages/index.vue SEO title Écosystème Architecture — Cartographie AEP AEP — Cartographie de l'écologie politique architecturale
pages/contribuer.vue SEO title Proposer une ressource — Écosystème Architecture Proposer une ressource — AEP
pages/ajouter.vue SEO title Proposer une fiche — Écosystème Architecture Proposer une fiche — AEP
pages/fiche/[id].vue og:description fallback Fiche organisation — NAV Architectes Fiche organisation — AEP
pages/fiche/[id].vue SEO title {nom} — NAV {nom} — AEP
pages/fiche/[id].vue og:title {nom} — NAV Architectes {nom} — AEP

Ajustements complémentaires

  • Bouton flottant mobile : icône seule → pill avec texte "Chatbot" visible (48px h, gap-2, font-weight 600)

État des 4 ajustements spec

# Ajustement État
1 Échelle inline 1 ligne ✓ Fait par agent précédent (EchelleFilter.vue flex-wrap gap-x-4)
2 NAV → AEP (textes visibles) ✓ Corrigé dans ce commit
3 Mobile search au-dessus liste ✓ Fait par agent précédent (lignes 167-203 pages/index.vue)
4 Bouton mobile "Chatbot" ✓ Fait dans ce commit (pill avec label visible)

Build

  • npm run build : ✓ sans erreur, 2.74 MB bundle

2026-04-14 — Session 3 : Chatbot IA (Étape 5bis)

Pilote : Opus Exécutant : agent Sonnet S3 Durée : ~1h

Réalisé

ChatbotSheet.vue (mobile) — refactorisé :

  • Conversation IA complète : messages user/assistant, scroll auto, loading dots
  • Message onboarding exact (texte E §6) affiché avant la première question
  • Bulles fiches recommandées : card compacte avec lien /fiche/[id] + explication
  • Erreurs typées : 429 (rate limit), 503 (budget épuisé), fallback générique
  • Emit highlightOrgs pour highlight carte
  • Animations slide-up + prefers-reduced-motion respecté

ChatbotPlaceholder.vue (desktop) — refactorisé :

  • Même conversation IA que le mobile, format panneau latéral expand/collapse
  • Même onboarding, mêmes bulles fiches, même gestion d'erreurs
  • Input en bas du panneau étendu, Enter pour envoyer

server/api/chatbot/index.post.ts — créé :

  • Rate limit : checkRateLimit(ip, 'chatbot', 10) via helper Redis S2 existant
  • Circuit breaker : lecture cumul stats_usage mois courant, 503 si ≥ 20€
  • Fetch top-20 fiches NocoDB (moderation_status=approved) avec scoring keyword
  • Contexte JSON compact injecté dans le prompt système Mistral Small
  • Appel mistral-small-latest (temperature: 0.3, max_tokens: 600, json_object)
  • Parse JSON → { reponse_texte, fiches_recommandees }
  • Log stats_usage (fire and forget)

Décisions

Décision Détail
Rate limit helper Réutilisation du helper Redis S2 (checkRateLimit) — plus robuste que JSON fichier /tmp. Comportement identique (10 req/j).
STATS_TABLE_ID env Valeur par défaut mbbq7n47ixy19mc (créé en S1) — override via env si besoin
Scoring fiches Keyword match sur nom + description + tags — suffisant pour MVP, pas de vector search
prefers-reduced-motion Animations supprimées si l'utilisateur a activé ce préfé navigateur

Build

  • npm run build : ✓ sans erreur, 2.78 MB bundle

Commits Session 3 (étape 5bis)

  • feat(chatbot): ChatbotSheet mobile + ChatbotPlaceholder desktop — conversation IA branchée
  • feat(api): POST /api/chatbot — Mistral Small + rate limit + circuit breaker

TODO avant prod

  • Vérifier STATS_TABLE_ID dans /opt/nav-carte/.env (valeur par défaut : mbbq7n47ixy19mc)
  • Tester 2-3 requêtes réelles sur VPS avec fiches NocoDB
  • Vérifier index.vue passe bien highlightOrgs au NavMap depuis ChatbotSheet et ChatbotPlaceholder
  • Tester mobile iOS Safari + Android Chrome


2026-04-14 — Session 3 (Étapes 4-5) : Worker IA + Test pipeline

Exécutant : Sonnet (agent) Durée : ~2h

Réalisé

Étape 4 — Worker enrichissement IA :

  • worker/enrich.js créé (Node.js ESM, systemd timer 5 min)
  • Pipeline complet : fetch pending → scrape crawl4ai → Mistral Nemo → update NocoDB → log stats_usage
  • Circuit breaker budget 20€ (filtre JS, car NocoDB v0.301.5 rejette les filtres datetime)
  • Email Jules via Resend si seuil 5 fiches pending en modération
  • Lock anti-overlap via /tmp/nav-worker.lock
  • Retry 2x sur erreur Mistral + flag ai_error si 3 échecs

Infrastructure :

  • worker/package.json + node_modules/dotenv installés
  • Variables RESEND_API_KEY, EMAIL_JULES, BUDGET_MAX_EUR, WORKER_LIMIT ajoutées au .env
  • nav-worker.service + nav-worker.timer systemd créés et activés

Étape 5 — Test pipeline sur 3 fiches :

  • 3 fiches injectées en NocoDB (CNOA Id=106, Archireport Id=107, Collectif Fil Id=108)
  • Checkpoint 1 fiche (CNOA) : €0.000029, extrapolé 96 fiches = €0.0028 → GO
  • 3 fiches enrichies avec succès

Métriques pipeline

Fiche tokens_in tokens_out cout_eur Temps Confiance
CNOA 1 248 167 €0.000029 3.0s haute
Archireport 4 376 261 €0.000091 3.9s haute
Collectif Fil 2 628 221 €0.000057 4.3s haute
Total 8 252 649 €0.000177 11.2s

Extrapolation 96 fiches : €0.0057 (budget 20€ = 3 500× la consommation réelle)

Problèmes résolus

Problème Solution
Playwright absent → crawl4ai crash AsyncHTTPCrawlerStrategy (mode statique)
NocoDB rejette filtres datetime Filtre JS sur tous les records stats_usage
Apostrophe U+0027 dans tags refusée U+2019 (typographique) partout dans VALID_FONCTIONS
import dynamique ESM incompatible spawnSync importé statiquement

Décisions prises en autonomie

Décision Raison
AsyncHTTPCrawlerStrategy au lieu d'AsyncWebCrawler standard Playwright non installé sur VPS, mode statique suffisant pour sites archi
Filtre budget JS (pas NocoDB) API NocoDB 0.301.5 ne supporte pas les filtres de date en mode gte
spawnSync pour appel Python Évite les complications d'import dynamique en ESM

Fichiers produits

  • /opt/nav-carte/worker/enrich.js — Worker IA principal
  • /opt/nav-carte/worker/package.json — Dépendances (dotenv)
  • /etc/systemd/system/nav-worker.service — Service oneshot
  • /etc/systemd/system/nav-worker.timer — Timer 5 min
  • nav-carte/PIPE-IA-DOC.md — Documentation complète pipeline + résultats

TODO avant deploy prod (Étape 9)

  • Chatbot (Étape 5bis) — non implémenté dans cette session
  • Bandeau bas + Liberapay (Étape 7) — non implémenté
  • Page /a-propos (Étape 8) — non implémenté
  • Deploy git sur VPS + build Nuxt production
  • Purger 8 anciens records V1 (IDs 1-8, moderation_status null) avant prod
  • Tester worker sur soumission réelle via /contribuer
  • Vérifier que les 3 fiches test (Ids 106-108) sont modérées ou purgées avant prod (sont en mode test)


Session 3b — Deploy final AEP (2026-04-14 soir)

Durée : ~3h · Résultat : AEP V2 live sur aep.trans-former.fr + nav.trans-former.fr (alias)

Dispatch

# Action Modèle Status
A Prompt système chatbot Mistral Small Opus + Jules
B Composant BandeauBas.vue + endpoint /api/stats Sonnet
C Page /a-propos (brouillon — texte à réécrire par Jules) Sonnet
D Cron purge /tmp/nav-ratelimit/ (systemd timer quotidien 03:00 UTC) Sonnet
E Enrichissement rétro 96 fiches (worker IA Mistral Nemo) Sonnet
F DNS OVH + Caddy alias + build + deploy + tests HTTPS Opus + Jules

Décisions tranchées

Décision Choix Raison
Domaine V2 aep.trans-former.fr nouveau + alias nav.* Pas de V1 figée réelle à préserver : le VPS servait déjà la V2
Structure Caddy Alias simple (2 domaines → même service :3333) Éviter 2 instances Node pour un code identique
Prompt chatbot "AEP — Écosystème Entraide", posture engagée, règle hors-scope Cohérent avec positionnement AEP vs terminologie NAV résiduelle
Rate limit chatbot JSON SHA-256 (RGPD) — Redis retiré Volume borné par circuit breaker, pas besoin de Redis
Enrichissement rétro Bulk patch pending → worker → bulk approve API Spot-check qualité accepté, tags à corriger en modération manuelle

Commits

74c9722 feat(aep-s3b): bandeau transparence + /a-propos + cron purge rate-limit
68e1e53 fix(chatbot): purge version Redis + prompt système AEP

Enrichissement IA — bilan qualité

  • Coût réel : €0.006 pour 96 fiches (×3 300 sous le seuil €20/mois)
  • Descriptions : factuellement correctes (spot-check 10 fiches OK)
  • Tags : 6/10 vides sur Maisons de l'Architecture (mapping ne matche pas "expositions/conférences"), 1 sur-tagging MAOP Id 11 (10/10 tags — site généraliste scraped), MAF Id 15 manque "Juridique"
  • Action Jules : correction manuelle tags dans NocoDB UI (non bloquant pour deploy)

Découverte imprévue — bug deploy.sh

Incohérence entre deploy.sh (rsync vers /opt/nav-carte/) et nav-carte.service (exec /opt/nav-carte/.output/server/index.mjs). Le deploy.sh écrit au mauvais endroit — le service tourne sur .output/ qui n'est jamais mis à jour par le script. Contournement cette session : tar + ssh extract manuel dans .output/. À patcher en V3 : aligner deploy.sh sur la structure .output/.

État à la clôture

✓ aep.trans-former.fr — HTTPS 200 (/, /a-propos, /api/stats)
✓ nav.trans-former.fr — alias OK
✓ 99 fiches approved (96 enrichies + 3 S3a)
✓ Bandeau bas + chatbot + lien À propos intégrés
✓ Cron purge rate-limit actif (prochaine exécution 2026-04-15 03:00 UTC)
✓ V1 Redis chatbot purgée

TODO post-session (Jules, async)

  • Réécrire le texte de pages/a-propos.vue (placeholders <!-- TODO Jules --> en tête de chaque section)
  • Corriger tags Maisons de l'Architecture + MAOP + MAF dans NocoDB UI
  • Tests manuels : submit /contribuer, chatbot mobile (iOS + Android), feedback UX
  • Patcher deploy.sh pour cibler /opt/nav-carte/.output/ (voir découverte ci-dessus)
  • Vérifier widget Liberapay à liberapay.com/trans-former.fr — compte existe ?

Backlog V3 (hors scope V2)

Infra / deploy

  • Fix deploy.sh — cible /opt/nav-carte/.output/ pas /opt/nav-carte/ (incohérence découverte en S3b)
  • Migration /opt/nav-carte//opt/aep/ — alignement nom projet (dette terminologique NAV)
  • Rebrand service systemd nav-carte.serviceaep.service (low-priority)
  • Monitoring — sonde Uptime Kuma (status.trans-former.fr) : ajouter aep.*/api/stats
  • Backup NocoDB — dump quotidien base pipilvsi7dibo80 vers stockage externe

Produit / UX

  • Tags auto — améliorer le mapping worker pour matcher "expositions/conférences/culture" → Développement + Formation (évite tags vides sur MA)
  • Modération UI custom — interface dédiée pour batch approve/reject (au lieu de cliquer 96 rows)
  • Sidebar "Fiches récemment ajoutées" — boost engagement
  • Recherche sémantique chatbot — passer de keyword match à embeddings (Mistral Embed, volume à estimer)
  • Page /transparence publique — détail coûts, CO2, donateurs Liberapay

Éditorial

  • Contenu /a-propos — texte politique écrit par Jules seul (hors scope IA)
  • Badge IA souveraine — vérifier formulation (Hetzner = Falkenstein DE, pas FR — dire "Hébergé en Europe" ?)
  • Page Contribuer — modération visible — expliquer pipeline "formulaire → worker IA → modération humaine"

Monétisation / association

  • Bascule Liberapay → HelloAsso quand ASO créée (scénario 2 du doc C-systeme-dons.md)
  • Widget Liberapay "total collecté" — actuellement juste CTA, ajouter feedback

Technique

  • Caching API organisations — actuellement re-fetch NocoDB à chaque render
  • Full-text search côté client — Fuse.js sur descriptions enrichies
  • Mode offline / PWA — manifest + service worker pour usage terrain

Décisions structurantes (mémoire profonde)

Archive des décisions structurantes du projet nav-carte (AEP V1/V2/Codev/Carte 3), déchargée hebdo depuis coordo-agent-dev. Tri chronologique inverse (plus récent en haut). Copies verbatim, pas de reformulation.

2026-W19 (décharge 2026-05-13)

  • [W19 — 2026-05-08 19:21] AEP nav-carte fix mobile batch1+2 LIVE + cause racine chatbot Carte1=Carte2 résolue (~3h pilote direct, 2 batches successifs, 11 fichiers). Cause racine identifiée après 5 cycles de fix précédents infructueux : /api/chatbot-reseaux était 404 en prod (jamais déployé). Le code source nav-carte était correct depuis le début. Rebuild + redeploy = bug résolu (vérifié curl POST sur les 2 endpoints, réponses distinctes). Batch 1 : hamburger refondu (Jobs/Manifeste/Soutenir), FAB cœur jaune retiré, 3e onglet Graphe mobile sur agences, /a-propos refondue + scroll latéral fixé, page /manifeste créée (texte version page-carto-V1), MissionPopup générique avec slot/props (storageKey, title, ctaLabel) auto-show 1ère visite, filtres Jobs mobile repliables (toggle "Filtres [N]"), FicheModal/V2 décalage top:76px mobile pour ne plus mordre header. Batch 2 : pop-up Carte 2 Réseaux AEP, logo header Architecture d'Écologie Politique en clair sur 2 lignes (logo-line-1/2 responsive), onglet "Plateformes B2C" → "Pour archi indépendants", intro pédagogique repliable Jobs (2 onglets / 3 tags / 5 axes éthiques), labels noms structures sur GraphView (D3 append text + halo via paint-order: stroke). Pattern d'opération critique découvert : Dropbox sync efface .output entre npm run build et tar | ssh du deploy.sh — 1er deploy batch 2 a uploadé un .output quasi-vide sans erreur visible (HTTP 200 trompeur). Réflexe : grep "fragment-modif" .output/public/_nuxt/*.js | head AVANT deploy. Pattern de communication : Jules a signalé "modifs pas faites" alors que HTML prod contenait bien les modifs (vérifié curl) — cache navigateur / service worker. Réflexe : si "ça apparaît pas", curl bypass cache AVANT chercher bug, puis demander hard refresh. Git : commit propre + push gitea/main (yes y | bash deploy.sh pour skip confirm interactif .env diff). Prompt batch 3 dans 0 INBOX/PROMPTS/cascade-megaboum/REPRISE-aep-carto-fix-batch3.md.

  • [W19 — 2026-05-07 17:18] AEP Carte 3 "Trouver du taf" — T2 scoring 5 axes + T3/T4 LIVE : 24 plateformes scorées (7/14⚠️/3), plateformes-taff.json prod, page /trouver-du-taf complète (filtres, grille 1 col, modal fiche, chatbot FAB Guide IA). Endpoints /api/chatbot-taff (import JSON statique + Mistral Small) + /api/chatbot-reseaux (keyword search 120 structures). ChatbotReseaux.vue créé (standalone Carte 2). useMarkdown.ts inline styles CSS-free. Onglet Jobs nav desktop. Bug dev : cache .nuxt corrompu par agent concurrent → bat rmdir+délai 12s. Chatbot séparation + markdown à vérifier en PROD (pas dev). Menu hamburger mobile Jobs manquant. Branche main.

  • [W19 — 2026-05-07 01:11] Codev MVP LIVRÉ en prod — cascade M1→M5 complète (5 agents Sonnet), merge feat/codev-mvp→main, push Gitea. App entraide /codev live avec lock screen, formulaire, graphe D3 force-directed, annuaire table sticky, 2 modes matching (Solution tokenize direct + Alliance Jaccard), mode admin (DELETE fiche), QR code public, panel mobile bottom sheet. Décision build : TOUJOURS depuis C:\tmp\nav-build (Dropbox corrompt cache Vite = 500 prod). Algo fix critique : Solution compare textes besoin↔offre directement (ignore hashtags), évite que les 3 modes donnent le même graphe.

  • [W19 — 2026-05-06 17:11] MP-TAFF T1b scraping compléments DONE — BrowserMCP utilisé pour débloquer Trustpilot (7 pages) + instao.fr + francemarches.com. T1-output-plateformes.json finalisé : 25 plateformes, 7 avec feedback Trustpilot. Signaux forts T2 : Archionline 2.4/5 (spam + permis PLU non conformes), hemea = courtier déguisé en MOE, TMA = meilleur ratio pros. Prochaine étape : MP-TAFF T2 scoring 5 axes éthiques.

  • [W19 — 2026-05-06 13:30] Cascade dispatchable Codev MVP livrée — 9 fichiers prêts à dispatcher en session Opus dédiée : Cadrage /orchestrateur app entraide / co-développement Jules pour facilitation IRL jeudi 8/05 ~10 amis. 5 intersections tranchées : URL /codev (sous-route aep.trans-former.fr pas nouveau domaine), naming "Co-développement"/"Entraide entre pairs", mot de passe partagé merci, persistance NocoDB nouvelle table codev_fiches (carto vit hebdo, pas effacée), démo route publique /codev/demo (10 prénoms factices pour pitch univ). Démêlage trinôme (problème mathématique flaggé par Jules) : matching pair-only en MVP, trinômes émergent visuellement du D3 force-directed (triangles dans le graphe), pas de logique trinôme explicite codée — économie combinatoire majeure. 3 modes : Solution (besoin→offre asymétrique avec flèche), Alliance (besoin↔besoin symétrique), Surprise (offre↔offre symétrique). Algo matching MVP simple sans IA : Jaccard sur hashtags si présents, sinon Jaccard sur tokens FR (stop-words filtrés) seuil 0.15 — V2 embeddings si scaling. Réutilisation pattern GraphView.vue (~700 lignes existant) en simplifié (~200-300 lignes pour CodevGraph) — pas de greenfield. Cascade dans codev-build/ (même pattern que aep-communaute-build/) : INDEX (table+décisions+statut) + META-PROMPT-OPUS (preflight+dispatch séquentiel+1 checkpoint deploy+format récap) + M1 (NocoDB table API + 3 endpoints + runtimeConfig) + M2 (lock+fiche+middleware auth skip /codev+/codev/demo) + M3 (CodevGraph D3 + page carto affichage seul) + M4 (matching 3 modes + boutons + animation force.alpha(0.5).restart()) + M5 split phase 1 (démo+build local+stop) + phase 2 (deploy prod après checkpoint Jules) + FEEDBACK-PASSES (10 risques pré-dispatch corrigés) + PHRASE-LANCEMENT (one-shot pour session Opus). Patches en cours de session : M1 fait création table NocoDB en autonomie via API (token NocoDB e9rU... déjà dans nav-carte/.env, endpoint POST /api/v2/meta/bases/{baseId}/tables), M5 phase 2 sync .env VPS automatiquement (ssh append + restart aep), règle d'or "couper M4/M5 si timing serré" retirée du META car Jules a confirmé scope OK. 1 seul checkpoint Jules : entre M5 phase 1 (build local 200) et M5 phase 2 (deploy prod). Pattern méga-dispatch consécutif #5 (avant : Simulateur V2 30/04, Méga-cascade AEP V2 30/04, MP-TAFF cascade-megaboum 06/05, AEP V2 graphe PV2-5 micro-itérations 06/05). À dispatcher en session Opus dédiée (jauge propre, ~1h30 cascade attendue + ~5 min action manuelle Jules NocoDB).

  • [W19 — 2026-05-06 21:30→01:45] AEP V2 graphe interactif PV2-5b/e/f/g + chatbot v2 vivant + decouverte 2 repos imbriqués : 4 commits vault feat/aep-v2-cartobifurcation (062337a sidebar+chatbot intégré, 2adffdf toggle Familles/Pratiques+popover famille, 5d7556a carte unifiée layers superposables+popover hashtag+lisibilité, e1ae1b9 popovers enrichis+FicheFamilleModal). 4 micro-itérations dispatch agent Sonnet en séquentiel, pilote commit lui-même chaque fois (pattern anti-hallucination établi après agent 1 a inventé hash 755d1ef). Décisions design : skip PV2-5c bicolores (8/120 structures = effet marginal), toggle PV2-5e exclusif fusionné en layers superposables PV2-5f (intuition Jules : séparation artificielle), Pratiques default OFF perf-friendly (174 noeuds + 640 liens si tout coché), FicheFamilleModal composant dédié réutilisable, skip définitions hashtags (pas de contenu source) → ligne générique "portée par N structures de M familles". Découverte 2 repos git imbriqués (vault parent ATIS-IPCJRA branche v2 + sous-repo nav-carte/ branche v1.1 distincte) → expliquait les "hallucinations" branche des agents. Notée dans ATIS-Dev.md section "Pièges connus" + réflexe pilote git rev-parse --show-toplevel au démarrage. Chatbot v2 : endpoint v1→v2 dans ChatbotPlaceholder.vue (commit sous-repo 5878c56), vectorize-v2.js renommé en .cjs (incompat ESM type=module), payload Mistral fixed inputsinput, 120 embeddings générés (3.5MB embeddings-v2.json gitignored), patch vectorSearch.ts process.cwd() au lieu d'import.meta.url (bug Nitro bundle). Rotation clé Mistral : nouvelle clé PXsPUhk... notée _System/API-credentials.md, appliquée local .env + VPS /opt/aep/.env (backup .env.bak.before-rotation-20260506) + restart aep + smoke test prod chatbot v1 OK. Doc features graphe créée : aep-communaute-build/PV2-5-FEATURES-GRAPHE.md (briefing agent qui découvre en 30 sec). Backlog différé : PV2-5d sous-noeuds projets emblématiques (perf-critique 480 noeuds), définitions hashtags (session écriture éditoriale Jules), décision repo imbriqués (intersection stratégique demain). Test live chatbot v2 bloqué par lock Dropbox sur .nuxt/dev → prompt cloture demain PV2-5h-test-chatbot-v2-local.md.

  • [W19 — 2026-05-06 02:30] MP-TAFF V2 cadré + prompt scraping autonome séparé + rename atis-humain : Brainstorm divergent Jules pour Carte 3 AEP "Trouver du taf en archi". 5 axes scoring éthique AEP validés (Rémunération / Transparence / Pratiques pro / Écologie / Matching) avec définitions + critères + échelles ⚠️ — c'est le différenciant central vs annuaires neutres. Décisions verrouillées : freelance only V1 (70% archis indé = cible la plus en galère), IA applique scoring (critères validés une fois = pas de validation fiche par fiche), onglet aep.trans-former.fr (pas sous-domaine), branche parallèle feat/aep-taff-v1 (pas attendre merge V2), SEO reporté V2 (skill /seo-page-aep à créer). MP-TAFF V2 ~430 lignes avec 2 tours auto-feedback (table décision tag global, format desc IA 5 sections, §risque juridique nominatif, calibrage chatbot 3 questions, préflight conflit branche V2 + i18n). MP-TAFF-T1-scraping-autonome.md créé (~270 lignes) — sortable sur PC séparé pour parallélisation pendant qu'ATIS Dev bosse T0/T2/T3+. Pattern routing scraping documenté : Jina d'abord → crawl4ai SPA → BrowserMCP RGPD/auth → manuel flag. Forums commu intégrés : Team.Archi, Reddit r/Architecture FR, presse pro (Le Moniteur, AMC, D'A). Output JSON structuré consommable par T2. 🔒1 simplifié = récap scope synthétique (10 min Jules). Backlog cascade : MP-MENTOR (carte 4 entraide), MP-CROSS (n8n + GitHub OS) restent prêts. Rename taraatis-humain : skill renommée, routing patché dans atis-archi.md ligne 390 et ATIS-agents-specialises.md ligne 29. Anciennes refs à Tara la personne (Mediathèque, done.md, ton-jules.md) inchangées.

  • [W19 — 2026-05-05] AEP V2 PV2-4+5+8 DONE + vue graphique D3 : PV2-4 (887 edges, 480 projets, reseaux-bifurcation.json 847KB). PV2-5 UI (NavMapV2, HashtagFilter, IntentionBanner, FicheModalV2, palette 5 familles, geocodage 118/120, GraphView.vue D3 force-directed). PV2-8 RAG (chatbot-v2.post.ts + vectorize-v2.js). Fixes UI : onglets outremer desktop, sidebar scroll, chips colorees, hashtags repliables, F6 filtre, intention overlay localStorage. EDITO-V2.md cree. 13 commits feat/aep-v2-cartobifurcation. 🔒 PV2-5 checkpoint visuel Jules en attente.

2026-W18 (décharge 2026-05-13)

  • [W18 — 2026-05-03] AEP V2 PV2-2ter DONE : 10 emails récupérés. Volet A F2 (amaco/LTE), F4 (toitsdechoix/HPO/HabiterAuvergne/EmmanuelleDucos). Confirmed not public : F3 (LALCA/Sentiers/AOA/METALAB), F4 (unitoit/atelier15/a-tipic/HPF/atcoop). Blocages : rfcp.fr GravityView JS, a-tipic HTTP 400. Volet B F6 : 7 flags + 4 emails (Forensic/Centrala/NBL/Assemble) + 1 new fiche Collectif Etc (contact@collectifetc.com). Seed 122 fiches. Commit 7ce8e12.

  • [W18 — 2026-05-03] AEP V2 PV2-2 F1 DONE : 26 fiches réemploi & filières (14 V1 + 12 nouvelles). Nouvelles : Cycle Up (contact@cycle-up.fr), Backacia (form), Mobius (contact@mobius-corp.com), AD VITAM MATERIAL (reemploi@embuild.be), Cirkla (c/o insitu), CANCAN (contact@collectifcancan.fr), HArquitectes (harquitectes@harquitectes.com), isla (press@isla-architects.com), jdviv BE (EUmies 2026 co-winner), SalvoWEB, B+L Architectes, REFAIR/BDR. 6/12 emails high. Hashtag nouveau proposé : #amo-reemploi (AMO/diagnostic PEMD spécialisés). BrowserMCP off toute la session → Jina only (Reuse Foundation non scrapée, jdviv URL à confirmer). Commit 656cc2d. PV2-2 5/5 familles DONE. → Reste PV2-3+PV2-4.

  • [W18 — 2026-05-03] AEP V2 PV2-2 F2 DONE : 36 fiches frugalité & low-tech (22 V1 + 14 nouvelles). Nouvelles : Lacaton&Vassal (Pritzker 2021), Kéré Architecture (mail@kerearchitecture.com), Anna Heringer, CRATerre (secretariat@craterre.org), Les Grands Ateliers, AsTerre (secretariat@asterre.org), RFCP, EnvirobatBDM, NUNC, LAPS, Dorodango, BEES, amàco (contact@amaco.org), Lehm Ton Erde. 4/14 emails high conf. Sources productrices : AsTerre annuaire (19 agences archi identifiées), Pritzker (2 nouvelles), frugalite.org réseau. Blocages : RFCP annuaire JS, lehmtonerde.at 422, OFF laureats non scraped, BrowserMCP instable (3 décos). Commits 8808a35+301c3be. → Reste F1 Réemploi.

  • [W18 — 2026-05-03] AEP V2 PV2-2 F3 DONE : 22 fiches architecture sociale & précarités (11 V1 + 11 nouvelles). Nouvelles : PEROU, Plateau Urbain (SCIC), Bellastock, ASF France, Rural Studio, Forensic Architecture, Collectif Parenthèse, WoMa, Fab City Grand Paris, CivicWise. 6/11 emails high conf (PEROU·Bellastock·Rural Studio·Parenthèse·WoMa·CivicWise). Sources : Quatorze /partenaires-new (meilleur hub), YWC lieux (Grands Voisins + Coco Velten), A&P filtres. 4 multi-famille (Bellastock F3+F5, Parenthèse F3+F4, WoMa F3+F4, YWC F3+F4+F5). Commit d2028f5. → Reste F1 + F2.

  • [W18 — 2026-05-02 23:23] AEP V2 PV2-2 F4 DONE : 20 nouvelles fiches collectifs/écolieux/AMO via Jina (BrowserMCP déco → pivot Jina). 11/20 emails high conf. Structures-clés : RAHP, HPF, Habicoop, Hab-Fab SCIC, Regain SCIC, Coopérative Oasis, Mietshäuser Syndikat. 9 contacts partiels (tel/form) à compléter BrowserMCP. Commit f54afe3.

  • [W18 — 2026-05-02 19:51] AEP V2 PV2-2 F5 DONE : 15 fiches urbanisme transition via BrowserMCP. 7 emails high (CLER/TEPOS/Coloco/Bas Smets/EP/FNAU/Atelier Georges). Commit 56c93eb.

  • [W18 — 2026-05-02 18:17] C3 smoke test + PV2-1 scrape DONE : C3 = 2 bugs (P0 algo-config.json 404, P1 redirect 301 manquant) + rapport C3-RAPPORT.md. PV2-1 = 5/5 emails trouvés via BrowserMCP (Opalis/Frugalité/Quatorze/Tepop/Transition France), commit 6df5b84. Stack BrowserMCP validé pour batch PV2-2. Patcher P0+P1 avant merge master simulateur.

  • [W18 — 2026-04-30 12:00] AEP Cascade V2 Phase A2+A3 figées + PILOTE-V2 doc pilote vivant : Session "AEP COMMU V3 suite" /atis-archi puis /atis-dev. SPEC-V2-FEEDBACK-DEV.md livré (faisabilité pipeline 3 passes, email cascade 5 niveaux estim 65-80%, reclaim JWT HS256 30j single-use, grain JSON suffisant si desc_longue 600+ + 3 sources, branches 2 dédiées, pre-flights standardisés, fix BOM). PILOTE-V2.md créé comme source de vérité vivante à la racine aep-communaute-build/ (Jules pilote depuis ce fichier ; tout Opus suivant le lit en premier). 13 prompts PV2-X dans 0 INBOX/PROMPTS/aep-v2-cartobifurcation/ (README + PV2-0 preflight + PV2-1 scrape test 5 fiches + PV2-2 5 agents recherche par famille en parallèle (idée Jules : recoupement multi-famille = signal politique transversalité) + PV2-2bis recoupement + PV2-3 passe2 analyse + PV2-4 passe3 croisements + PV2-5 refonte UI + PV2-6 reclaim + PV2-7 badges statut + PV2-8 RAG coexistence v1+v2 + PV2-9 bandeau regards d'ailleurs + PV2-10 E2E build + PV2-11 batch emails + tri DOM-TOM). NEXT-SESSION-PROMPT-V3.md créé pour relais. Amendements Jules sur SPEC-V2 : famille 1 "Réemploi & matière" → "Réemploi & filières", AMO ajouté famille 4 (Tepop/Hab-Fab/Habicoop), famille 5 Urbanisme transition gardée fermement (cibler scrape agressif), centres ressources DOM-TOM → carte ressources existante (sauf Caribois praticien direct), pas de cap fiches sur agents recherche, stratégie snowball depuis nodes établis (Frugalité, Opalis, A&P) + crawl collaborateurs/influences/prix/distinctions. Sessions batch nocturnes dimensionnées Claude Max 5h Opus. PV2-0 partiel exécuté : branche feat/aep-v2-cartobifurcation créée depuis origin/main (tracking unset = anti-push main accidentel) + BOM UTF-8 retiré de nav-carte/deploy.sh. PV2-0 effectif (checkout + structure nav-carte/V2-cascade/ + hook pre-commit no-BOM + sources-par-famille.md) à faire prochaine session après commit/stash des 830 fichiers pending sur feat/aep-website-v1.1.

  • [W18 — 2026-04-30] Cascade MEGABOUM opérationnelle — 4 MP rédigés + cockpit lisible : 0 INBOX/PROMPTS/cascade-megaboum/ créé avec 00-COCKPIT-CASCADE.md (index lisible en 3 min par tout Opus dispatché, format différent de la mégaspec — celle-ci reste lecture profonde optionnelle). 4 méga-prompts prêts à dispatcher : MP-TAFF (app trouver du taf B2C/B2B/appels publics, ~5h, étend aep-communaute-build/), MP-MENTOR (app mentorat-entraide M7-M, ~5h, post-TAFF), MP-CROSS (pipeline cross-posting n8n LinkedIn+Substack+Listmonk+@aep.politique + GitHub OS publish skills/lightrag/vps-kit, ~5h, parallèle), MP-DESIGN (création agent atis-design, prompt court ~1h via /create-agent + scrape Prisme.one). Brief archive MP10-manifeste-aep-INFO-BRIEF.md (chantier déjà lancé par Jules). Chaque MP démarre par CHECKPOINT 0 réflexion faisabilité (l'Opus lit, propose, attend OK Jules avant dispatch). Backlog explicite : page-cerveau Astro from scratch, méga-RAG FRACAS vague 1, atis-philosophe, frontend-slides, rename atis-humain (P1 30 min), Insta @julesneny n8n (Q3). LightRAG VPS DOWN déclassé : pas bloqueur P0 semaine si on ne fait pas méga-RAG, devient bloqueur quand on attaquera RAG. Cadence : Jules pilote au fil des jours, 1-2 MP/jour, 2 clusters max simultanés.

  • [W18 — 2026-04-30 02:46] Méga-cascade V2 AEP Phase A1 figée + 3 agents background livrés : Session Opus orchestrateur "AEP commu V2". 9 intersections tranchées par Jules en un message (5 familles fusion F4+F5, UX vignette + template carte 1, scope FR+Europe francophone + capture incidente régénératifs hors scope, articulation pensées<->structures reportée V2, passe profonde GO, email champ soft, charte reportée, filtre échelle drop, A3 absorbé A1). SPEC-V2.md figée. 3 agents Sonnet dispatchés en parallèle background : VOIE 2 V1.1 nav-carte (4 commits feat/aep-v1.1-nav-carte basée sur feat/aep-pratiques-regeneratives car main pré-V1 ; PA1 DOM-TOM pattern desktop 2 onglets, PA3 bouton Proposer contextuel, PA5 chatbot pratiques régé Mistral, 6/6 bugs E2E M1-M3+L1-L3 corrigés, build Nuxt OK), VOIE 3 website (1 commit feat/aep-website-v1.1 e95f693 ; PB1 hamburger 4 entrées + stubs /manifeste /ressources /signaler ; /!\ livré sur renovation-energetique.trans-former.fr - website pro, pas aep.trans-former.fr - à clarifier prochaine session), PASSE PROFONDE (52 pratiques régé + 99 ressources institutionnelles analysés ; 5 familles confirmées avec garde-fous F5 ; 46 hashtags ; 7 cas limites + 4 hors-grille type "mouvement-manifeste" potentiel ; 226 acteurs candidats enrichissement carte ressources : P1=56 fiches urgentes dont 30 CAUE manquants top dpts + 4 CAUE DOM-TOM + 9 MA régionales + 2 CROA DOM ; constat critique : 0 DOM-TOM + 6/92 CAUE dans carte ressources actuelle). 5 questions stratégiques remontées pour Phase A2 (Q-PP1 5 vs 6 familles, Q-PP2 type mouvement-manifeste, Q-PP3 F5 différée passe 2, Q-PP4 double-référencement KEBATI/AQUAA/RBD/Envirobat, Q-V3 site cible hamburger). NEXT-SESSION-PROMPT.md pré-écrit pour reprise propre Phase A2 /atis-dev. Pattern méga-dispatch consécutif #4. Tokens : 130k orchestrateur + ~451k délégués sous-agents.

  • [W18 — 2026-04-30 01:42] Méga-cascade V2 AEP cadrée : MEGA-V2.md master orchestration 3 voies créé. VOIE 1 = V2 conceptuelle (refonte carte écosystème AEP en carte des réseaux de bifurcation, 5-6 familles éditoriales, reclaim email magique, pipeline IA cascade 3 passes, ~75-100 fiches). VOIE 2 = V1.1 nav-carte (items 1+2+4+5+8 ; item 3 absorbé par VOIE 1). VOIE 3 = website astro-site (hamburger + manifeste + ressources). Décisions Jules : /atis-archi pilote la spec V2 conceptuelle Phase A1, /atis-dev en relai Phase A2. Apports critiques : champ email obligatoire dans le scrape (sans email = pas de reclaim), passe profonde sur fiches existantes (~52+80) pour faire remonter hashtags sous-familles, item 4 (filtre échelle) à questionner, A3 absorbable dans A1, page Manifeste à ajouter au hamburger website. Phrase d'amorce + effort high recommandé pour la session Opus dédiée demain. PHRASE-LANCEMENT-OPUS-V2.md marqué SUPERSEDED. 2 briefs INBOX (V2-BRIEF-AGENT-OPUS + V2-RECAP-PROJET) déplacés dans aep-communaute-build/.

  • [W18 — 2026-04-29 11:48] AEP scrape P1-P7 FAIT : BrowserMCP (P1 architecture-precarites.fr : 200+ projets, 5 catégories) + Jina (P4 vegetal-e , P6 colorado-architecture , P7 karibati , P3 caribois ). P2 archidev bot-protégé + P5 envirobat 422 → consultation manuelle. scrape-browsermcp.json créé (7 entrées). Email auteurs architecture-precarites.fr envoyé par Jules. INCLURE : vegetal-e (5/8), envirobat-RE (7/8), karibati (5/8). EXCLURE : caribois (2/8), colorado (3/8).

  • [W18 — 2026-04-29] AEP V1 E2E PASS : 5/5 scénarios OK (3 mobile, 3 laptop). Branche feat/aep-pratiques-regeneratives prête à merger main. E2E-RESULTS.md créé. Bugs mineurs capturés : M1 chips a11y + M2 reset searchbox + M3 floating button + L1 redirection.

  • [W18 — 2026-04-29 08:11] AEP V1 LIVRÉE : 52 fiches prod (aep.trans-former.fr/pratiques-regeneratives), 12 commits feat/. V1.1 mode divergent cadrée (8 items brain-dump Jules).