gigafibre-fsm/docs/features/legacy-dispatch-bridge.md
louispaulb 70bf25ea84 feat(dispatch): pont legacy(osTicket)→Dispatch Job pour les tickets « Tech Targo »
Tire régulièrement les tickets ouverts assignés au compte « Tech Targo » (staff 3301)
de la DB legacy MariaDB et crée/maj un Dispatch Job ERPNext (pool à répartir).

- lib/legacy-dispatch-sync.js : fetch (status=open AND assign_to=3301) + mapping
  customer (legacy_account_id) / Service Location (coords) / job_type (dept) /
  scheduled_date (epoch→America/Toronto) / start_time (am|pm|HH:MM) / priority
- Idempotent via Custom Field Dispatch Job.legacy_ticket_id (lookup avant create) ;
  ne clobbe pas le travail du répartiteur (maj date seulement si encore open+non assigné)
- SÉQUENTIEL (frappe_pg) ; endpoints GET preview (dry-run) + POST run
- Récurrence opt-in : startSync() au boot, LEGACY_DISPATCH_SYNC=on + _MIN=15
- server.js : route /dispatch/legacy-sync + startSync()
- doc docs/features/legacy-dispatch-bridge.md + index

Mise en service : 70 tickets importés (0 erreur), récurrence 15 min active.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 09:33:53 -04:00

4.0 KiB

Pont legacy → Dispatch (osTicket → Dispatch Job) — Handoff dev

Tire régulièrement les tickets ouverts assignés au compte « Tech Targo » dans la DB legacy (osTicket/MariaDB gestionclient) et crée/maj un Dispatch Job ERPNext pour les répartir (grille Planification / tableau Dispatch).

Pourquoi « Tech Targo » = staff id 3301

Dans le legacy, le travail terrain à dispatcher est assigné au compte générique « Tech Targo » (staff.id = 3301, username tech) — c'est le default_staff des départements techniciens (Installation/Réparation/Fibre). Filtre du pont : ticket.status='open' AND ticket.assign_to=3301. (~70 tickets au démarrage.) Override possible via LEGACY_TARGO_STAFF_ID.

Surfaces

Quoi
Module services/targo-hub/lib/legacy-dispatch-sync.js
Routage + scheduler services/targo-hub/server.js (/dispatch/legacy-sync, startSync() au boot)
Champ idempotence Custom Field Dispatch Job.legacy_ticket_id (dispatch-app/frappe-setup/setup_dispatch_custom_fields.py)
Conso côté UI Pool « à assigner » du tableau Dispatch + panneau « Jobs à assigner » de la Planification

Mapping ticket legacy → Dispatch Job

Dispatch Job Source legacy Notes
legacy_ticket_id ticket.id clé d'idempotence (lookup avant create)
ticket_id 'LEG-' + ticket.id nom lisible du DJ
subject ticket.subject + adresse ajoutée si pas de Service Location
customer Customerlegacy_account_id = ticket.account_id 61/70 matchés ; sinon laissé vide
service_location + latitude/longitude Service Location du customer (ville qui matche) → pin carte
job_type ticket.dept_id → {Installation, Réparation, Retrait, Autre} valeurs valides du Select
scheduled_date ticket.due_date (epoch) converti America/Toronto (anti-décalage UTC)
start_time ticket.due_time HH:MM tel quel · am→08:00 · pm→13:00 · day→aucune
priority ticket.priority (1/2/≥3) → low / medium / high
duration_h défaut par type Install 2h · Répar 1.5h · autre 1h (le legacy n'en a pas)
status toujours open (pool ; PAS auto-assigné à un tech précis)

Comportement

  • Idempotent : 1 ticket legacy = 1 Dispatch Job (clé legacy_ticket_id). Re-run ⇒ 0 doublon.
  • Ne clobbe PAS le répartiteur : un DJ déjà assigné/déplacé n'est plus touché ; maj de scheduled_date seulement tant qu'il est encore open + non assigné.
  • SÉQUENTIEL (frappe_pg ne supporte pas la concurrence) — pas de Promise.all.

Endpoints

  • GET /dispatch/legacy-sync/previewdry-run, 0 écriture : ce qui serait créé + matching client/SL + non-matchés.
  • POST /dispatch/legacy-sync/run — exécute la synchro (création/maj). Retourne {tickets, created, updated, skipped, errors, unmatched_customer}.

Récurrence

startSync() (server.js, au boot) — opt-in via env :

LEGACY_DISPATCH_SYNC=on        # active la récurrence (sinon preview/run manuels seulement)
LEGACY_DISPATCH_SYNC_MIN=15    # période en minutes (défaut 15)

Posé dans /opt/targo-hub/.env. ⚠️ Après modif de .env, recréer le conteneur (cd /opt/targo-hub && docker compose up -d) — docker restart ne relit pas l'env_file. 1er passage différé de 90 s après le boot, puis toutes les MIN minutes.

État (mise en service 2026-06-06)

70 tickets importés (0 erreur, 9 clients non matchés = comptes post-migration + 2 tickets internes « FORMATION EN HAUTEUR »). Récurrence active (15 min).

TODO / idées

  • Fermer/annuler le Dispatch Job quand le ticket legacy passe closed (v1 ne gère que open).
  • Filtrer les départements non-terrain (ToDo, Support Informatique, Conception…) si bruit.
  • Matcher les 9 clients manquants (créer le Customer ou enrichir legacy_account_id).
  • Écrire en retour le tech assigné / la date vers le legacy (bidirectionnel) — non fait (lecture seule legacy).