Vœu de compagnon : traité comme réciproque par le solveur
Le vœu reste à sens unique en base (A choisit B sur sa fiche, B n'a rien à faire) mais si A souhaite B, B doit désormais profiter aussi de la présence de A — dans les deux sens : affecter A d'abord fait remonter B comme candidat, et affecter B d'abord fait remonter A, même si B n'a rien demandé. - Solveur (`loader.py`) : le vœu (A → B) alimente maintenant l'ensemble effectif des deux bénévoles (A et B), pas seulement celui du demandeur. Aucun changement dans `engine.py` : il ne fait que lire un ensemble déjà symétrisé. - Mock (`buildEffectiveCompanions`) et classement par défaut (`buildEffectiveCompanionIds` dans `lib/planning.ts`, utilisé par `AssignmentPanel.tsx`) : même symétrisation, pour rester cohérents avec le vrai solveur. - La fiche bénévole (vœux affichés/édités) n'est pas touchée : c'est le seul endroit qui reste à sens unique, par construction (la réciprocité n'est qu'une lecture, jamais une donnée enregistrée — sinon éditer sa propre liste risquerait d'effacer le vœu de quelqu'un d'autre). - Nouveau test d'intégration : le bénévole qui n'a rien demandé profite quand même de la présence de celui qui l'a choisi. - CLAUDE.md à jour. Vérifié : 193 tests backend pertinents (dont le nouveau), ruff, alembic check ; typecheck/lint/build/smoke frontend. 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
166e2c3366
commit
11bc8cbe36
@@ -85,11 +85,13 @@ les tables sauf les tables d'association.
|
||||
voudrait tenir »), distinct de `Assignment` (décision) et de `Position.
|
||||
lead_account_id` (référent).
|
||||
- Vœux de compagnon : `volunteer_companion_wish` (« bénévoles avec qui je
|
||||
voudrais être affecté », 0 à N, à sens unique — A peut souhaiter B sans que
|
||||
B ne le souhaite en retour). `CHECK (volunteer_id <> companion_id)` : un
|
||||
bénévole ne peut pas se souhaiter lui-même. Le solveur (section 4)
|
||||
favorise un candidat dont l'un des compagnons souhaités est déjà affecté
|
||||
au créneau.
|
||||
voudrais être affecté », 0 à N). **Saisi à sens unique** (A souhaite B sans
|
||||
que B fasse le geste en retour) **mais traité comme réciproque par le
|
||||
solveur** (section 4) : si A souhaite B, B profite aussi de la présence de
|
||||
A, même s'il ne l'a rien demandé — la réciprocité est artificielle, calculée
|
||||
à la volée (le loader du solveur, pas la table elle-même, qui reste à sens
|
||||
unique et éditable indépendamment par chacun). `CHECK (volunteer_id <>
|
||||
companion_id)` : un bénévole ne peut pas se souhaiter lui-même.
|
||||
- **`Position`** : `name`, `location`, `category` (`PositionCategory`),
|
||||
`lead_account_id` (→ `Account`, `SET NULL` à la suppression du compte).
|
||||
- **`Shift`** : `position_id`, `day_part_id` (nullable ; le créneau type dont
|
||||
@@ -291,9 +293,9 @@ affectation n'est jamais persistée par cet endpoint.
|
||||
- malus si le créneau chevauche le passage d'un artiste que le bénévole
|
||||
veut voir (`VolunteerArtist` + `Artist.start_time`/`end_time`) — lui
|
||||
ferait manquer le passage ;
|
||||
- bonus par compagnon souhaité (`VolunteerCompanionWish`) déjà affecté
|
||||
(affectation décidée) au créneau — plusieurs compagnons présents
|
||||
cumulent le bonus ;
|
||||
- bonus par compagnon souhaité (`VolunteerCompanionWish`, **réciproque** :
|
||||
si A souhaite B, B en profite aussi) déjà affecté (affectation décidée)
|
||||
au créneau — plusieurs compagnons présents cumulent le bonus ;
|
||||
- léger malus pour les bénévoles déjà bien chargés (répartition de la
|
||||
charge).
|
||||
- **Pas de plafond de cumul journalier côté solveur** : contrairement à la
|
||||
|
||||
Reference in New Issue
Block a user