gigafibre-fsm/docs/field-tech-app.md
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

53 lines
4.9 KiB
Markdown
Raw Permalink 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.

# App technicien & capture passive du temps (durées apprises)
> But : mesurer **sans effort tech** le temps réel passé par job → apprendre les durées par **type × technicien** → alimenter le recommandeur « prochaine dispo » et le solveur. Principe directeur : **aucun tap dédié** — la durée se *déduit* d'événements que le tech produit déjà + géorepérage GPS automatique.
## 1. Modèle « fil de checkpoints »
Chaque job accumule des **checkpoints** horodatés (et géolocalisés). La durée réelle = **1er checkpoint sur place → dernier** (ou entrée→sortie de géorepérage).
| Type de checkpoint | Source | Effort tech |
|---|---|---|
| `geo_enter` / `geo_exit` | Géorepérage GPS (zone de l'adresse) | **nul** (auto) |
| `scan` (série / MAC / code-barre) | Caméra app (modem, ONU, mesh, STB) | déjà fait (activation) |
| `photo` / `signature` | App | déjà fait |
| `reply` | Réponse au ticket | déjà fait |
| `manual_start` / `manual_finish` | Override répartiteur (Ops) ou tech | filet de sécurité |
**Dérivation** : `actual_start` = 1er checkpoint « sur place » (geo_enter, ou 1er scan/photo/reply à < R m de l'adresse) ; `actual_end` = dernier ; `actual_minutes = end start`. Les checkpoints hors-zone (> R m) sont ignorés pour la durée mais conservés pour l'audit.
## 2. Backend (cette itération — indépendant de l'app)
- **Endpoint public token-gated** `POST /field/checkpoint` `{ token, type, ts, lat, lon, acc, ref }` → vérifie le token (HMAC du job), enregistre le checkpoint, recalcule `actual_start/end` du Dispatch Job, ajoute une ligne d'audit dans `completion_notes`. Réponse : `{ ok, on_site, distance_m, minutes }`.
- **Lecture** `GET /field/job?t=<token>` → infos job (sujet, client, adresse, coords, état) pour l'app.
- **Token** = `base64url(jobName).hmac12` signé (`crypto`, secret stable du hub) → stateless, valable pour tout job, aucun champ DB ni login.
- `/field` + `/field/*` câblés **publics** dans `server.js` (calqués sur `/book`, hors forwardAuth Authentik).
## 3. App Capacitor (projet natif dédié — `apps/field-tech/`)
Véhicule unique pour les techs (remplace le mobile legacy) :
- **Géorepérage arrière-plan économe** : `@transistorsoft/capacitor-background-geolocation` (référence batterie + geofencing natif iOS/Android) — ou `@capacitor-community/background-geolocation` pour démarrer. On enregistre un geofence par job du jour ; `enter`/`exit` → POST `/field/checkpoint`.
- **Scan caméra** : `@capacitor-mlkit/barcode-scanning` → série/MAC → checkpoint `scan` **et** push vers GenieACS (par MAC) — réunit l'item roadmap « scan série/MAC des devices ».
- **Offline-first** : file d'attente locale (Preferences/SQLite) → rejoue les checkpoints à la reconnexion.
- **Auth** : login Authentik (groupe `tech`) → l'app reçoit ses jobs du jour + un token par job ; ou device-token. (À finaliser.)
- **Push** : web-push/FCM (déjà côté legacy) pour les nouvelles assignations.
- Builds : iOS (TestFlight) + Android (APK interne) ; permissions localisation « toujours » + caméra.
## 4. Amorçage SANS app (mineur legacy — cette itération)
Estimer une 1re durée par ticket depuis les événements legacy **déjà horodatés** : `ticket_msg.date_orig` du staff (réponses), création `device` (scan série), activation Ministra. Fenêtre sur-site ≈ (dernière activité première) le même jour, filtrée < 8 h (exclut le multi-jour). **Bruité à l'unité, mais l'agrégat (médiane par type) donne une baseline d'apprentissage dès aujourd'hui.** Rapport `GET /dispatch/legacy-sync/mine-durations` (lecture seule).
## 5. Boucle d'apprentissage (consomme les durées)
1. Capture (checkpoints app + override Ops + baseline minée) `actual_minutes` par job.
2. Agrégation : **médiane / p75 par sous-type × tech** (sous-types fins par mots-clés du sujet : « modem » vs « fil/fibre/drop » vs « ONT » vs « install »).
3. Remplace la table statique `DUR` (util/legacy-parse) + affine `skill_eff` (facteur vitesse par tech×compétence).
4. Le recommandeur « prochaine dispo » (`bookingSlots/fitBooking`) utilise la durée apprise ajustée au tech.
## 6. Phasage
- **P1 (maintenant)** : backend checkpoints 2) + mineur legacy 4).
- **P2** : recommandeur « prochaine dispo » (UI Ops) + sous-types fins + durées seed.
- **P3** : app Capacitor 3) scaffold geofence scan offline stores.
- **P4** : agrégation apprise 5) qui remplace les seeds, une fois les données accumulées.
## 7. Sécurité / contraintes
- Endpoint checkpoint **public mais token-gaté** (HMAC par job) ; pas de PII dans le token.
- N'écrit QUE sur le Dispatch Job (ERPNext) ; ne touche pas le legacy en écriture.
- GPS = **preuve + contrôle de distance**, pas du tracking continu serveur (le geofencing reste sur l'appareil).
- Le tap répartiteur ▶/⏹ (Ops) reste comme override/fallback.