Files
benevoles/backend/app/migrations/versions/0009_volunteer_email_not_unique.py
T
AdamThomasandClaude Sonnet 5 897a76ca6d 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
2026-09-15 19:38:28 +02:00

33 lines
955 B
Python

"""Bénévole : l'email n'est plus unique par édition
Revision ID: 0009_volunteer_email_not_unique
Revises: 0008_artist_performance_time
Create Date: 2026-09-15
Plusieurs bénévoles peuvent partager une même adresse (couple, famille) :
l'import les traitait auparavant comme des doublons et ignorait le second.
L'unicité (edition_id, email) est retirée ; l'index sur `email` seul est
conservé pour les recherches.
"""
from collections.abc import Sequence
from alembic import op
revision: str = "0009_volunteer_email_not_unique"
down_revision: str | None = "0008_artist_performance_time"
branch_labels: str | Sequence[str] | None = None
depends_on: str | Sequence[str] | None = None
def upgrade() -> None:
op.drop_constraint(
"uq_volunteer_edition_email", "volunteer", type_="unique"
)
def downgrade() -> None:
op.create_unique_constraint(
"uq_volunteer_edition_email", "volunteer", ["edition_id", "email"]
)