louispaulb
|
7d1a5b067f
|
feat(dispatch): persistent URGENT flag per job (SLA/commercial)
Like the omnichannel inbox urgent flag, but for jobs â a đ© that
persists and drives the optimizer.
- hub: durable job-flags store (data/job-flags.json) mirroring
job-levels â getJobFlags/setJobFlag + POST /roster/job-flag {name,
urgent}; buildUnassigned sets j.urgent; invalidatePool on write.
- SPA: đ© chip on each review entry (replaces the session âĄ). Optimistic
local toggle + persists via roster.setJobFlag; reflects j.urgent from
the pool. Flagged jobs â priority_boost (never dropped) + urgent_weight
(served early). Bumped urgent early-weight 6â10.
Verified: flag round-trips (setâurgent, revertâcleared) through the pool;
chips render (đ©/AM/PM).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-07-02 15:16:13 -04:00 |
|
louispaulb
|
8b2d7b54e9
|
feat(dispatch): pre-wired sites â install time Ă·4 (Lac des pins/Camping/Domaine Dauphinais)
estimateForJob: an INSTALLATION whose location matches a pre-wired site
(Lac des pins, Camping, Domaine Dauphinais) takes Œ of the normal time
(infra already in place). Applied at the estimator source â flows into
est_min everywhere (greedy duration, VRP service_min, occupancy, travel).
Floored at 15 min; adds a "site prĂ©-cĂąblĂ© ĂÂŒ" label. Verified: Lac des
pins install 120â30 min; normal install unchanged.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-07-02 15:08:33 -04:00 |
|
louispaulb
|
96929bed6f
|
feat(dispatch): OSRM road-time matrix for the VRP optimizer (Phase 2)
Replace the haversine straight-line estimate with real road travel times
from a self-hosted OSRM (free/offline â Mapbox Matrix is billable).
- hub: osrmMatrix() calls OSRM /table for the job+home coords (node order
matches route_solver: jobs then homes), returns a minutes matrix.
Handles PARTIAL coords â OSRM for geolocated nodes, 0/neutral for the
rest (matches the solver's own fallback), so a few tech homes without
coords don't disable OSRM for the geolocated majority. /roster/
optimize-routes injects body.matrix; graceful fallback to haversine if
OSRM is unreachable or too few points.
- config: OSRM_URL (default http://osrm:5000).
- services/osrm/README.md: reproducible setup (Québec extract, MLD
pipeline, osrm-routed on erpnext_erpnext network).
Deployed + verified: OSRM /table hit with the full coord set, no
fallback; optimizer routes on real road times.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-07-02 13:48:43 -04:00 |
|
louispaulb
|
a6508845a7
|
feat(dispatch): VRP route optimizer (OR-Tools) â "Optimiser" mode
Real vehicle-routing optimization behind the Suggérer UI, reusing our
existing OR-Tools solver service (no new stack). Fixes the greedy's
structural limits (sector-splitting, no global optimization).
- roster-solver: new route_solver.py (OR-Tools Routing / VRPTW).
Minimizes real travel; skills = hard filter (VehicleVar â allowedâȘ{-1};
SetAllowedVehiclesForIndex has a broken Span typemap in ortools 9.15);
on-site service time within each tech's shift window; optional per-job
time windows; unfittable jobs left unassigned (drop penalty) instead of
infeasible; specialist bias via skill order (per-vehicle arc cost).
New POST /route endpoint. Dockerfile now COPYs route_solver.py.
Unit-tested: skills respected, sectors consolidated, edge cases safe.
- hub: POST /roster/optimize-routes â proxies to solver /route.
- ops SPA: "⥠Optimiser" strategy. Greedy buckets jobs into days +
placeholders, then the solver re-optimizes each day (assignment +
routes) among shifted techs; result maps into the same review dialog
(occupation bars, route map, swap/merge reused). Graceful fallback to
greedy if the solver is unreachable (never drops jobs). shiftWindowMin
derives each vehicle's shift from templates.
Phase 2 (later): OSRM/Mapbox road-time matrix for exact travel times.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-07-02 11:24:08 -04:00 |
|
louispaulb
|
aa6cc3e732
|
feat(dispatch): niveau requis persistant + lasso freeform + routes réelles Mapbox
- Niveau requis PAR JOB persistant : store hub durable (job-levels.json) + endpoint
POST /roster/job-level + buildUnassigned enrichit required_level ; pastille « niv »
écrit via l'API (survit reload/session). NB : l'API Custom Field ERPNext v16 échoue
(IndexError) sur ce doctype custom â store hub (migratable en champ ERPNext plus tard).
- Lasso FREEFORM : tracĂ© libre (souris + tactile) â polygone SVG + point-in-polygon sur
les pins/amas projetés (remplace le rectangle) + expansion des amas (getClusterLeaves).
- D v2 : carte des tournĂ©es = routes ROUTIĂRES rĂ©elles (Mapbox Directions par tech,
domicileâarrĂȘts) + distance/temps RĂELS dans la lĂ©gende (cache par signature ;
fallback segments droits + estimation haversine).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-07-02 09:18:33 -04:00 |
|
louispaulb
|
512c4a5f1b
|
feat(ops): dispatch auto complet + perf BoĂźte/rapports + fix session
Planificateur « Suggérer » : 4 stratégies (smart / meilleurs d'abord / équilibré /
juste ce qu'il faut), compétences+niveaux par tech (édition inline), niveau requis
par compĂ©tence + par job, carte des tournĂ©es (1 couleur/tech, domicileâarrĂȘts,
sĂ©lecteur de jour), fenĂȘtre de dispatch auj.+demain (dates sĂ©lectionnĂ©es), rĂšgle
week-end + placeholder « en attente du quart », clustering + lasso + filtre-date
sur la carte, accÚs rapide « à assigner » (badge).
BoĂźte : liste /conversations allĂ©gĂ©e (45 Mo â ~1 Mo, 17Ă) + messages chargĂ©s Ă
l'ouverture. Rapports : cache SWR sur revenue-explorer (22Ă). Session : keep-alive
+ timeout fetch global + authFetch durci â fin des rechargements manuels.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-07-02 08:49:35 -04:00 |
|
louispaulb
|
0f65c02d83
|
feat(fsm): platform build â comms UI, FâERPNext sync/billing, roster, campaigns, network, reports
Accumulated work on the dispatch/legacy-writeback branch:
- Communications UI: CommunicationsPage, ConversationFullPage, DepartmentBoard,
PipelineBoard, ReaderStack, Orchestrator/NewTicket/ServiceStatus/Outbox dialogs;
hub gmail.js, ticket-collab.js, outbox.js, coupon-triage.js, client-diag.js.
- Billing/sync mirror (FâERPNext): legacy-payments.js, legacy-sync.js,
sync-orchestrator.js, supplier-invoices.js, municipality.js + incremental
migration scripts; LegacySyncPage, SupplierInvoices + negative-billing /
terminated-active reports.
- Roster/campaigns/network/voice: roster + roster-assistant, campaigns, giftbit,
olt-snmp, traccar, twilio, vision, tech-absence-sms, ai/agent/config/helpers,
legacy-dispatch-sync; ops PlanificationPage, RapportsPage, Settings, Tickets,
ClientDetail updates.
- docs/ PLATFORM_GUIDE + UI_AND_OPTIMIZATION; .gitignore __pycache__.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-15 06:12:12 -04:00 |
|
louispaulb
|
98458861c3
|
feat(dispatch): capacité AM/PM, durées additives, capture terrain (/field), sync techs
Hub (lib/roster.js, vision.js, legacy-dispatch-sync.js, server.js) + Ops + pont legacy.
- Capacité par jour AM/PM (Soir = réserve garde/urgence, jamais offerte) calculée
client-side sur les techs visibles -> suit le filtre de compétence.
- ModÚle de durée ADDITIF (caractéristiques, tableur inline) + auto-détection
DĂTERMINISTE par mots-clĂ©s (sans IA permanente) ; est_min branchĂ© sur capacitĂ© + pool.
- Capture terrain passive : endpoints publics /field (job/tech/checkpoint/ts/photo/
device/vision), tokens HMAC signés sans PII ; dérive actual_start/end. UI hébergée
public/field-app.html (liste/carte Mapbox/Street View/photo/scan MLKit->Gemini).
- Chrono job (start/finish), repositionnement carte (set-location), vue satellite,
Street View clic-droit, année devant les dates dues groupées.
- Sync techniciens : rapport de réconciliation 3 systÚmes (staff legacy / Dispatch
Technician / groupe Authentik), application MANUELLE, zéro écriture Authentik (+11 fiches).
- vision.js : extractEquipment() réutilisable (marque/modÚle/série/MAC/codes-barres).
- Pont legacy (ops_reassign.php) : désassignation reflétée, fermeture ticket, retour
au pool ; notification courriel Ă l'assignation.
Déployé sur le hub ; ce commit aligne le repo sur l'état en production.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-08 19:47:21 -04:00 |
|
louispaulb
|
4abce6fd66
|
feat(dispatch): pont d'écriture legacy + adresses/coords/carte/UX Planification
Pont d'Ă©criture Ops â legacy osTicket via endpoint PHP token-gated (hĂ©rite des
droits write de l'app facturation.targo.ca â AUCUN grant DB). FidĂšle Ă ticket_view.php :
réassignation (assign_to + participant[assistants] + followed_by + ticket_msg + lock
respecté) + fermeture (status=closed + date_closed + closed_by + réouverture des enfants).
Auteur du log = utilisateur Authentik rĂ©el (email â staff legacy par email/nom).
Hub (legacy-dispatch-sync.js):
- adresse de SERVICE importée (champ address) + reimportAddresses + fillMissingCoords
- garde TERRITOIRE (rejette les homonymes hors-zone Gaspésie/Outaouais/Estrie) + centroïde CP/ville
- purgeStaleOrphans (anciens imports TT- périmés), # ticket legacy dans titre + description
- legacyWrite (POST form + X-Ops-Token lu d'un fichier), pushAssignments (reassign), closeTicketLegacy
roster.js: occupancy + unassigned-jobs exposent address/latitude/longitude.
Ops (PlanificationPage.vue):
- carte des jobs Ă assigner (pins couleur=compĂ©tence + lettre repĂšre listeâcarte), chips
filtre par type, panneau ouvert par défaut
- clics cellule: bande quart/garde + blocs jobs â tournĂ©e ; fond â menu horaire (fini le clic droit)
- éditeur de tournée: itinéraire routier réel + adresse + fil ticket (expand), refresh occupation à l'assignation
- bouton « Publier au legacy » (aperçu + â dĂ©sassigner) + « Fermer le ticket »
- fix dates (lundi calculĂ© en local â plus de dĂ©calage UTC) + nav ±1 jour
services/legacy-bridge/ops_reassign.php: endpoint (placeholders; secrets injectés au déploiement, hors repo).
scripts/migration: backfill_dispatch_address.sql + diagnostics.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-07 22:32:00 -04:00 |
|
louispaulb
|
22fbb81d3e
|
feat(planif): éditeur journée = planificateur de tournée (heures recalculées, pas d'overlap, RDV verrouillables, détails)
- FIX overlap/ordre : packedDay recalcule les heures depuis la SĂQUENCE (ordre liste) + durĂ©es + transport ;
le timeline et les heures affichĂ©es en dĂ©coulent â rĂ©ordonner/allonger repousse les suivants, plus d'overlap
- RDV Ă heure FIXE : verrou par job (đ, dĂ©faut = booking_status 'ConfirmĂ©') â garde son heure ; flexibles = enchaĂźnĂ©s
- clic sur un job â dĂ©tails (legacy_detail : dates + description) pour juger urgence/durĂ©e ; + tooltip au survol
- save persiste start_time recalculé (+ route_order/priority/duration_h) via reorder-jobs
- hub occupancy renvoie booking_status/legacy_detail/legacy_id ; reorder-jobs accepte start_time
- fix collision fmtH â fmtHM (HH:MM padded)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-06 13:56:26 -04:00 |
|
louispaulb
|
faea3b0c1a
|
feat(planif): Ă©diteur journĂ©e â rĂ©ordonnancement fiable (flĂšches+drop) + durĂ©e Ă©ditable (min) + temps de transport
- FIX rĂ©ordonnancement : flĂšches ââ (fiable) + drag-drop basĂ© sur le DROP (au lieu du splice live jittery)
- durĂ©e Ă©ditable par job en MINUTES (pas de 5, best practice prĂ©cision) â persistĂ©e via reorder-jobs (duration_h)
- temps de transport estimé entre 2 jobs (haversine sur coords Service Location, 40km/h + 5min) affiché entre les lignes
â en attendant la gĂ©oloc live (Capacitor background-geolocation, notĂ© pour plus tard)
- hub : occupancyByTechDay renvoie lat/lon par job ; reorder-jobs accepte duration_h ; total h en pied
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-06 13:41:28 -04:00 |
|
louispaulb
|
d96e7be672
|
feat(planif): Ă©diteur de JOURNĂE contextuel au clic sur le progressbar (drag-drop rĂ©ordonner + retirer)
- clic sur le progressbar â q-dialog ciblĂ© sur le techĂjour (garde le contexte de la grille derriĂšre) :
timeline visuelle (blocs colorés par compétence) + liste éditable des jobs
- rĂ©ordonnancement par DRAG-DROP (dragstart/dragover/dragend â route_order) + sĂ©lecteur de prioritĂ© + Enregistrer
- retrait d'un job (â â hub POST /roster/unassign-job : assigned_tech null, status open â retour au pool)
- bouton « Dispatch » comme échappatoire vers le tableau complet (gotoDispatch)
- réutilise occupancy/cellBands/cellBlocks/blockStyle + reorderJobs ; best-practice détail-drawer (pas de navigation pleine page)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-06 13:29:55 -04:00 |
|
louispaulb
|
510f8c10e0
|
feat(planif): blocs cellule colorés par compétence + menu réordonner/re-prioriser au clic sur le progressbar
- Blocs d'occupation = 1 job, colorĂ© par la COULEUR DE SA COMPĂTENCE (palette skills Ă©ditable),
au lieu du dĂ©gradĂ© vertârouge par taux. Hub occupancyByTechDay attache skill+job Ă chaque bloc
(skillForJob||deptToSkill) ; blockStyle â getTagColor(blk.skill).
- Clic sur le progressbar (.tl, @click.stop+@mousedown.stop) â menu : liste des jobs du techĂjour avec
rĂ©ordonnancement (flĂšches â route_order) + re-priorisation (select) + Enregistrer.
Hub POST /roster/reorder-jobs (route_order/priority, séquentiel) ; tri occupancy par route_order.
- Clic HORS du progressbar dans la cellule â menu shift inchangĂ© (crĂ©er/modifier).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-06 12:44:22 -04:00 |
|
louispaulb
|
2631ed9199
|
feat(dispatch): couleur ticket = couleur skill + fil complet du ticket + tri pool (date/ville/priorité)
- Couleurs liées aux skills (éditable/cohérent) : hub deptToSkill() déduit une compétence du type legacy
â /roster/unassigned-jobs renvoie required_skill ; PlanificationPage colore la carte par getTagColor(required_skill)
(mĂȘme couleur que le chip skill) ; bordure 5px
- Fil complet du ticket : hub /dispatch/legacy-sync/ticket-thread (ticket_msg + auteur staff, HTML nettoyé) ;
api legacyTicketThread ; RightPanel bouton « đŹ Voir le fil / commentaires » (chargĂ© au clic, messages+auteurs+dates)
- Order-by du pool dispatch : useBottomPanel.bottomSort (date|city|priority) + dropdown â
dans BottomPanel
(ville = 2e segment adresse / token sujet avant |)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-06 12:37:45 -04:00 |
|
louispaulb
|
b492e30971
|
feat(dispatch): réconciliation + heartbeat + détails ticket dans Ops + couleurs panneau roster
#1 « ne rien échapper » :
- /dispatch/legacy-sync/reconcile : compare legacy(3301,open) â Dispatch Jobs â missing/orphan (70â70, 0/0)
- /dispatch/legacy-sync/status : heartbeat (last_sync + stale) pour Uptime-Kuma
Détails ticket dans Ops (bug signalé) :
- pont extrait le 1er message du fil legacy (stripHtml) â champ legacy_detail (backfill 70)
- store legacyDetail ; RightPanel : section « Détails du ticket » ; tooltip dans le panneau roster
Couleurs panneau roster (bug signalé) :
- /roster/unassigned-jobs renvoie job_type/legacy_dept/priority/legacy_* ; PlanificationPage colore
chaque carte par type (legacyDeptColor partagĂ©) â bordure gauche
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-06 11:50:21 -04:00 |
|
louispaulb
|
e33dd8e83a
|
roster(planif): assignation drag-drop + timeline ressource + occupation + nettoyage
Panneau « jobs à assigner » v2 : multi-sélection (cases), groupes parent-enfant
surlignés, heuristique terrain/à distance (activation/netadmin pré-décochés),
prĂ©-total d'heures, aperçu d'occupation PROJETĂE au survol (barre fantĂŽme + badge).
Fix barre d'occupation figée aprÚs drop : /roster/assign-job pose désormais un
start_time (premier-trou-libre dans le shift) + garantit duration_h, sinon le job
compte dans les heures mais n'affiche aucun bloc. Nouvel endpoint
/roster/backfill-start-times (idempotent) pour rattraper l'historique.
Infobulle de cellule : nb de jobs + liste triée par priorité (occupancyByTechDay
renvoie jobs[]). Timeline contextuelle par ressource (dialogue, 0 appel réseau).
Lisibilité du drag : fantÎme compact semi-transparent décalé sous le curseur
(ne masque plus l'aperçu) + source estompée.
Scoring de prioritĂ© : hook proximitĂ© (neutre â secteur gĂ©rĂ© manuellement),
réservé à 20% du score quand la géoloc arrivera.
Refactor hub : helper partagé firstFitStart (assign-job + backfill).
Nettoyage : retrait code mort (onDeleteRosterTag, projUsedH), carte des sections
en tĂȘte de PlanificationPage. Doc : docs/features/roster.md + index.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-05 15:50:17 -04:00 |
|
louispaulb
|
9ec829fc6f
|
Planification: marquer une absence d'1 jour depuis la grille (touche A + menu)
Clic sur une case â touche « A » (bascule) ou menu « Marquer absent ce jour / Retirer l'absence » â
crĂ©e/supprime une Tech Availability d'1 jour APPROUVĂE (hachurĂ©e tout de suite). Multi-sĂ©lection
supportée (A marque toutes, re-A retire). Endpoint POST /roster/absence/set {tech,date,type,remove}
(remove ne touche que les absences d'un jour, pas les vacances multi-jours). Type défaut Congé.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-04 22:02:39 -04:00 |
|
louispaulb
|
a60a9bee91
|
Garde: génération sur un HORIZON multi-semaines (évÚnement récurrent) au lieu d'une seule semaine
Avant: « Appliquer Ă la semaine » n'Ă©crivait qu'une semaine â 1 seul tech (rotation hebdo). Maintenant
« Générer la garde » matérialise la rotation sur N semaines (4/8/12/26) d'un coup, écrit direct (publié),
navigable semaine par semaine â comme un Ă©vĂšnement rĂ©current. Endpoint /roster/garde/apply : wipe ciblĂ©
des shifts de garde dans l'horizon + recréation (idempotent, reflÚte l'édition de la séquence). Saut
d'absent conservé. (source='manuel' car le Select n'autorise que solveur/manuel.)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-04 21:58:15 -04:00 |
|
louispaulb
|
2e5ef6d001
|
Roster publish: diff au lieu de wipe+recreate â publication quasi instantanĂ©e
Avant: /roster/publish-week supprimait TOUTES les assignations de la semaine puis les recréait toutes
(~2N Ă©critures ERPNext sĂ©quentielles â plusieurs secondes/dizaines de s). Maintenant: diff par clĂ©
tech|date|shift â supprime seulement les retirĂ©es, crĂ©e seulement les nouvelles, ignore les inchangĂ©es.
Republier sans changement: 87 assignations â 0 Ă©criture, 37 ms (vs ~174 Ă©critures avant). Une modif
de quelques cellules = quelques écritures seulement.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-04 21:20:03 -04:00 |
|
louispaulb
|
fedaf53a3b
|
Planification: drapeau « longue durée » sur absence (maternité/invalidité = à remplacer)
Tech Availability gagne long_term (Check). Case à cocher « Longue durée » dans le dialogue Congés.
absencesByTechDay encode « (longue durĂ©e) » â applyTemplate force « Ă remplacer » (pas juste sauter
comme des vacances), mĂȘme si l'absence ne couvre pas toute la semaine. ComplĂšte l'intelligence
permanent vs vacances (avant: déduit de « absent toute la semaine »).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-04 20:31:39 -04:00 |
|
louispaulb
|
bb337db14f
|
Planification: hachuré = ABSENT (congé/pause), garde = pointillé ambre (sur appel hors heures)
- Hachuré gris = ABSENT (Tech Availability approuvée + En pause). Nouvel endpoint /roster/absences
(En pause global + congĂ©s approuvĂ©s par jour) â la cellule d'un tech absent est hachurĂ©e (tooltip = type).
Remplace l'ancien 'P' pause.
- GARDE = nouveau visuel: bande à CONTOUR POINTILLà AMBRE + fond ambre léger (sur appel, hors heures
d'ouverture) â distinct du travail planifiĂ© et de l'absent.
- LĂ©gende: dispo (matinâsoir) · occupation · absent (hachurĂ©) · garde (pointillĂ©). Retrait 'P pause'.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-04 19:43:47 -04:00 |
|
louispaulb
|
054deb7b97
|
Roster: la garde ne compte PAS comme heures travaillées (mise en dispo)
Garde (on_call) exclue partout des heures travaillées + du coût:
- hub statsByDay: heures = somme des shifts NON-garde ; nouveau compteur on_call/jour (techs en dispo).
- Ops: hoursOf (heures/tech + alerte heures supp) et costByDate/weekCost excluent la garde.
- nouvelle ligne de pied 'đĄïž Garde' = nb de techs en disponibilitĂ©/jour (si applicable).
Cohérent avec l'occupation (déjà hors-garde) : la garde = réserve d'urgence, ni offerte ni facturée.
Vérifié 8 juin: 112 h travaillées (garde 6 h exclue), garde=1.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-04 15:52:01 -04:00 |
|
louispaulb
|
ebb440b5d8
|
Roster: quart de Garde (on_call) = réserve d'urgence, jamais offert au booking
ModĂšle: champ on_call (Check) sur Shift Template. Un quart garde:
- N'est JAMAIS offert au booking client (techGaps retourne null) â vĂ©rifiĂ©: tech Jour+Garde
n'offre que la fenĂȘtre Jour, aucun crĂ©neau dans la plage de garde.
- Est EXCLU du dénominateur d'occupation (heures offrables), affiché à part.
- Timeline: bande HACHURĂE (vs neutre pour l'offrable) + đĄïž dans le label + tag (garde) en infobulle.
- Ăditeur de modĂšles: bascule 'đĄïž Garde' pour crĂ©er/marquer un quart de garde.
hub: fetchTemplates expose on_call; create/update template le gĂšrent. Champ ajoutĂ© Ă
setup_dispatch_custom_fields.py (persistance). Démo: Garde 18h-minuit marquée on_call.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-04 15:37:34 -04:00 |
|
louispaulb
|
2f868133d5
|
Planification: mini-timeline positionnĂ©e (fenĂȘtre rĂ©elle du shift + blocs pris)
Avant: 'J8' ne distinguait pas 7-15 de 9-17 â mĂȘmes crĂ©neaux apparents, dispo rĂ©elle diffĂ©rente.
Maintenant chaque cellule affiche: chip (lettre) + intervalle '7â15', et une mini-timeline sur un
axe de journĂ©e (06:00â21:00) oĂč la fenĂȘtre du shift est positionnĂ©e (donc 7-15 Ă gauche, 9-17 Ă
droite = visuellement distinctes) avec les blocs de jobs pris (couleur selon charge) â les TROUS
restants = créneaux offrables. Infobulle = intervalle + h occupées/h (%).
- hub occupancyByTechDay renvoie {h, blocks:[{s,e}]} (heures de début réelles des jobs).
- ops: cellWindow/axisPos/shiftStyle/blockStyle, rendu .tl/.tl-shift/.tl-blk + tick midi.
- dĂ©mo 8 juin: modĂšles Matinal 7-15 + DĂ©calĂ© 9-17, techs alignĂ©s (7â13.8, 9â18.6 surbookĂ©).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-04 15:21:04 -04:00 |
|
louispaulb
|
fd5c83d367
|
Planification: taux d'occupation par cellule (jobs assignés / heures du shift)
Chaque cellule techĂjour avec un shift affiche, sous le chip (J8), une mini-barre + % colorĂ©s
(vert <70, orange 70-99, rouge >=100 surbooké) + infobulle = intervalle du shift + h occupées/h.
Occupation = Σ duration_h des Dispatch Jobs planifiés assignés ce jour ÷ Σ heures du shift.
- hub: occupancyByTechDay(start,days) + GET /roster/occupancy â map 'TECH|date': heures.
- ops api: getOccupancy ; PlanificationPage: occCells (computed), cellOcc/occColor/cellInterval,
rendu barre + q-tooltip, chargé dans loadStats. Données démo semaine 8 juin (45/85/120%).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-04 15:13:27 -04:00 |
|
louispaulb
|
96a76812d6
|
Copilote: agit vraiment sur les absences (gerer_absence + IROPS rematch) + gig dispo
Bug: le copilote comprenait l'absence mais n'agissait pas â aucun impact. Causes:
1) prompt « par dĂ©faut analyse » â ne dĂ©clenchait pas l'action ;
2) marquer une absence n'excluait PAS des créneaux (techGaps ne testait que le statut
global En pause, pas les Tech Availability approuvées par jour) ;
3) loadBookingData calculait unavail mais ne le retournait pas (oubli) â garde inerte.
Fixes:
- roster.js: loadBookingData inclut unavail (buildUnavailability = En pause + absence_from/until
+ Tech Availability approuvées) ; techGaps exclut le tech absent ce jour-là ; export bookingSlots/fetchTemplates.
- roster-assistant.js: nouvel outil gerer_absence = crée l'absence (par jour) + trouve les RDV
impactĂ©s + RĂASSIGNE auto Ă un autre tech libre du mĂȘme crĂ©neau (IROPS), renvoie les
« à reporter ». Nouvel outil ajouter_disponibilite (tech à l'acte ouvre un créneau). Prompt
orienté ACTION (signaler une absence = instruction d'exécution).
- ValidĂ© prod (lab): copilote crĂ©e l'absence â, booking exclut le tech absent (109â104) â,
rematch DJ-âŠâAntoine mĂȘme crĂ©neau â ; donnĂ©es de test nettoyĂ©es.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-04 14:43:03 -04:00 |
|
louispaulb
|
d94623e58a
|
Booking #56: politique de créneaux offerts + holds temporaires
- getBookingPolicy() (sous-objet 'booking' du fichier policy): lead_hours, day_start/end,
days_offered, horizon_days, max_per_day, hold_minutes. AppliquĂ©e dans bookingSlots â
cohérent pour /book + vue agent + fit. ignorePolicy au moment de confirmer (slot encore libre).
- Holds en mĂ©moire (Map TTL): /roster/book/hold {date,start,minutes|release} â fenĂȘtre retirĂ©e
des dispos des autres pendant le hold; libĂ©rĂ©e Ă la confirmation. Ăvite le double-booking
pendant qu'un agent/client choisit.
- roster-assistant: DEFAULT_POLICY.booking + booking_fields/weekdays (descripteurs UI), fusion fine.
- TestĂ©: plage 10-14h filtre bien; hold 10:00 dispo 12â11.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-04 14:19:42 -04:00 |
|
louispaulb
|
20ba2a327e
|
Booking /book: grille semaine â jour â Matin/AprĂšs-midi (se situer dans le temps)
Avant: liste plate jj/mm peu lisible. Maintenant: bandeau de semaine ('Semaine du 8 â 14 juin'),
en-tĂȘtes de jour complets (lundi 8 juin), sections Matin/AprĂšs-midi. SĂ©lection 1-3 prĂ©fĂ©rences inchangĂ©e.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-04 14:04:08 -04:00 |
|
louispaulb
|
fa696fb8e9
|
Fix reschedule: notify-reschedule dĂ©sassigne (vide date/heure/tech, status open) â /book repropose des crĂ©neaux
Avant: le job gardait scheduled_date â page /book court-circuitait en 'dĂ©jĂ confirmĂ©' sans options.
Maintenant un report = vrai retour au pool â le client choisit un nouveau crĂ©neau (vĂ©rifiĂ©: 50 crĂ©neaux proposĂ©s, SMS livrĂ©).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-04 13:56:20 -04:00 |
|
louispaulb
|
b77e251e8e
|
Reschedule: endpoint aviser-client (lien /book + SMS Twilio + statut 'Ă reporter') + file 'Ă reporter' + outil copilote
/roster/job/notify-reschedule (job,phone?) â token /book + SMS + booking_status='Ă reporter'.
/roster/jobs-to-reschedule â file superviseur. Copilote: outil notifier_client_report.
Testé OK (chemin sans téléphone = sûr). Brique P5 de #55, déclenchable depuis le flux de pause.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-04 13:28:45 -04:00 |
|
louispaulb
|
1a4c45662a
|
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 |
|