MIR6,00 € +57,9 %OIN1,55 € −29,5 %KAK3,30 € +4,8 %BET2,10 € 0,0 %ECH1,75 € 0,0 %TRO19,05 € −8,0 %CHA2,75 € −1,8 %CRG2,60 € −1,9 %GIR33,00 € +2,8 %SAR5,70 € 0,0 %BRO3,80 € +38,2 %PON2,60 € 0,0 %MOR43,00 € 0,0 %CRV30,00 € 0,0 %PAA2,15 € +16,2 %CES8,45 € +5,0 %COU1,40 € +16,7 %POA2,25 € 0,0 %CAD3,20 € −1,5 %ABR3,50 € 0,0 %TOT3,80 € −7,3 %POR2,05 € +2,5 %CAR1,65 € −2,9 %POM1,40 € 0,0 %COE24,81 € −1,7 %PEH2,80 € −20,0 %POT1,40 € 0,0 %PEE2,80 € −20,0 %
🛠️ Console de la place

Admin HallesX

v2.0.0 · build f44f440 · 2026-08-01

Architecture HallesX

La carte complète de la plateforme — pour reprendre le projet sans archéologie. Mise à jour : juillet 2026.

Vue d'ensemble

RNM/FranceAgriMer ─┐                        ┌─ hallesx.com (Cloud Run, europe-west1)
Agence Bio ────────┤  scripts/* (crawlers)  │    Next.js 15 standalone, ~640 pages SSG
OSM / Overpass ────┼─▶ data/*.json ────────▶│    /api/v1 ouverte (CORS)
Agreste (xlsx) ────┤   (columnar, committé) │    next/og : ~300 vignettes de partage
data.gouv (468) ───┘                        └─ Firebase Auth (hallesx-prod)

Tout est statique au build quand c'est possible ; les données vivent dans le repo (data/), rafraîchies par cron GitHub Actions → commit → redéploiement. Aucune base de données serveur : la « base » est columnar JSON + le graphe en mémoire, reconstruits au build.

Données (data/ + lib/)

Source Script Fichiers Lib
Mercuriales RNM (79 marchés, 3 781 séances, 6 630 séries, 2018+)build-rnm-db.mjs (+ discover-rnm-markets.mjs)data/rnmdb/*.json (columnar : dates[], labels[], series)lib/rnm.tsgetCandles, rnmCoverage, allMarketStats, latestSession, marketMovers
Annuaire bio (60 874 producteurs, 883 importateurs)fetch-bio.mjs (param activite, singulier !)data/bio/*.jsonlib/bio.ts
Marchés de plein vent (4 077)fetch-marches-locaux.mjs (Overpass, miroir kumi)data/marches-locaux.jsonpages /marches-locaux
Production régionale (18,6 Mt)fetch-agreste.py (openpyxl + reset_dimensions, quintaux÷10)data/agreste.json/regions
HVE (25 329) · EGalim (66 135)harvestdata/hve.json, data/acheteurs.jsongraphe
Catalogue open data (468 jeux) + miroir 191 Moharvest-opendata.mjs, mirror-opendata.mjsdata/opendata-catalog.json, data/raw/** (hors Docker)/donnees

Graphe TAO (lib/graph.ts) : 86 101 nœuds / 86 225 arêtes typées (PRODUCED_BY, QUOTED_ON, SELLS_AT, IN_DEPT…), ids internés, adjacence in/out, mémoïsé au module. Alimente /graphe (carte à bulles canvas) et l'API.

Marché simulé au-dessus du réel (lib/market.ts) : cotes par produit seedées (mulberry32) et recalées sur les prix RNM réels quand la série existe (lib/rnm.ts findMatch : mot entier + famille marée/viande/f&l).

Pages (app/)

  • / home (héros + KPIs + movers + halles + partenaires) · /marche (la cote, recherche XL) · /produit/[slug] (chandelles OHLC temps réel-gap, carnet d'ordres deux sens, achat/vente) · /mercuriale/[slug] (79) · /marches, /marches-locaux, /halles(+slug), /regions, /graphe, /donnees
  • /producteurs/annuaire(+[ref]) — les 60 874, partenaires épinglés « ✓ Validée »
  • /pour + 52 landings (lib/landings.ts : pains/features/KPIs par audience)
  • /pro (stock photo→IA, prévisions, commandes) · /pro/ferme (jeu 3D Babylon, Norbert l'assistant, création sur adresse BAN réelle uniquement) · /pro/factures (factures conformes, PDP stub lib/pdp.ts, parrainage)
  • /compte — auth Firebase (voir plus bas) · /admin — console (état, pack d'images + prompts, docs) · /api/v1/* — API publique CORS (produits, cotes, mercuriales, graphe)
  • SEO : sitemap.ts complet, robots.txt, metadataBase, ~300 OG dynamiques (opengraph-image.tsx : racine, landings, produits, halles, mercuriales)

Auth (Firebase — projet GCP hallesx-prod)

  • Fournisseurs : Google (client OAuth auto-créé), téléphone/SMS (reCAPTCHA invisible), e-mail/mot de passe, anonyme. Domaines autorisés : hallesx.com, www, localhost.
  • lib/firebaseClient.ts (config publique) · components/AuthPanel.tsx — flux identifier-first (l'e-mail détecte compte existant/nouveau ; emailPrivacyConfig désactivé côté Identity Platform pour le permettre).
  • Header : avatar vivant (import Firebase différé post-montage dans Nav.tsx).
  • Pas encore de session serveur : l'auth est client-side ; brancher les server actions sur le token (Admin SDK) est l'étape suivante naturelle.

Design system (app/globals.css)

Crème #F7F4EC · vert jardin #17803D / feuille #7CB944 · terracotta #D96B3F · miel #F6B93B · charbon #211F1A. Fraunces (display) + DM Sans via next/font. Mobile : overflow-x: clip global, tables→cartes ≤800 px (data-th), tabbar avec safe-area-inset. Dataviz : chandelles vert/rouge sur surface claire, axe X proportionnel au temps (les trous saisonniers se voient), ≤64 bougies agrégées.

Infra & déploiement

  • Repo : github.com/Bros-AI/hallesx (privé) · commits conventionnels FR
  • CI (ci.yml) : tsc --noEmit + next build sur chaque push
  • Deploy (deploy.yml) : Docker multi-stage (standalone, non-root, port 8080, --build-arg GIT_SHA, copie public/ et data/) → Artifact Registry → Cloud Run europe-west1 (1 Gi, 0→3 instances). Auth keyless (WIF : pool github, condition assertion.repository=='Bros-AI/hallesx')
  • Data refresh (refresh-data.yml) : RNM 22 h 30 quotidien, bio dimanche 23 h 30 → commit data/ → redéclenche le deploy
  • Domaine : hallesx.com via Cloudflare (zone importée, enregistrements gris/DNS only — TLS géré par Google), mapping Cloud Run
  • Cache : HTML max-age=0, must-revalidate · /_next/static immuable 1 an · /img 30 j + SWR · OG 24 h + SWR · generateBuildId = GIT_SHA, version visible au footer
  • Images : pack Nano Banana 122 images bi-style généré une fois puis committé (voir IMAGES.md) ; OG rendues au build ; coût récurrent 0 €

Conventions & pièges connus

  • Heredocs bash + texte français = casse silencieuse → écrire un patch .py dans le scratchpad et l'exécuter (python patch.py).
  • Agence Bio : le paramètre est activite (singulier) — activites est ignoré sans erreur.
  • RNM : pages UTF-8 (ne pas décoder latin1) ; dates quotidiennes du JJ/MM/AA ET hebdo du JJ-MM-AAAA ; matching produit = mot entier + famille.
  • satori/next-og : tout <div> multi-enfants doit être display:flex ; pas de glyphes ▲▼ (fetch de police dynamique qui échoue).
  • Windows dev : tuer le port 3000 avant npm start (Get-NetTCPConnection -LocalPort 3000 | Stop-Process).

Backlog assumé

Surfaces/rendements Agreste + Douanes en couches carte · crawler des ateliers de transformation · aliasing des séries RNM renommées pré-2022 · Norbert branché sur un vrai LLM · vérification SIRET des revendications de ferme · sessions serveur (Admin SDK) · vidéos Remotion (« la semaine du marché »).

Documentation — Admin HallesX