Bénévole : l'email n'est plus unique (couple, famille)
Plusieurs bénévoles peuvent légitimement partager une même adresse email — l'architecture l'interdisait : l'import ignorait silencieusement le second (« duplicate_email_in_file »), et l'ajout manuel renvoyait un 409. Les deux sont corrigés. - Migration 0009 : retrait de la contrainte d'unicité (edition_id, email) sur `volunteer` (l'index sur `email` seul est conservé). - Import (`app/importing/service.py`) : l'upsert se fait désormais sur (email, nom + prénom), pas sur l'email seul. Un même email revu avec un nom différent dans le fichier crée un second bénévole (nouveau code `import.row.shared_email`, WARNING) au lieu d'être ignoré ; `duplicate_email_in_file` ne se déclenche plus que sur une ligne littéralement répétée (même email ET même nom). - API (`POST`/`PATCH /volunteers`) : retrait du rejet 409 `volunteer.duplicate_email`, devenu sans objet (le mock ne l'a d'ailleurs jamais appliqué à la création manuelle). - Mock frontend (`mock-client.ts`) : même correction de l'upsert par import, pour rester cohérent avec le backend. - CLAUDE.md à jour (modèle de domaine, règles d'import, journal). Contrepartie assumée (documentée) : un email re-importé avec un nom légèrement différent (faute de frappe corrigée) crée désormais un bénévole de plus signalé, plutôt que de renommer silencieusement l'existant — même philosophie que la détection sans email, qui ne fusionne jamais rien automatiquement. Vérifié : 179 tests backend, ruff, alembic check ; typecheck/lint/build/smoke frontend ; reseed de démonstration. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017uUsRg7XzopkCPWimwg9ZM
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
fcc42c8d43
commit
897a76ca6d
@@ -65,12 +65,13 @@ les tables sauf les tables d'association.
|
||||
postes (pas les disponibilités, qui sont des fenêtres libres).
|
||||
CRUD `GET/POST/PATCH/DELETE /editions/{id}/day-parts` (COORDINATION pour
|
||||
l'écriture).
|
||||
- **`Volunteer`** : `email` (unique **par édition**, nullable pour les
|
||||
bénévoles créés à la main — plusieurs `NULL` autorisés), `first_name`,
|
||||
`last_name`, `phone`, `comment`. Pas de date de naissance, taille de
|
||||
t-shirt, régime, ni compétences. Porte deux listes de vœux, exposées par la
|
||||
fiche (`artist_ids`, `wished_position_ids` ; `None`/absent = inchangé,
|
||||
`[]` = vider).
|
||||
- **`Volunteer`** : `email` (nullable, **pas unique** — plusieurs bénévoles
|
||||
peuvent partager une même adresse, ex. un couple ou une famille ; c'est le
|
||||
couple (email, nom + prénom) qui identifie un bénévole, pas l'email seul),
|
||||
`first_name`, `last_name`, `phone`, `comment`. Pas de date de naissance,
|
||||
taille de t-shirt, régime, ni compétences. Porte deux listes de vœux,
|
||||
exposées par la fiche (`artist_ids`, `wished_position_ids` ; `None`/absent =
|
||||
inchangé, `[]` = vider).
|
||||
- **`Artist`** : programmation de l'édition (`name`, `performance_date`,
|
||||
`start_time`, `end_time` — `end_time <= start_time` ⇒ le passage finit le
|
||||
lendemain). Unique (`edition_id`, `name`, `performance_date`). La
|
||||
@@ -308,7 +309,10 @@ défilement horizontal — jamais de colonnes étroites par défaut.
|
||||
commentaire — pas les disponibilités, qui se déclarent dans l'app), en deux
|
||||
temps : analyse (colonnes détectées, aperçu) puis exécution avec mapping
|
||||
validé. Rapport ligne par ligne. Détection des doublons : upsert sur
|
||||
`email` ; sans email, détection sur (`last_name`, `first_name`) signalée
|
||||
(`email`, `last_name` + `first_name`) — l'email seul ne suffit pas,
|
||||
plusieurs bénévoles peuvent le partager (couple, famille) ; un même email
|
||||
revu avec un nom différent crée un bénévole de plus (signalé, jamais
|
||||
ignoré) ; sans email, détection sur (`last_name`, `first_name`) signalée
|
||||
sans upsert automatique. Mode simulation qui ne persiste rien.
|
||||
3. API CRUD sur `Position`, `Shift`, `Volunteer`, `Assignment`.
|
||||
4. Moteur de validation (section 3).
|
||||
@@ -460,6 +464,7 @@ Aucune dépendance locale requise hors Docker.
|
||||
| 13 | Bénévole : retrait taille de t-shirt / régime ; entité `Artist` (CRUD, par jour) + vœux des bénévoles (artistes, postes) | à valider |
|
||||
| 14 | Retrait des compétences (`Skill` et règle `MISSING_REQUIRED_SKILL`) ; disponibilités = fenêtres horaires libres par jour (`GET`/`PUT` availability), prises en compte par `OUTSIDE_AVAILABILITY` | à valider |
|
||||
| 15 | Solveur de suggestions OR-Tools CP-SAT (section 4) : `POST /editions/{id}/solver/suggestions`, candidats remontés en tête de liste dans la grille des besoins — aucune affectation automatique | à valider |
|
||||
| 16 | Bénévole : l'email n'est plus unique (couple, famille) — identification par (email, nom + prénom) dans l'import et l'API, plus de rejet 409 à la création manuelle | à valider |
|
||||
|
||||
**Reste hors périmètre** (modèle prêt à les accueillir) : SMS, constructeur
|
||||
de formulaire, pointage sur site, IA. Frontend : squelette + 6 écrans +
|
||||
|
||||
Reference in New Issue
Block a user