Créneaux types : paramétrage + génération auto des créneaux
Le paramétrage des créneaux se fait dans « Règles & édition » : la coordination
définit des créneaux types (DayPart). À la création d'un poste, un créneau à
besoin 0/0 est généré pour chaque jour de l'édition et chaque créneau type ;
les coordinateurs ajustent ensuite min/idéal.
Back-end :
- DayPart CRUD (GET/POST/PATCH/DELETE /editions/{id}/day-parts). Code figé
après création (slugifié depuis le libellé si absent), unique par édition.
- Shift.day_part_id (nullable, SET NULL) + migration 0004.
- create_position génère les créneaux ; POST .../positions/{pid}/generate-shifts
recrée les manquants (idempotent, ne touche pas aux besoins déjà réglés).
- 13 tests (day-parts, génération, extension d'édition, ajout de type).
Front-end :
- api/hooks/mock : dayParts CRUD + positions.generateShifts.
- ConfigRules : panneau « Créneaux types » (libellé + horaires éditables,
ajout, suppression).
- ConfigGrid : bouton « Générer les créneaux » sur l'en-tête du poste.
- GrillePage : case « à définir » (gris, glyphe ·) quand min=idéal=0, avec
entrée de légende.
155 tests back OK ; typecheck + lint + build + smoke front OK.
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
cee581b832
commit
f58ec00e30
@@ -57,10 +57,12 @@ les tables sauf les tables d'association.
|
||||
- **`Edition`** : `year`, `name` (opt.), `start_date`, `end_date`,
|
||||
`retention_days` (durée de rétention des données nominatives en jours,
|
||||
`NULL` = pas de purge).
|
||||
- **`DayPart`** : découpage d'une journée propre à l'édition (nombre et bornes
|
||||
libres, paramétrable par la coordination). `code`, `label`, `start_time`,
|
||||
`end_time` (`end_time < start_time` ⇒ passe minuit), `order`. Unique
|
||||
(`edition_id`, `code`).
|
||||
- **`DayPart`** (« créneau type ») : découpage d'une journée propre à l'édition
|
||||
(nombre et bornes libres). `code`, `label`, `start_time`, `end_time`
|
||||
(`end_time < start_time` ⇒ passe minuit), `order`. Unique (`edition_id`,
|
||||
`code`) ; `code` figé après création (clé de l'import des disponibilités).
|
||||
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`, `tshirt_size`, `diet`, `comment`. Pas de date de
|
||||
@@ -69,8 +71,13 @@ les tables sauf les tables d'association.
|
||||
(`volunteer_skill`). N-N `Shift` (`shift_required_skill`).
|
||||
- **`Position`** : `name`, `location`, `category` (`PositionCategory`),
|
||||
`lead_account_id` (→ `Account`, `SET NULL` à la suppression du compte).
|
||||
- **`Shift`** : `position_id`, `starts_at`, `ends_at` (peut finir le
|
||||
lendemain), `min_staff`, `ideal_staff`, compétences requises (N-N `Skill`).
|
||||
- **`Shift`** : `position_id`, `day_part_id` (nullable ; le créneau type dont
|
||||
il est issu, `SET NULL` si le type est supprimé), `starts_at`, `ends_at`
|
||||
(peut finir le lendemain), `min_staff`, `ideal_staff`, compétences requises
|
||||
(N-N `Skill`). À la création d'un `Position`, un `Shift` à 0/0 est généré par
|
||||
jour de l'édition et par `DayPart` ;
|
||||
`POST /editions/{id}/positions/{pid}/generate-shifts` recrée les manquants
|
||||
(après ajout d'un créneau type ou extension des dates).
|
||||
- **`Availability`** : `volunteer_id`, `date`, `day_part_id`, `status`
|
||||
(`AvailabilityStatus`). Unique (`volunteer_id`, `date`, `day_part_id`).
|
||||
- **`Assignment`** : `volunteer_id`, `shift_id`, `source` (`AssignmentSource`,
|
||||
@@ -253,9 +260,10 @@ fonctions d'IA. *(L'envoi d'emails par SMTP est en place — voir § 2.)*
|
||||
│ │ ├── db.py # engine + session
|
||||
│ │ ├── logging_config.py # RGPD : pas de PII dans les logs
|
||||
│ │ ├── api/ # routers + schemas Pydantic + deps
|
||||
│ │ │ # health, auth, accounts, imports,
|
||||
│ │ │ # volunteers, positions, shifts,
|
||||
│ │ │ # assignments, matrix, notifications
|
||||
│ │ │ # health, auth, accounts, editions,
|
||||
│ │ │ # day_parts, imports, volunteers,
|
||||
│ │ │ # positions, shifts, assignments,
|
||||
│ │ │ # matrix, notifications
|
||||
│ │ ├── auth/ # mot de passe + lien magique + JWT + rôles
|
||||
│ │ ├── email/ # SMTP (sender) + rendu des emails (templates)
|
||||
│ │ ├── importing/ # import CSV/Excel (parser, values, service)
|
||||
@@ -342,7 +350,8 @@ Aucune dépendance locale requise hors Docker.
|
||||
| 8 | Second système : connexion mot de passe (bcrypt) pour la coordination | validée |
|
||||
| 9 | Suppression du statut d'affectation (plus d'étape de confirmation) | validée |
|
||||
| 10 | Envoi d'emails par SMTP : lien magique + récapitulatif de planning | validée |
|
||||
| 11 | `GET`/`PATCH /editions/{id}` (nom, dates) — ajouter/retirer des jours ; UX config front | à valider |
|
||||
| 11 | `GET`/`PATCH /editions/{id}` (nom, dates) — ajouter/retirer des jours ; UX config front | validée |
|
||||
| 12 | Créneaux types (`DayPart` CRUD) + génération auto des créneaux 0/0 à la création d'un poste ; case « à définir » / « sureffectif » sur la grille | à valider |
|
||||
|
||||
**Reste hors périmètre** (modèle prêt à les accueillir) : solveur OR-Tools,
|
||||
SMS, constructeur de formulaire, pointage sur site, IA. Frontend :
|
||||
|
||||
Reference in New Issue
Block a user