Files
sejeteralo/CLAUDE.md
Yvv 19ac64c856
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Seed : foyers fixture dev + codes stables dans dev hints
- seed.py : 3 foyers avec codes fixes (DEVTEST2/3/4, RS/RP/PRO)
  insérés avant les 363 réels ; existing_codes pré-chargé → zéro collision
- page citizen : dev hint mis à jour avec les 3 mêmes codes + profils
- CLAUDE.md : reformaté en guide de session

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 03:45:12 +01:00

4.4 KiB
Raw Blame History

SejeteralO

Plateforme de tarification participative de l'eau pour communes françaises. Les citoyens votent sur la forme de la courbe tarifaire via des éditeurs Bézier interactifs ; le système calcule un tarif à équilibre de recettes en temps réel.

Protocole de début de session

  1. git pull --rebase origin main
  2. Vérifier que data/ existe à la racine — si absent, signaler avant toute opération
  3. Si l'objectif de la session n'est pas précisé, le demander

Stack

  • Frontend : Nuxt 4 (Vue 3, TypeScript) + Pinia ; package manager : npm ; port dev : 3009
  • Backend : Python FastAPI + SQLAlchemy 2.0 async + SQLite (aiosqlite) ; port dev : 8000
  • Déploiement : Docker multi-stage + Traefik (backend + frontend) ; CI Woodpecker
  • Pas d'UnoCSS — CSS vanilla avec variables CSS palettes dans main.css

Structure

frontend/
  app/
    components/       # composants Vue (dont DisplaySettings.vue — 6 palettes)
    layouts/          # layouts Nuxt
    pages/
      commune/[slug]/index.vue   # page principale citoyenne (~1900 lignes)
    composables/
      useApi.ts       # wraps fetch avec Bearer token ; usage : api.get<Type>('/path')
    middleware/       # route middleware (auth)
    plugins/
      auth-restore.client.ts     # restaure token depuis localStorage au démarrage
    stores/
      auth.ts         # token, role, communeSlug
      commune.ts
    utils/
      bezier-math.ts  # formule Bézier (Cardano + Newton-Raphson) — miroir du backend
  nuxt.config.ts      # port 3009, apiBase via NUXT_PUBLIC_API_BASE (défaut :8000)
backend/
  app/
    routers/          # 6 routers : auth, communes, tariff, votes, households, content
    engine/
      pricing.py      # compute_p0(), compute_tariff(), compute_impacts()
      integrals.py    # coefficients α₁, α₂, β₂ (intégrales Bézier)
      median.py       # médiane élément par élément des votes
      current_model.py  # tarif linéaire de référence
    models/           # Commune, TariffParams, Household, Vote, AdminUser, CommuneContent
  alembic/versions/   # migrations
  tests/
  seed.py             # Commune Saoû, 363 foyers, codes auth 8 chars, comptes admin
data/                 # runtime — JAMAIS dans git (voir Données runtime)
docker/
  docker-compose.yml  # backend + frontend (réseau traefik externe)
  backend.Dockerfile
  frontend.Dockerfile
  docker-compose.dev.yml
Makefile              # docker-up, docker-dev

Données runtime (CRITIQUE)

  • data/ à la racine : contenu non géré par git, jamais écrasé par les commits
  • Volume Docker backend-data monté sur /app — contient sejeteralo.db (SQLite)
  • Avant toute migration de chemin ou écriture sur data/ ou le volume : demander confirmation
  • En dev local : la DB SQLite est dans backend/ (chemin relatif ./sejeteralo.db)
  • Seed requis après chaque reset DB : cd backend && python seed.py

Commandes

# Backend
cd backend && . venv/bin/activate
uvicorn app.main:app --reload --port 8000 --host 0.0.0.0
python -m pytest tests/ -v
python seed.py          # Saoû, 363 foyers, admin accounts

# Frontend
cd frontend && npm run dev        # :3009
npm run build

# Docker
make docker-up     # production
make docker-dev    # dev avec hot-reload

Conventions / pièges

  • UI français, code anglais — "foyer" = household (facturation), "électeur" = voter (vote)
  • Modèle Bézier deux niveaux — 6 paramètres citoyens (vinf, a, b, c, d, e) + p0 auto-calculé :
    p0 = (Recettes  Σabo  Σβ₂) / Σ(α₁ + α₂)
    
    Implémenté deux fois : backend Python (engine/pricing.py) et frontend TS (utils/bezier-math.ts) — garder synchronisés
  • Agrégation votes : médiane élément par élément des votes actifs (pas moyenne)
  • Graphiques SVG : axe X inversé (volumes élevés à gauche) — utiliser bindings réactifs t.* ou var(--svg-*), jamais de couleurs hex codées en dur dans les SVG
  • Thème : 6 palettes via useState('theme-dark') ; CSS vars : --color-primary, --color-bg, --color-surface, --color-text, --color-border, --svg-plot-bg, --svg-grid, --svg-text, --svg-text-light ; .palette-dark sur <html>
  • Dev hints : classe .dev-hint + v-if="isDev" ; les codes auth doivent exister dans la DB seedée
  • Port backend : 8000 en local (nuxt.config + uvicorn) — la table globale CLAUDE.md indique 8009 par erreur ; les fichiers de config font foi
  • Pas de ssr: true — CSR uniquement