gigafibre-fsm/services/roster-solver/sample_request.json
louispaulb f4138cdd75 Roster AI (planification) + prise de rendez-vous client
Solveur OR-Tools (services/roster-solver) : couverture, compétences,
équité, coût chargé, cadence/efficacité, capacité-par-job ; contraintes
dures/souples façon Timefold.

Hub (lib/roster.js) : génération via solveur, publication par réécriture
de semaine (anti-doublons), demande (effectif ou nb de jobs), cadence/coût/
compétences par tech, pause, congés (Tech Availability + approbation),
booking (slots roster-aware / fit 3-dispos / confirm) + portail public /book.
Réessai sur serialization failures frappe_pg ; appels ERP séquentiels.

Ops : page Planification (grille compacte « J8 », multi-shift, drag-select
+ undo/redo, modèles de semaine, éditeur cadence&coût, congés, SMS opt-in),
page Rendez-vous (répartiteur), jobColor tech en pause → tickets rouges.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 16:42:44 -04:00

27 lines
2.2 KiB
JSON

{
"horizon": { "start": "2026-06-08", "days": 7 },
"shift_templates": [
{ "id": "jour", "name": "Jour 8h-16h", "start_h": 8, "end_h": 16, "hours": 8 },
{ "id": "soir", "name": "Soir 14h-22h", "start_h": 14, "end_h": 22, "hours": 8 }
],
"technicians": [
{ "id": "T001", "name": "Marc Tremblay", "skills": ["fibre", "cuivre"], "max_hours_week": 40, "max_days": 5, "cost_per_h": 38, "zone_home": "Montréal", "preferred_off": ["sam", "dim"], "unavailable": [] },
{ "id": "T002", "name": "Sophie Gagnon", "skills": ["fibre"], "max_hours_week": 40, "max_days": 5, "cost_per_h": 35, "zone_home": "Laval", "preferred_off": ["dim"], "unavailable": ["2026-06-10", "2026-06-11"] },
{ "id": "T003", "name": "Hugo Thibert", "skills": ["fibre", "cuivre", "aerien"], "max_hours_week": 44, "max_days": 6, "cost_per_h": 42, "zone_home": "Montréal", "preferred_off": ["dim"], "unavailable": [] },
{ "id": "T004", "name": "Émilie Roy", "skills": ["fibre"], "max_hours_week": 32, "max_days": 4, "cost_per_h": 33, "zone_home": "Laval", "preferred_off": ["sam", "dim"], "unavailable": [] }
],
"coverage": [
{ "date": "2026-06-08", "shift": "jour", "zone": "Montréal", "required": 2, "required_skills": ["fibre"] },
{ "date": "2026-06-08", "shift": "jour", "zone": "Laval", "required": 1, "required_skills": ["fibre"] },
{ "date": "2026-06-09", "shift": "jour", "zone": "Montréal", "required": 2, "required_skills": ["fibre"] },
{ "date": "2026-06-09", "shift": "soir", "zone": "Montréal", "required": 1, "required_skills": ["aerien"] },
{ "date": "2026-06-10", "shift": "jour", "zone": "Montréal", "required": 2, "required_skills": ["fibre"] },
{ "date": "2026-06-10", "shift": "jour", "zone": "Laval", "required": 1, "required_skills": ["fibre"] },
{ "date": "2026-06-11", "shift": "jour", "zone": "Montréal", "required": 2, "required_skills": ["cuivre"] },
{ "date": "2026-06-12", "shift": "jour", "zone": "Montréal", "required": 3, "required_skills": ["fibre"] },
{ "date": "2026-06-13", "shift": "jour", "zone": "Montréal", "required": 1, "required_skills": ["fibre"] }
],
"weights": { "uncovered": 1000, "fairness": 5, "cost": 1, "preference": 8, "continuity": 4 },
"max_seconds": 10
}