gigafibre-fsm/apps/ops/src/features/workforce/api/assignment.js
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

40 lines
2.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* API d'assignation UNIFIÉE — chemin d'écriture UNIQUE (via targo-hub).
* -----------------------------------------------------------------------------
* CONVERGENCE Dispatch ⇄ Planification : l'assignation job→tech
* (`assigned_tech` / `scheduled_date` / `route_order` / `start_time` / `status`
* + l'ÉQUIPE) ne doit JAMAIS être écrite en direct dans ERPNext (PUT
* api/dispatch.js). Tout passe ici → le hub (lib/roster.js) qui valide, pose le
* first-fit `start_time`, garde la durée, le booking_status, et — après 1b —
* préserve les assistants. Un seul écrivain ⇒ plus de conflit « dernier qui
* écrit gagne » entre les deux UIs.
*
* NE PAS importer api/dispatch.js#updateJob pour ces champs. Utiliser ceci.
*/
import { HUB_URL as HUB } from 'src/config/hub'
async function jpost (path, body) {
const r = await fetch(HUB + path, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body || {}),
})
if (!r.ok) throw new Error('Assignment API ' + r.status + ' ' + path)
return r.json()
}
// Assigner un job à un tech sur une date (le hub pose first-fit start_time + garde durée + booking_status).
export const assign = (job, tech, date) => jpost('/roster/assign-job', { job, tech, date })
// Réordonner / re-prioriser les jobs d'un tech×jour — updates = [{ job, route_order, priority? }]
export const reorder = (updates) => jpost('/roster/reorder-jobs', { updates })
// Retirer un job du tech (retour au pool non assigné).
export const unassign = (job) => jpost('/roster/unassign-job', { job })
// Équipe (lead + assistants). assistants = [{ tech_id, tech_name, duration_h, note, pinned }].
// Le LEAD reste `assigned_tech` (inchangé) ; on ne fait qu'éditer la table-enfant `assistants`.
// Route hub /roster/job/team ajoutée en 1b (qui persiste la table-enfant + recalcule l'occupation
// des assistants pinnés). Avant 1b, cet appel échoue proprement (404) — aucune vue ne l'appelle encore.
export const setTeam = (job, assistants) => jpost('/roster/job/team', { job, assistants })