Files
decision/docs/dev/tdd-methode.md
Yvv fc84600f97 Fix auth : CORS outermost + dev rate limit + filtre workspace réactif
- Middleware : CORSMiddleware ajouté en dernier = plus externe = tous les
  codes de retour (dont 429) portent Access-Control-Allow-Origin
  → résout "no response / Failed to fetch" sur POST /auth/challenge
- Dev mode : rate_limit_auth = RATE_LIMIT_DEFAULT (60/min) au lieu de 10/min
  → plus de blocage login après quelques reconnexions
- app.vue : watcher activeSlug → refetch documents/décisions/protocoles/mandats
  → le sélecteur de workspace filtre désormais le contenu en temps réel
- TDD : 4 tests middleware (RED→GREEN) + doc méthode docs/dev/tdd-methode.md
- Régression : 190/190 tests verts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 15:51:28 +02:00

5.0 KiB

Méthode de travail TDD — libreDecision

Principe fondamental

Tu décris la règle métier. Claude traduit en test. Tu valides. Claude implémente.

Jamais l'inverse. Le test est la source de vérité ; l'implémentation n'est que le moyen de le faire passer.


Workflow par itération

1. Tu décris une règle en français naturel
   → "Si scope=personal, la décision est toujours individuelle"

2. Claude écrit le(s) test(s) — RED (le test échoue avant l'implémentation)
   → Tu valides que le test capture bien l'intention

3. Claude implémente le minimum pour que le test passe — GREEN
   → Rien de plus que ce que le test exige

4. Claude refactorise si nécessaire — REFACTOR
   → Sans casser les tests existants

5. Répétition avec la règle suivante

Commandes de prompt

Commande Action
+test Écrire le(s) test(s) sans implémenter
+impl Implémenter pour faire passer les tests en attente
+test+impl Test + implémentation d'un coup (règle simple)
+règle Ajouter une règle au moteur existant
+règle remplace Une nouvelle règle remplace une précédente (précise laquelle)
+régression Vérifier qu'aucun test existant n'est cassé après un changement
+résumé Afficher l'état des règles implémentées et en attente

Format d'une règle métier

Pour être efficace, une règle doit préciser :

ENTRÉES :  les variables concernées et leurs valeurs
RÉSULTAT : ce que le système doit retourner ou faire
EXCEPTIONS : cas qui brisent la règle générale (si aucune, dire "aucune")

Exemple :

ENTRÉES  : scope = "personal"
RÉSULTAT : decision_type = "individual", recommend_onchain = False
EXCEPTIONS : aucune — même si stakes = "critical", une décision personnelle reste individuelle

Structure des tests dans ce projet

backend/app/tests/
  test_qualifier.py         ← moteur de qualification (tunnel Décider)
  test_middleware.py        ← rate limiter, CORS, headers
  test_threshold.py         ← formules WoT existantes
  test_votes.py             ← logique de vote
  test_decisions.py         ← service décisions
  ...

Chaque fichier de test correspond à un module ou un bloc fonctionnel.
Les tests d'intégration (qui touchent la DB) sont marqués @pytest.mark.integration.


Les 4 blocs algorithmiques

┌─────────────────────────────────────────────────────────┐
│  TUNNEL "DÉCIDER"                                        │
│                                                          │
│  1. QUALIFIER    → nature / enjeu / réversibilité        │
│        ↓                                                 │
│  2. ROUTEUR      → individual / collective / delegated   │
│        ↓                 ↓                              │
│  3. PROTOCOLE    → sélection formule WoT + paramètres   │
│        ↓                                                 │
│  4. GRAVURE      → recommandation on-chain (IPFS+remark) │
└─────────────────────────────────────────────────────────┘

Les blocs sont testés indépendamment puis en intégration.
Un changement dans le bloc 1 ne doit jamais casser silencieusement le bloc 4.


Invariants fondamentaux (ne jamais casser)

Ces règles doivent avoir un test dédié et rester vertes en permanence :

  1. Une décision individual ne génère jamais de session de vote
  2. Une décision on_chain implique toujours recommend_onchain = True
  3. recommend_onchain = True requiert reversibility = "impossible" ou stakes = "critical"
  4. Le qualificateur ne retourne jamais un type inconnu (enum strict)
  5. Un protocole WoT sélectionné doit exister en base (slug valide)

Règles de régression

  • Après chaque implémentation : pytest backend/app/tests/ -v --tb=short
  • Avant tout commit : zéro test rouge
  • Si un test existant casse après un nouveau changement → stop, analyser, ne pas contourner
  • RATE_LIMIT_AUTH en dev = 60/min minimum (pas de blocage en développement)

Où sont les règles métier documentées

Source Contenu
docs/dev/tdd-methode.md Cette méthode
docs/dev/qualifier-rules.md Règles du moteur de qualification (créé au fil des itérations)
backend/app/engine/qualifier.py Implémentation du qualificateur
backend/app/tests/test_qualifier.py Tests — source de vérité exécutable

À propos de la mémoire de contexte

Entre les sessions, Claude peut perdre le contexte des règles en cours.
Pour reprendre efficacement :

"Résume les règles du qualificateur implémentées jusqu'ici"
→ Claude lit test_qualifier.py et qualifier.py et synthétise

Les tests sont leur propre documentation. Ne pas dupliquer les règles en commentaires.