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

101 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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
```bash
# 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