Étape 6 : jeu de données de démonstration

- app/seed.py, exécutable via python -m app.seed, idempotent et déterministe
  (graine fixe), sans donnée nominative réelle
- Édition « Festival des Lucioles » 2026 : 120 bénévoles, 15 postes,
  4 jours (montage/festival/démontage), 3 demi-journées, 8 compétences,
  ~100 créneaux, ~280 affectations actives, disponibilités tri-état
- ~12 créneaux volontairement sous l'effectif minimal (trous d'effectif)
- 3 affectations à avertissement (compétence absente, hors disponibilité,
  repos insuffisant), 0 violation bloquante
- Passe de vérification finale via le moteur de validation : le résumé imprime
  le décompte des avertissements par règle et le nombre de bloquantes
- covered_slots rendue publique dans validation.engine (réutilisée par le seed)
- 2 tests (dataset réaliste, déterminisme/idempotence) ; 106 tests au total

Fin du premier incrément backend.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017uUsRg7XzopkCPWimwg9ZM
This commit is contained in:
AdamThomas
2026-09-09 23:07:31 +02:00
co-authored by Claude Sonnet 5
parent 74e35f0195
commit 49ac6a4726
4 changed files with 730 additions and 7 deletions
+2 -2
View File
@@ -58,7 +58,7 @@ def _check_overlap(data: ValidationInput) -> list[Violation]:
# --------------------------------------------------------------------------- #
# OUTSIDE_AVAILABILITY (avertissement) #
# --------------------------------------------------------------------------- #
def _covered_slots(
def covered_slots(
shift: ShiftInfo, day_parts: tuple
) -> list[tuple[dt.date, str]]:
"""Demi-journées (date, code) dont la fenêtre horaire recoupe le créneau."""
@@ -83,7 +83,7 @@ def _covered_slots(
def _check_outside_availability(data: ValidationInput) -> list[Violation]:
slots = _covered_slots(data.candidate_shift, data.day_parts)
slots = covered_slots(data.candidate_shift, data.day_parts)
if not slots:
return []
declared = {