Reglova · API 1.0.0

API REST de Reglova. Authentification : Authorization: Bearer <jeton>, soit un jeton de session (POST /api/auth/login), soit une clé d'API gmao_… créée par un administrateur pour une intégration (ERP, supervision, BI) ; la clé agit au nom de son compte (rôle et usines).

Webhooks : chaque événement du journal d'audit (work_order.create, work_order.transition, purchase.receive, inspection.result…) peut être poussé en POST JSON vers une URL. En-têtes X-GMAO-Event, X-GMAO-Delivery et X-GMAO-Signature: sha256=<HMAC-SHA256 du corps avec le secret du webhook>. Trois tentatives (immédiate, +5 s, +30 s). Corps : schéma WebhookPayload.

Rapports et Power BI : GET /api/reports renvoie les indicateurs calculés côté serveur sur tout l'historique, pour une période en jours UTC entiers. Pour Power BI ou un entrepôt de données, interroger cette route (JSON) avec une clé d'API dans l'en-tête Authorization: Bearer gmao_… ; éviter ?token=, qui finit dans les journaux des serveurs. Les exports CSV préfixent d'une apostrophe les textes qui ressemblent à des formules : préférer le JSON pour un traitement automatique.

Temps réel : WebSocket GET /api/live?token=… (deltas et KPI).

Hors ligne : l'application terrain met chaque geste en file sur l'appareil et le rejoue au retour du réseau. Les commandes de terrain acceptent at, l'heure du geste : 48 h au plus dans le passé, un léger futur est ramené à l'heure du serveur, au-delà d'un jour dans le futur refus (code clock). Les contrôles de sécurité (consignation, permis, habilitations, surveillance incendie) sont évalués à cette heure. Rejouer un même geste est sans effet ; les créations portent une client_ref. Chaque refus porte un code stable. L'audit garde at, received_at et deferred.

Spécification brute : /api/openapi.json (OpenAPI 3.1, à importer dans Postman, Insomnia ou un générateur de client).

Système

GET /api/health — Santé de l'API public

Réponse

object

Authentification

POST /api/auth/login — Connexion e-mail / mot de passe → jeton de session (12 h). Double authentification active : 401 « mfa_required » sans `code`, puis code TOTP à 6 chiffres. 5 échecs (mot de passe ou code) en 15 minutes bloquent l'adresse e-mail, 50 échecs bloquent l'adresse IP : 429 `rate_limited`, en-tête `Retry-After` (secondes) et `retry_after` dans le corps public

Corps

  • email* : string
  • password* : string
  • code : string

Réponse

  • token : string
  • user : object
GET /api/auth/options — Ce que la page de connexion propose : comptes de démonstration (`demo`, si le tenant de démonstration existe) et connexion unique d'entreprise (`sso.label`, ou null) public

Réponse

  • demo : boolean
  • sso : object
POST /api/auth/logout — Se déconnecter : le jeton de la session est refusé jusqu'à son échéance. `everywhere` : toutes les sessions du compte, sur tous les appareils

Corps

  • everywhere : boolean

Réponse

204 No Content
POST /api/auth/forgot — Mot de passe oublié : 202, que l'adresse existe ou non. Un compte actif reçoit par e-mail un lien d'une heure (`/acces#gmaolink_…`), un compte invité un nouveau lien d'invitation. 5 demandes par adresse et par quart d'heure (429) public

Corps

  • email* : string
  • locale : string

Réponse

204 No Content
POST /api/auth/link — À qui est un lien d'accès (réinitialisation, invitation ou activation d'un essai `gmaotrial_…`) : adresse, nom, motif, entreprise de l'essai, échéance. 410 si le lien est échu, déjà utilisé ou falsifié public

Corps

  • token* : string

Réponse

  • email : string
  • name : string
  • purpose : reset | invite | trial
  • company : string
  • expires_at : integer
POST /api/auth/reset — Choisir son mot de passe par un lien d'accès (10 caractères au moins). Le lien ne sert qu'une fois ; les sessions ouvertes du compte tombent. Lien d'activation d'un essai (`gmaotrial_…`) : l'espace du client est créé à cet instant, essai de 30 jours. 410 si le lien n'est plus valable public

Corps

  • token* : string
  • password* : string

Réponse

  • email : string
POST /api/auth/renew — Prolonger une session encore valide (écran d'atelier, poste partagé) : nouveau jeton de 12 h, rôle et nom relus dans le compte ; au plus 7 jours après la connexion (401 ensuite : se reconnecter) ; 400 pour une clé d'API, qui n'expire pas

Réponse

  • token : string
  • user : object
GET /api/auth/oidc — Connexion unique d'entreprise : activée ? libellé du bouton public

Réponse

  • enabled : boolean
  • label : string
GET /api/auth/oidc/start — Redirige vers le fournisseur d'identité (OpenID Connect, code + PKCE) public

Réponse

204 No Content
GET /api/auth/oidc/callback — Retour du fournisseur : vérifie le jeton d'identité et redirige vers le front avec la session (#sso=…) public

Réponse

204 No Content
POST /api/me/mfa/setup — Double authentification : nouveau secret TOTP et adresse otpauth:// à scanner

Réponse

  • secret : string
  • otpauth_url : string
POST /api/me/mfa/enable — Activer la double authentification avec un premier code

Corps

  • code* : string

Réponse

204 No Content
POST /api/me/mfa/disable — Désactiver la double authentification (code requis)

Corps

  • code* : string

Réponse

204 No Content
GET /api/me — Utilisateur courant (dont `reminders` : reçoit les rappels par e-mail)

Réponse

object
PUT /api/me/reminders — Recevoir ou non le rappel du matin et le récapitulatif du lundi (pour soi seulement)

Corps

  • on* : boolean

Réponse

  • reminders : boolean

Comptes

GET /api/security — Administrateur : double authentification imposée par le client (`off`, `privileged` = administrateurs et responsables, `all`) et nombre de comptes actifs qui devront l'activer selon la politique

Réponse

  • mfa_policy : off | privileged | all
  • without_mfa :
    • privileged : integer
    • all : integer
PUT /api/security — Administrateur : imposer la double authentification. Un compte visé qui ne l'a pas encore activée ne peut plus que l'activer (403 `mfa_setup_required` ailleurs) ; une session de connexion unique d'entreprise en est dispensée ; la désactiver devient impossible (422 `mfa_required`)

Corps

  • mfa_policy* : off | privileged | all

Réponse

  • mfa_policy : string
  • without_mfa :
    • privileged : integer
    • all : integer
POST /api/users/{id}/access-link — Administrateur : (ré)envoie l'invitation d'un compte invité (7 jours, la précédente est périmée) ou un lien de réinitialisation de 24 h pour un compte actif. Le lien est aussi rendu, à transmettre si l'e-mail n'est pas configuré

Corps

  • locale : string
  • send : boolean

Réponse

  • url : string
  • purpose : reset | invite
  • expires_at : integer
  • emailed : boolean
GET /api/users/{id}/personal-data — RGPD art. 15 : export des données d'un utilisateur (compte, OT, temps, messages, absences, journal d'audit)

Réponse

object
POST /api/users/{id}/erase — RGPD art. 17 : pseudonymise l'utilisateur dans tout l'historique, anonymise et désactive le compte (journal d'audit conservé)

Réponse

204 No Content
POST /api/privacy/erase — RGPD : effacement d'un demandeur sans compte (nom et e-mail)

Corps

  • name* : string
  • email : string

Réponse

204 No Content

Données

GET /api/snapshot — État complet du tenant (filtré par usines autorisées)

Réponse

Snapshot
GET /api/export/work-order-analysis.csv — Analyse prévu / réel des OT d'une période en CSV (une ligne par OT ; mêmes paramètres que GET /api/work-orders/analysis)

Réponse

204 No Content
POST /api/import/assets — Import d'équipements, CSV ou classeur Excel .xlsx (tout ou rien)

Corps

string

Réponse

object
POST /api/import/work-orders — Reprise de l'historique des interventions, CSV ou .xlsx (tout ou rien) : OT clôturés avec compte rendu et temps passés. Codes ISO 14224 facultatifs (failure_mode, mechanism, cause_code, activity, detection) : un code inconnu rejette la ligne, une ligne sans code est reprise telle quelle. Réponse : imported, et uncoded (correctifs sans mode ni cause, « non renseignés »)

Corps

string

Réponse

  • imported : integer
  • uncoded : integer
GET /api/import/work-orders/template — Modèle CSV de l'historique

Réponse

204 No Content
GET /api/export/assets.csv — Export CSV des équipements

Réponse

204 No Content
GET /api/export/work-orders.csv — Export CSV des OT, avec leurs codes ISO 14224 (même vocabulaire que la reprise d'historique)

Réponse

204 No Content
GET /api/sites/{id}/audit-dossier.pdf — Dossier d'audit PDF d'une usine (query : standard=ifs|brcgs|iatf, from, to en ms) : synthèse, interventions, réparations temporaires, levées d'hygiène, contrôles et étalonnages, consignations, permis, signatures ; empreinte SHA-256 journalisée

Réponse

204 No Content
GET /api/export/plans.csv — Export CSV des plans préventifs

Réponse

204 No Content
GET /api/export/audit.csv — Export CSV complet du journal d'audit

Réponse

204 No Content
GET /api/export/all.zip — Export complet du compte en .zip : LISEZMOI.txt, donnees.json (toutes les données des usines autorisées, sans les adresses des demandeurs), equipements.csv, interventions.csv, preventif.csv, controles.csv, pieces.csv, journal-audit.csv (droit d'audit) et fichiers/ (pièces jointes, 300 Mo au plus, les autres listées). Reste ouvert après la fin d'un essai

Réponse

204 No Content

Équipements

GET /api/assets/{id} — Fiche équipement

Réponse

Asset
PATCH /api/assets/{id} — Corriger la fiche (droit d'implantation) : nom, fabricant, modèle, année (0 : inconnue), criticité, ligne (`null` : hors ligne), numéro de série, fournisseur, valeur, dates AAAA-MM-JJ. Le code et la classe ne changent pas. Chaque champ changé est tracé dans le fil de l'équipement

Corps

  • name : string
  • manufacturer : string
  • model : string
  • year : integer
  • criticality : A | B | C
  • line_id : string
  • serial_no : string
  • supplier : string
  • cost_eur : integer
  • commissioned_on : string
  • warranty_until : string

Réponse

204 No Content
POST /api/assets/{id}/retire — Retirer du parc (rebut, vente) : plus de demande, d'OT ni de portail QR, plans préventifs désactivés, hors indicateurs ; historique gardé. 422 open_work tant qu'un OT est ouvert sur l'équipement

Corps

  • note : string

Réponse

204 No Content
POST /api/assets/{id}/reinstate — Remettre au parc un équipement retiré par erreur (ses plans restent à réactiver)

Réponse

204 No Content
POST /api/assets/{id}/restart — Remise en service d'une machine arrêtée (rôle d'exécution) : l'arrêt finit pour les OT qui la tenaient à l'heure du geste (`at`), qui restent ouverts ; une panne « machine arrêtée » déclarée après ce geste tient toujours la machine arrêtée. 422 si la machine n'est pas arrêtée (not_stopped), sous consignation (lockout_active), en cours d'intervention (in_progress) ou en attente de levée d'hygiène (hygiene_pending), ou si l'heure du geste précède l'arrêt (order)

Corps

  • at : integer — Heure du geste (ms epoch), saisie hors ligne : 48 h au plus dans le passé ; un léger futur est ramené à l'heure du serveur. Absent : heure de réception

Réponse

204 No Content
POST /api/assets/{id}/public-token — Nouveau QR code (gestion des usines) : un nouveau jeton remplace l'ancien, qui n'ouvre plus le portail de demande (QR perdu, déclarations abusives). Journalisé sans le jeton

Réponse

Asset
POST /api/assets/{id}/model — Modèle 3D depuis un lien (fichier glTF/GLB stocké en pièce jointe, ou fiche produit / image → recette générée par l'IA), une description (`prompt`) ou une pièce jointe glTF de l'équipement. `same_model` : tous les équipements du même fabricant et modèle. 413 fichier trop gros, 415 contenu non reconnu, 502 lien ou IA en échec, 503 IA non configurée

Corps

  • url : string
  • prompt : string
  • attachment_id : string
  • same_model : boolean

Réponse

ModelResult
DELETE /api/assets/{id}/model — Retour au modèle procédural du type (`?same_model=true` : tous les équipements du même modèle)

Réponse

ModelResult
PUT /api/assets/{id}/anchors — Ancrages 3D des points d'isolement et des points de mesure de l'équipement (tout ou rien ; null retire l'ancrage)

Corps

AnchorsInput

Réponse

Asset

Usines

POST /api/assets — Poser un équipement depuis le catalogue de l'éditeur (mêmes champs et règles qu'une ligne d'import ; x/z absents : zone d'attente)

Corps

  • site_code* : string
  • line_code : string
  • code* : string
  • name* : string
  • kind* : string
  • manufacturer : string
  • model : string
  • year : integer
  • criticality* : A | B | C
  • x : number
  • z : number
  • length : number
  • serial_no : string
  • supplier : string
  • cost_eur : integer
  • commissioned_on : string
  • warranty_until : string

Réponse

Asset
POST /api/sites — Créer une usine (responsable, administrateur) : place libre sur la vue réseau, équipes et canal de maintenance créés

Corps

SiteInput

Réponse

Site
PATCH /api/sites/{id} — Modifier une usine (identifiant et place sur la vue réseau inchangés)

Corps

SiteInput

Réponse

Site
PUT /api/sites/{id}/layout — Enregistrer le plan (tout ou rien) : emprise facultative, positions et rotations (radians) ; cour de 40 m autour du bâtiment

Corps

  • width : number
  • depth : number
  • placements : [
    • asset_id* : string
    • x* : number
    • z* : number
    • rotation : number
    ]

Réponse

LayoutResult
POST /api/sites/{id}/auto-layout — Implantation automatique : une rangée par ligne selon le flux, utilités au nord, silos dehors à l'ouest, allée principale au sud ; bâtiment redimensionné

Réponse

LayoutResult
PATCH /api/sites/{id}/settings — Administrateur : mode petite structure (`simple` : barre courte, clôture d'une phrase, codes de panne facultatifs) et rappels par e-mail (`reminders` : rappel du matin à 7 h et récapitulatif du lundi aux administrateurs et responsables)

Corps

  • simple : boolean
  • reminders : boolean

Réponse

object
GET /api/sites/{id}/digest-preview — Récapitulatif du lundi tel qu'il partirait maintenant, groupé par urgence (en retard, cette semaine, plus tard) avec un lien par fiche : objet, texte, HTML, `empty` (rien à signaler : il ne partirait pas), `reminders`

Réponse

  • subject : string
  • body : string
  • html : string
  • empty : boolean
  • reminders : boolean
POST /api/lines — Créer une ligne de production (code unique dans l'usine)

Corps

LineInput

Réponse

ProductionLine
PATCH /api/lines/{id} — Modifier une ligne

Corps

LineInput

Réponse

ProductionLine

Agenda

GET /api/calendars — Agendas visibles : personnels du compte, d'usine et d'équipe des usines autorisées

Réponse

[Calendar]
POST /api/calendars — Créer un agenda : personnel (tout compte, propriétaire), d'usine ou d'équipe (droit `plan`) ; fuseau de l'usine par défaut

Corps

  • kind* : personal | site | team
  • site_id : string
  • team_id : string
  • name* : string
  • tz : string
  • default_reminders : [integer]

Réponse

Calendar
PATCH /api/calendars/{id} — Renommer, changer de fuseau, rappels par défaut, archiver (propriétaire, ou `plan` et usine)

Corps

  • name : string
  • tz : string
  • default_reminders : [integer]
  • archived : boolean

Réponse

204 No Content
GET /api/calendar/occurrences — Occurrences de [from, to) (ms, 400 jours au plus) : événements visibles dépliés (répétition RFC 5545, exceptions, dérogations) et calques demandés (`layers` : work_orders, inspections, contracts, absences, on_call, preventive, qualifications, deliveries, activities, holidays, ou all). Un OT apparaît sur son jour sans heure ; un contrôle échu est « overdue » et son suivant projeté ; le motif d'une absence n'est donné qu'au droit `plan`. `no_holidays` : usines dont le pays n'a pas de fériés connus. Réponse `no-store`

Réponse

  • items : [Occurrence]
  • more : boolean
  • no_holidays : [string]
POST /api/calendar/preview — Aperçu sans enregistrement : dix premières occurrences, conflits, règle en phrase dans la langue de l'usine

Corps

EventInput

Réponse

  • occurrences : [[integer]]
  • conflicts : [Conflict]
  • describe : string
POST /api/calendar/events — Créer un événement (`schedule` pour un agenda d'usine ou d'équipe, propriétaire pour un agenda personnel). La première occurrence doit suivre la règle. Conflits (absence, chevauchement, charge du jour au-delà de 7 h, machine prise par un OT programmé) : 409 `conflicts` avec leur liste, sauf `accept_conflicts` ; ils restent dans l'audit

Corps

EventInput

Réponse

PATCH /api/calendar/events/{id} — Modifier (`scope` : all, this ou following, `occurrence` : clé « @2026-11-18T07:30 ») : une occurrence devient une dérogation ; « et les suivantes » coupe la série (COUNT partagé ou UNTIL une seconde avant, nouvel UID, `split_from`) ; un nouvel horaire de série emmène ses exceptions. 409 comme à la création

Corps

  • title : string
  • description : string
  • location : string
  • when : object — Horaire : {kind: timed, start: AAAA-MM-JJTHH:MM:SS (heure murale), tz: fuseau IANA, minutes} ou {kind: all_day, start: AAAA-MM-JJ, days}
  • rule : string
  • attendees : [object]
  • reminders : [integer]
  • busy : boolean
  • links : [object]
  • cancelled : boolean
  • accept_conflicts : boolean

Réponse

POST /api/calendar/events/{id}/cancel — Annuler un événement (organisateur, ou droit d'écriture de l'agenda)

Réponse

204 No Content
POST /api/calendar/events/{id}/rsvp — Réponse du compte invité

Corps

  • partstat* : accepted | declined | tentative | needs_action

Réponse

204 No Content
GET /api/calendar/events/{id}/event.ics — Fichier iCalendar (RFC 5545) d'un événement visible, série complète (`text/calendar`)

Réponse

204 No Content
GET /api/calendars/{id}/export.ics — Fichier iCalendar d'un agenda visible : ses événements, 30 jours en arrière et un an devant (`text/calendar`)

Réponse

204 No Content
GET /api/me/calendar-feeds — Flux d'agenda du compte ; `all=true` : ceux du tenant (`manage_users`)

Réponse

[
  • id : string
  • user_id : string
  • prefix : string
  • scope : object
  • created_at_ms : integer — Horodatage en millisecondes (epoch)
  • last_fetched_ms : integer — Horodatage en millisecondes (epoch)
  • revoked : boolean
]
POST /api/me/calendar-feeds — Créer un flux d'abonnement : calques, agendas (absent : tous ceux que le compte voit), « occupé seulement ». Le jeton `gmaocal_…` n'est rendu qu'une fois ; seule son empreinte est gardée

Corps

  • layers : [string]
  • calendars : [string]
  • busy_only : boolean

Réponse

  • feed :
    • id : string
    • user_id : string
    • prefix : string
    • scope : object
    • created_at_ms : integer — Horodatage en millisecondes (epoch)
    • last_fetched_ms : integer — Horodatage en millisecondes (epoch)
    • revoked : boolean
  • token : string
  • path : string
DELETE /api/me/calendar-feeds/{id} — Révoquer un flux (le sien ; tout flux du tenant avec `manage_users`) : sa lecture répond 404

Réponse

204 No Content
GET /api/ical/{token}/agenda.ics — Lecture d'un flux par Outlook, Thunderbird ou un téléphone, sans session : droits **actuels** du compte recalculés à chaque appel (404 si le flux est révoqué ou le compte désactivé), `ETag` et 304, `Cache-Control: private, max-age=300`, 60 lectures par heure (429). Le jeton n'ouvre aucune autre route et n'apparaît pas dans la trace public

Réponse

204 No Content

Calculs

PUT /api/assets/{id}/specs — Caractéristiques de la plaque de l'équipement (droit implantation) : remplacent les précédentes ; 422 sur une clé inconnue ou une valeur hors bornes. Elles pré-remplissent les calculateurs

Corps

object

Réponse

204 No Content
PUT /api/parts/{id}/specs — Caractéristiques techniques de l'article (droit stock), par ex. un roulement : d, D, B, C, C0, f0

Corps

object

Réponse

204 No Content
GET /api/calc — Catalogue des calculateurs (tout compte connecté, commun à tous les tenants) : entrées (clé, unité, bornes comprises, défaut, choix, condition d'affichage), sorties (clé, unité, décimales), avertissements, refus, formule, référence, calcul de sécurité, suites possibles

Réponse

[object]
POST /api/calc/{id} — Calcule sans rien enregistrer (tout compte connecté). Corps : les entrées `{clé: nombre | texte | booléen | liste}`, les absentes prennent leur défaut. 422 `out_of_range` avec `field`, `min`, `max` ; 404 sur un calculateur inconnu

Corps

object

Réponse

CalcOutcome
POST /api/work-orders/{id}/calculations — Joint un calcul à l'OT (rôle d'exécution, usine de l'OT) : le serveur refait le calcul avec sa version des formules, garde les entrées et les sorties, et avec `add_step` ajoute l'étape à cocher (clé `calc:<id>`, 50 étapes au plus) dans la langue de l'usine ; tracé dans le fil. 20 calculs au plus par OT. Idempotent par `client_ref`. 422 `calc_version` si la version diffère, `out_of_range` sur une entrée hors bornes, `closed` sur un OT clôturé

Corps

  • calc_id* : string
  • version* : integer
  • inputs* : object
  • add_step : boolean
  • client_ref : string — Référence de l'appareil (UUID, 8 à 64 caractères [A-Za-z0-9_-]) : un envoi rejoué renvoie l'enregistrement déjà créé
  • at : integer — Heure du geste (ms epoch), saisie hors ligne : 48 h au plus dans le passé ; un léger futur est ramené à l'heure du serveur. Absent : heure de réception

Réponse

CalcRecord

Stock

GET /api/parts/{id}/reorder — Point de commande proposé : sorties des 365 derniers jours (moyenne et écart type journaliers), délai moyen des commandes reçues (14 j par défaut), z 1,645 (2,326 pour une pièce critique) ; SS = z·σd·√L, PC = d·L + SS arrondi à l'unité. `min_qty` n'est pas modifié

Réponse

  • part_id : string
  • window_days : integer
  • issued : number
  • daily_demand : number
  • demand_sd : number
  • lead_time_days : number
  • lead_time_measured : boolean
  • z : number
  • safety_stock : number
  • reorder_point : number
  • current_min : number
POST /api/assets/{id}/bom/{part} — Ligne de nomenclature (qty = 0 la retire)

Corps

  • qty* : number

Réponse

204 No Content
POST /api/work-orders/{id}/parts/{part} — Ajouter un besoin à l'OT : réservé (défaut ; 422 code shortage si le disponible ne suffit pas, avec la liste des manques « not enough stock: CODE missing 4 kg; … ») ou seulement prévu (`reserve: false`, pièce à approvisionner). Un kit est éclaté en ses composants. `unit` : unité de gestion, conditionnement (paquet) ou multiple usuel (g pour un article en kg)

Corps

  • qty* : number
  • unit : string
  • reserve : boolean

Réponse

204 No Content
DELETE /api/work-orders/{id}/parts/{part} — Libérer une réservation ou un besoin prévu (kit : tous ses composants) ; ce qui est déjà sorti reste imputé, la ligne est soldée

Réponse

204 No Content
POST /api/work-orders/{id}/parts/{part}/issue — Sortir du stock sur l'OT : une partie (`qty`) ou tout le reste de la ligne ; un kit sort composant par composant, par différence de cumuls (n sorties d'un paquet = la sortie globale, au gramme près) ; au-delà du prévu, l'écart est gardé. `lot` : lot ou numéro de série tracé sur le mouvement ; `kit_id` : ligne d'un composant de kit. Saisie hors ligne : `at` (heure du geste) et `client_ref` (référence de l'appareil : la même sortie rejouée ne sort rien de plus)

Corps

  • qty : number
  • unit : string
  • lot : string
  • kit_id : string
  • at : integer — Heure du geste (ms epoch), saisie hors ligne : 48 h au plus dans le passé ; un léger futur est ramené à l'heure du serveur. Absent : heure de réception
  • client_ref : string — Référence de l'appareil (UUID, 8 à 64 caractères [A-Za-z0-9_-]) : un envoi rejoué renvoie l'enregistrement déjà créé

Réponse

204 No Content
POST /api/work-orders/{id}/reserve — « Réserver » : tous les besoins prévus de l'OT, tout ou rien (422 avec la liste des manques)

Réponse

204 No Content
POST /api/work-orders/{id}/issue — « Sortir les réservations » : tout le reste réservé de l'OT sort du stock, un mouvement par ligne

Réponse

204 No Content
GET /api/parts/{id}/explode — Besoins pour une quantité d'article (`qty`, `unit` en paramètres) : un kit est éclaté en ses composants, quantités exactes, disponible et manque de chacun

Réponse

Explosion
POST /api/parts — Créer un article ou un kit (`components`, `kit_base`), avec un conditionnement facultatif (`pack`)

Corps

object

Réponse

Part
PATCH /api/parts/{id} — Modifier un article (`components` absent : composition inchangée)

Corps

object

Réponse

204 No Content
POST /api/parts/{id}/receive — Réception (coût moyen pondéré). `unit` : conditionnement ou multiple usuel, le coût unitaire est alors celui de cette unité ; `lot` tracé sur le mouvement. Refusée sur un kit (pas de stock propre)

Corps

  • qty* : number
  • unit : string
  • unit_cost : number
  • lot : string
  • note : string

Réponse

204 No Content
POST /api/parts/{id}/count — Inventaire

Corps

  • qty* : number
  • note : string

Réponse

204 No Content

Sécurité

PUT /api/assets/{id}/isolation-points — Procédure de consignation

Corps

[
  • energy : string
  • label : string
]

Réponse

204 No Content
PUT /api/technicians/{id}/qualifications — Remplacer les habilitations d'un technicien (BR, BC, ATEX, CATEC, HAUTEUR) — contrôlées à l'affectation, au planning et à la consignation

Corps

[
  • code* : BR | BC | ATEX | CATEC | HAUTEUR
  • obtained_at* : integer — Horodatage en millisecondes (epoch)
  • expires_at* : integer — Horodatage en millisecondes (epoch)
  • issuer : string
]

Réponse

204 No Content
POST /api/work-orders/{id}/permits — Demander un permis de travail (hot_work, confined_space, height, atex) — exigé avant de démarrer selon les dangers de l'équipement

Corps

  • kind* : hot_work | confined_space | height | atex
  • at : integer — Heure du geste (ms epoch), saisie hors ligne : 48 h au plus dans le passé ; un léger futur est ramené à l'heure du serveur. Absent : heure de réception

Réponse

204 No Content
POST /api/work-orders/{id}/permits/{permit}/issue — Délivrer un permis (admin, responsable, qualité ; pas le demandeur) : toutes les précautions confirmées, 1 à 12 h

Corps

  • confirmed* : [string]
  • hours* : integer

Réponse

204 No Content
POST /api/work-orders/{id}/permits/{permit}/close — Clôturer un permis (les permis ouverts sont clôturés avec l'OT) ; `at` facultatif : la surveillance incendie part de l'heure du geste

Corps

  • at : integer — Heure du geste (ms epoch), saisie hors ligne : 48 h au plus dans le passé ; un léger futur est ramené à l'heure du serveur. Absent : heure de réception

Réponse

204 No Content
POST /api/work-orders/{id}/permits/{permit}/fire-watch — Confirmer la fin de la surveillance incendie (1 h après la clôture d'un permis de feu) ; l'OT ne se clôture pas avant ; `at` facultatif, sans tolérance sur l'heure

Corps

  • at : integer — Heure du geste (ms epoch), saisie hors ligne : 48 h au plus dans le passé ; un léger futur est ramené à l'heure du serveur. Absent : heure de réception

Réponse

204 No Content
POST /api/work-orders/{id}/lockout/{point}/{action} — Consigner (lock), vérifier (verify) ou déconsigner (unlock) un point. Corps facultatif : `at` (heure du geste, ordre de la procédure respecté, habilitation évaluée à cette heure), `energy` et `label` du point vu par le technicien — si la procédure a changé, 422 procedure_changed

Corps

  • at : integer — Heure du geste (ms epoch), saisie hors ligne : 48 h au plus dans le passé ; un léger futur est ramené à l'heure du serveur. Absent : heure de réception
  • energy : string
  • label : string

Réponse

204 No Content
POST /api/work-orders/{id}/hygiene-release — Signer la levée d'hygiène (admin, responsable, qualité) : toujours par une autre personne que celle qui a clôturé ou pointé sur l'OT, quelle que soit la zone (422 sinon)

Corps

  • note : string

Réponse

204 No Content

Interventions

POST /api/work-orders — Créer une demande d'intervention (rejouée avec la même `client_ref` : même OT renvoyé)

Corps

  • asset_id* : string
  • title* : string
  • priority* : string
  • client_ref : string — Référence de l'appareil (UUID, 8 à 64 caractères [A-Za-z0-9_-]) : un envoi rejoué renvoie l'enregistrement déjà créé
  • at : integer — Heure du geste (ms epoch), saisie hors ligne : 48 h au plus dans le passé ; un léger futur est ramené à l'heure du serveur. Absent : heure de réception
  • machine_stopped : boolean — La panne arrête la machine : elle passe « En panne » à l'heure du geste (`at`)

Réponse

WorkOrder
POST /api/work-orders/done — Intervention déjà faite, saisie après coup : OT créé clôturé, daté du travail (`done_at`, un an au plus dans le passé ; défaut : maintenant), avec son temps passé (1 à 1 440 min) ; codes de défaillance facultatifs (un correctif sans mode : mode lu dans la phrase, marqué `report.inferred`), un mode saisi doit convenir à la classe ; `technician_id` : le technicien de l'usine qui a fait le travail (défaut : la personne qui saisit)

Corps

  • asset_id* : string
  • kind : corrective | preventive | improvement
  • title* : string
  • remedy : string
  • minutes* : integer
  • done_at : integer — Horodatage en millisecondes (epoch)
  • downtime_minutes : integer
  • failure_mode : FailureMode
  • technician_id : string

Réponse

WorkOrder
PATCH /api/work-orders/{id} — Modifier titre, priorité, état kanban, notes. `base_notes` : notes sur lesquelles la saisie a été faite ; si elles ont changé entre-temps, 422 (code notes_changed) au lieu d'écraser

Corps

  • title : string
  • priority : string
  • kanban_state : string
  • notes : string
  • base_notes : string

Réponse

204 No Content
PUT /api/work-orders/{id}/checklist/{index} — Cocher ou décocher une case (idempotent ; refusé sur un OT clôturé). `failed` : true, étape faite et non conforme ; false, l'échec est retiré ; absent, seule la case change (la décocher retire aussi l'échec)

Corps

  • done* : boolean
  • failed : boolean
  • at : integer — Heure du geste (ms epoch), saisie hors ligne : 48 h au plus dans le passé ; un léger futur est ramené à l'heure du serveur. Absent : heure de réception

Réponse

204 No Content
POST /api/work-orders/{id}/checklist/{index}/escalate — « Réparation urgente » depuis une étape de checklist (rôle d'exécution) : l'étape passe faite et non conforme, un correctif priorité haute est créé au statut « Demande » sur le même équipement, titré du libellé de l'étape, lié dans les deux sens (`escalated_from`, `escalated_to`) et tracé dans les deux fils ; sans effet sur l'état de la machine. Idempotent : étape déjà escaladée ou même `client_ref` → même OT. 422 sur un OT clôturé (closed)

Corps

  • client_ref : string — Référence de l'appareil (UUID, 8 à 64 caractères [A-Za-z0-9_-]) : un envoi rejoué renvoie l'enregistrement déjà créé
  • at : integer — Heure du geste (ms epoch), saisie hors ligne : 48 h au plus dans le passé ; un léger futur est ramené à l'heure du serveur. Absent : heure de réception

Réponse

WorkOrder
PUT /api/work-orders/{id}/operations — Remplacer la gamme d'opérations (ordre de la liste). Une opération gardée (même `seq`) conserve son état ; sans `seq`, elle est numérotée à la dizaine suivante ; une opération qui a des temps passés ne peut pas être retirée (422). Changer le temps prévu ou le métier d'une opération, ou en retirer une, demande le droit de planifier (403 sinon) ; le fil trace « phase:minutes:métier » avant et après. L'avancement de l'OT suit le temps prévu des opérations faites

Corps

[
  • seq : integer
  • title* : string
  • trade* : mechanic | electrician | automation
  • planned_minutes : integer
]

Réponse

204 No Content
POST /api/work-orders/{id}/children — Créer un sous-OT (arrêt technique, révision) : même usine, nature et échéance que le parent, validé d'office si le parent l'est ; équipement facultatif (celui du parent), gamme facultative (validée avant la création : un refus ne crée rien). Trois niveaux au plus. Le parent ne se clôture pas tant qu'un sous-OT est ouvert (422, code children_open)

Corps

  • title* : string
  • asset_id : string
  • trade : mechanic | electrician | automation
  • priority : string
  • operations : [
    • title : string
    • trade : string
    • planned_minutes : integer
    ]

Réponse

WorkOrder
GET /api/work-orders/{id}/rollup — Cumul de l'OT et de tout son arbre : sous-OT ouverts, avancement, temps prévu et passé, coût réel (main-d'œuvre, pièces sorties, sous-traitance) et engagé (pièces réservées)

Réponse

Rollup
GET /api/work-orders/windows — Dates au plus tôt / au plus tard des OT ouverts (query `site_id` facultatif) : depuis l'échéance et le temps prévu restant, appro au plus tard, pièces attendues et leur commande, attente appro et retard prévu

Réponse

[Window]
GET /api/work-orders/{id}/window — Dates au plus tôt / au plus tard d'un OT (null s'il est clôturé)

Réponse

Window
PUT /api/work-orders/{id}/due — Échéance de l'OT (null : aucune) ; les sous-OT qui suivaient l'ancienne échéance suivent la nouvelle. Une commande passée avec une livraison annoncée après l'appro au plus tard d'un OT écrit une alerte (supply_late) dans son fil

Corps

  • due_at* : object

Réponse

204 No Content
GET /api/work-orders/{id}/analysis — Analyse prévu / réel de l'OT : main-d'œuvre par opération (minutes et coût), temps hors gamme, pièces prévues, réservées et consommées, sous-traitance (devis contre montant final), écarts

Réponse

Analysis
GET /api/work-orders/analysis — Analyse prévu / réel des OT actifs sur la période (créés avant sa fin, ouverts ou clôturés depuis son début) : totaux, main-d'œuvre par métier, une ligne par OT. Mêmes paramètres et droits que GET /api/reports ; seuls comptent les OT gardés en mémoire (ouverts et derniers clôturés de chaque usine)

Réponse

AnalysisSummary
POST /api/work-orders/{id}/operations/{seq}/status — État d'une opération : todo, in_progress, done (faite : auteur et heure gardés). `at` : heure du geste (saisie hors ligne)

Corps

  • status* : todo | in_progress | done
  • at : integer — Heure du geste (ms epoch), saisie hors ligne : 48 h au plus dans le passé ; un léger futur est ramené à l'heure du serveur. Absent : heure de réception

Réponse

204 No Content
POST /api/work-orders/{id}/timer/start — Démarrer le minuteur, éventuellement sur une opération de la gamme (`operation` : son numéro, qui passe en cours). Corps facultatif `at` (saisie hors ligne) : pas avant la vérification de la consignation, le dernier changement d'étape ni la fin du temps précédent de la personne ; rejouer le même geste est sans effet

Corps

  • at : integer — Heure du geste (ms epoch), saisie hors ligne : 48 h au plus dans le passé ; un léger futur est ramené à l'heure du serveur. Absent : heure de réception
  • operation : integer

Réponse

204 No Content
POST /api/work-orders/{id}/timer/stop — Arrêter le minuteur (corps facultatif `at`, pas avant le démarrage ; rejeu sans effet)

Corps

  • at : integer — Heure du geste (ms epoch), saisie hors ligne : 48 h au plus dans le passé ; un léger futur est ramené à l'heure du serveur. Absent : heure de réception

Réponse

204 No Content
POST /api/work-orders/{id}/transition — Changer d'étape. « in_progress » exige, comme le démarrage du minuteur, une consignation vérifiée de chaque point d'isolement (422 lockout) et des permis valables (422 permit). « done » est toujours refusé (422 close_with_report, ou hygiene_checks en zone d'hygiène) : un OT se clôture par POST /close, qui contrôle compte rendu, codes, déconsignation, signature et surveillance incendie

Corps

  • status* : string
  • assignee_id : string

Réponse

204 No Content
POST /api/work-orders/{id}/cancel — Annuler l'OT, ou refuser la demande s'il n'est pas validé (droit plan) : doublon (`duplicate_of`, un OT de la même usine), fausse alerte, plus nécessaire, ou autre motif écrit (422 note_required). Le technicien, les réservations et l'arrêt déclaré sont libérés ; l'OT n'entre pas dans les rapports ; le demandeur est prévenu. Refusé sous consignation (lockout_active), avec un permis délivré (permit_open) ou un sous-OT ouvert (children_open)

Corps

  • reason* : duplicate | false_alarm | not_needed | other
  • note : string
  • duplicate_of : string

Réponse

204 No Content
GET /api/work-orders/{id}/suggested-codes — Codes proposés à la clôture de l'OT : modes admis pour la classe, codes fréquents (appris des seules usines autorisées), détection déduite, codes hérités d'une réparation temporaire

Réponse

Codes
POST /api/work-orders/{id}/close — Clôturer avec compte rendu. Correctif : mode de défaillance admis pour la classe de l'équipement et cause obligatoires (422 sinon) ; mécanisme et activité complétés par le serveur ; détection enregistrée si saisie ou déductible de l'origine. Réparation définitive : codes repris de l'OT d'origine. Préventif : codes facultatifs. Sécurité : sur un équipement à points d'isolement, chaque point a été condamné puis vérifié (422 lockout_missing) et levé (422 lockout_active) ; chaque permis exigé par les dangers a été délivré à l'heure du geste (422 permit). Parent : tous ses sous-OT clôturés (422 children_open). `at` : heure du geste (saisie hors ligne) pour le compte rendu, l'historique et l'arrêt des minuteurs ; rejeu par le même auteur sans effet, sinon 422 closed. `amended` : clôture refusée puis complétée sur l'appareil, la signature et les contrôles d'hygiène prennent l'heure de réception

Corps

  • at : integer — Heure du geste (ms epoch), saisie hors ligne : 48 h au plus dans le passé ; un léger futur est ramené à l'heure du serveur. Absent : heure de réception
  • amended : boolean — Clôture complétée après un refus : signature et contrôles d'hygiène horodatés à la réception
  • problem : string
  • cause : string
  • remedy* : string
  • failure_mode : FailureMode
  • downtime_minutes : ['integer', 'null'] — Arrêt de production déclaré, en minutes. Absent ou null : la part de l'arrêt mesuré imputée à l'OT (panne déclarée « machine arrêtée ») est reprise ; 0 : la machine n'a pas été arrêtée
  • hygiene : object
  • temporary_days : integer
  • mechanism : string — Tableau B.2 ; par défaut, le mécanisme type du mode
  • cause_code : string — Tableau B.3 ; obligatoire sur un correctif
  • activity : string — Tableau B.5 ; par défaut, l'activité type du mode
  • detection : DetectionMethod
  • signature :
    • signer* : string
    • image* : string — data:image/png;base64,… (60 000 caractères au plus) ; obligatoire si l'OT est sous-traité

Réponse

204 No Content
POST /api/work-orders/{id}/schedule — Planifier l'OT (technicien et jour, sans le lancer)

Corps

  • technician_id : string
  • at : integer — Horodatage en millisecondes (epoch)

Réponse

204 No Content
GET /api/assets/{id}/report-suggestions — Descriptions proposées en puces pour signaler une panne (6 au plus) : pannes déclarées sur la même classe d'équipement (hors préventif, réparation définitive, sous-OT, réparation urgente et réserve de contrôle), dans les usines autorisées de même langue que celle de l'équipement, normalisées (casse, accents, espaces, ponctuation finale) et comptées, puis symptômes types de la classe dans la langue de l'usine. Rôle déclarant (pas « external »)

Réponse

GET /api/assets/{id}/suggested-codes — Codes ISO 14224 les plus fréquents de l'équipement (mode admis pour la classe, mécanisme, cause, activité), appris des seules usines autorisées

Réponse

Codes
POST /api/micro-stops — Déclarer un micro-arrêt (refusé pendant un arrêt déclaré : déjà compté avec la panne)

Corps

  • asset_id* : string
  • minutes* : integer
  • reason* : string
  • client_ref : string — Référence de l'appareil (UUID, 8 à 64 caractères [A-Za-z0-9_-]) : un envoi rejoué renvoie l'enregistrement déjà créé
  • at : integer — Heure du geste (ms epoch), saisie hors ligne : 48 h au plus dans le passé ; un léger futur est ramené à l'heure du serveur. Absent : heure de réception

Réponse

object

Équipe

POST /api/technicians — Créer la fiche d'un technicien (droit plan) : nom unique dans l'entreprise (422 name_taken), usine, métier, coût horaire chargé (défaut : celui du métier). Il rejoint l'équipe de son métier

Corps

  • site_id* : string
  • name* : string
  • trade* : mechanic | electrician | automation
  • hourly_rate : number

Réponse

object
PATCH /api/technicians/{id} — Corriger un technicien, le changer d'usine, le faire partir (`active: false`) ou revenir. Parti : plus affecté (422 tech_left), planifié ni d'astreinte, ses absences à venir tombent. Changement d'usine et départ refusés tant qu'il a des OT ouverts (422 tech_has_work)

Corps

  • name : string
  • trade : mechanic | electrician | automation
  • hourly_rate : number
  • site_id : string
  • active : boolean

Réponse

204 No Content

IoT

POST /api/ingest/readings — Relevés capteurs poussés par une passerelle (clé d'API, droit exécuter) : chaque tag est rattaché à un point de mesure ; filtrage par zone morte et intervalle minimal, seuils toujours évalués, OT conditionnel si dépassement. Réponse : relevés enregistrés, filtrés, tags inconnus, OT ouverts

Corps

  • samples* : [
    • tag* : string
    • value* : number
    • at : integer — Horodatage en millisecondes (epoch)
    ]

Réponse

object

Préventif

POST /api/points — Créer un point de mesure (maintenance conditionnelle) : équipement, nom, unité, seuil bas et/ou haut, tag capteur

Corps

  • asset_id* : string
  • name* : string
  • unit : string
  • low : number
  • high : number
  • tag : string
  • vibration : object — Classe vibratoire ISO 20816-3 de la machine (point en « mm/s » seulement, sinon 422) ; à la modification, absent : inchangée, null : retirée ; un changement d'unité la retire

Réponse

object
PATCH /api/points/{id} — Modifier un point de mesure (mêmes champs qu'à la création, `vibration` comprise)

Corps

  • asset_id* : string
  • name* : string
  • unit : string
  • low : number
  • high : number
  • tag : string
  • active : boolean
  • vibration : object — Classe vibratoire ISO 20816-3 de la machine (point en « mm/s » seulement, sinon 422) ; à la modification, absent : inchangée, null : retirée ; un changement d'unité la retire

Réponse

204 No Content
POST /api/points/{id}/readings — Saisir un relevé ; hors seuil, un OT préventif conditionnel est ouvert (un seul à la fois par point). `at` : relevé saisi hors ligne, replacé dans le temps

Corps

  • value* : number
  • at : integer — Heure du geste (ms epoch), saisie hors ligne : 48 h au plus dans le passé ; un léger futur est ramené à l'heure du serveur. Absent : heure de réception

Réponse

204 No Content
POST /api/plans — Créer des plans préventifs (plusieurs équipements). `operations` : gamme type recopiée dans chaque OT généré (phases 10, 20, 30…)

Corps

  • asset_ids* : [string]
  • title* : string
  • interval_hours : number
  • interval_days : integer
  • instructions : string
  • checklist : [string]
  • operations : [OperationTemplate]

Réponse

[object]
PATCH /api/plans/{id} — Modifier un plan (`operations` absent : gamme inchangée)

Corps

  • title : string
  • interval_hours : number
  • interval_days : integer
  • instructions : string
  • checklist : [string]
  • active : boolean
  • operations : [OperationTemplate]

Réponse

204 No Content
POST /api/plans/{id}/generate — Générer l'OT d'un plan

Réponse

WorkOrder

Planning

POST /api/roster — Déclarer une absence (leave, sick, training) ou une astreinte (on_call) — sans chevauchement ; un absent n'est ni affecté ni planifié

Corps

  • technician_id* : string
  • kind* : leave | sick | training | on_call
  • start* : integer — Horodatage en millisecondes (epoch)
  • end* : integer — Horodatage en millisecondes (epoch)
  • note : string

Réponse

object
POST /api/roster/{id}/cancel — Annuler une absence ou une astreinte

Réponse

204 No Content

Contrats

POST /api/work-orders/{id}/subcontract — Confier l'OT à un prestataire. `cost` : montant facturé ; `quote` : devis (coût prévu de l'analyse), modifiable tant que l'OT est ouvert — absent : inchangé (aucun pour un nouveau prestataire), `null` : retiré

Corps

  • vendor_id : string
  • cost : number
  • quote : ['number', 'null']

Réponse

204 No Content
POST /api/vendors — Créer un prestataire

Corps

object

Réponse

Vendor
PATCH /api/vendors/{id} — Modifier un prestataire

Corps

object

Réponse

204 No Content
POST /api/contracts — Créer un contrat

Corps

object

Réponse

Contract
PATCH /api/contracts/{id} — Modifier un contrat

Corps

object

Réponse

204 No Content

Achats

POST /api/purchases — Demande d'achat

Corps

  • site_id* : string
  • supplier : string
  • lines* : [
    • part_id : string
    • qty : number
    • unit_cost : number
    ]
  • work_order_id : string
  • note : string

Réponse

Purchase
POST /api/purchases/reorder — Réapprovisionnement automatique d'une usine

Corps

  • site_id* : string

Réponse

[Purchase]
POST /api/purchases/{id}/lines/{part} — Ligne d'un brouillon

Corps

  • qty : number
  • unit_cost : number

Réponse

204 No Content
POST /api/purchases/{id}/order — Passer la commande

Corps

  • supplier : string
  • expected_at : integer — Horodatage en millisecondes (epoch)

Réponse

204 No Content
POST /api/purchases/{id}/receive — Réceptionner une livraison

Corps

[
  • part_id : string
  • qty : number
]

Réponse

204 No Content
POST /api/purchases/{id}/cancel — Annuler

Réponse

204 No Content

Contrôles

POST /api/inspections — Créer un contrôle réglementaire / étalonnage

Corps

object

Réponse

Inspection
GET /api/inspections/library — Bibliothèque des contrôles usuels d'un atelier en France (VGP chariots et levage, presses, équipements sous pression, électricité, extincteurs, portes, ventilation, fluides frigorigènes, arrêts d'urgence) : classes concernées, périodicité, texte de référence indicatif, classes cochées d'office (`primary`) et mots du nom qui le font cocher (`keywords`)

Réponse

[
  • code : string
  • asset_kinds : [string]
  • kind : string
  • title : string
  • reference : string
  • body : string
  • interval_days : integer
  • note : string
  • primary : [string]
  • keywords : [string]
]
POST /api/inspections/library — Responsable : pose des contrôles de la bibliothèque. `last_at` (date du dernier contrôle) fixe la prochaine échéance ; inconnue, échéance dans 30 jours. Un contrôle déjà suivi (même intitulé, actif) n'est pas doublé ; un code inconnu ou un contrôle qui ne convient pas à la classe refuse tout le lot (2 000 au plus)

Corps

  • items* : [
    • code* : string
    • asset_id* : string
    • last_at : integer — Horodatage en millisecondes (epoch)
    ]

Réponse

  • created : integer
  • skipped : integer
PATCH /api/inspections/{id} — Modifier un contrôle

Corps

object

Réponse

204 No Content
POST /api/inspections/{id}/results — Saisir un résultat (réserves → OT de levée)

Corps

  • result* : compliant | reserves | non_compliant
  • inspector : string
  • certificate : string
  • note : string
  • at : integer — Horodatage en millisecondes (epoch)

Réponse

204 No Content

Collaboration

POST /api/threads/{model}/{id}/messages — Message ou note interne

Corps

  • body* : string
  • kind : string
  • client_ref : string — Référence de l'appareil (UUID, 8 à 64 caractères [A-Za-z0-9_-]) : un envoi rejoué renvoie l'enregistrement déjà créé
  • at : integer — Heure du geste (ms epoch), saisie hors ligne : 48 h au plus dans le passé ; un léger futur est ramené à l'heure du serveur. Absent : heure de réception

Réponse

object
POST /api/activities — Planifier une activité

Corps

object

Réponse

object
GET /api/attachments/{model}/{id} — Pièces jointes d'un enregistrement (`work_order`, `asset`, `inspection`) ; un compte limité à ses usines ne voit que celles de ses usines, même pour une fiche qui n'est plus en mémoire

Réponse

[object]
POST /api/attachments/{model}/{id} — Ajouter une photo ou un document (corps brut, en-têtes `content-type` et `x-filename`) à un OT, un équipement ou un contrôle (le PV de l'organisme, droit de planifier ; cité dans le dossier d'audit). Photo prise hors ligne : `client_id` (att-<référence>, un envoi rejoué renvoie la même pièce) et `at` (heure de la prise de vue) en paramètres

Réponse

object

Rapports

GET /api/reports — Rapport de maintenance sur tout l'historique (EN 15341) : disponibilité R1, MTBF, MTTR, taux de codification ISO 14224 (correctifs clôturés avec mode et cause), part du préventif, conformité, backlog, coûts, Pareto, tendance et comparatif entre usines. Une réparation définitive n'est pas une nouvelle défaillance (ni dans le compte, ni dans le Pareto). Rôles admin, manager, qualité ; usines autorisées seulement

Réponse

Report
GET /api/export/reports.csv — Une table du rapport en CSV (UTF-8 avec BOM, clés anglaises) : table=indicators|assets|series|sites. Les cellules texte qui commencent par = + - @ sont préfixées d'une apostrophe

Réponse

204 No Content
GET /api/export/reports.xlsx — Rapport en classeur Excel : Indicateurs (avec formules), Équipements, Tendance, Usines en vue réseau

Réponse

204 No Content

Administration

GET /api/audit — Journal d'audit

Réponse

[object]
GET /api/notifications — E-mails envoyés aux demandeurs

Réponse

[object]

Intégrations

GET /api/api-keys — Clés d'API (administrateur)

Réponse

[object]
POST /api/api-keys — Créer une clé (le jeton n'est affiché qu'une fois)

Corps

  • name* : string
  • user_email* : string

Réponse

  • key : object
  • token : string
DELETE /api/api-keys/{id} — Révoquer une clé

Réponse

204 No Content
GET /api/webhooks — Webhooks

Réponse

[object]
POST /api/webhooks — Créer un webhook (le secret n'est affiché qu'une fois)

Corps

  • url* : string
  • events : [string]

Réponse

  • webhook : object
  • secret : string
PATCH /api/webhooks/{id} — Modifier un webhook

Corps

  • url : string
  • events : [string]
  • active : boolean

Réponse

204 No Content
DELETE /api/webhooks/{id} — Supprimer un webhook

Réponse

204 No Content
POST /api/webhooks/{id}/ping — Envoyer un événement de test

Réponse

204 No Content
GET /api/webhooks/deliveries — Dernières livraisons

Réponse

[object]

Portail public

GET /api/public/{tenant}/assets/{token} — Équipement scanné (QR), sans compte : OT ouverts et descriptions fréquentes de sa classe (apprises de sa seule usine) public

Réponse

PublicAsset
POST /api/public/{tenant}/assets/{token}/requests — Demande sans compte (5 / 10 min) ; `machine_stopped` : la machine passe « En panne » aussitôt public

Corps

  • title* : string
  • requester* : string
  • urgent : boolean
  • email : string
  • machine_stopped : boolean

Réponse

  • code : string
  • reference : string
GET /api/public/{tenant}/requests/{reference} — Suivi d'une demande (aussi pour un OT clos qui n'est plus en mémoire) public

Réponse

PublicTracking
POST /api/public/{tenant}/requests/{reference}/followups — Relancer une demande ouverte depuis le lien de suivi : 3 relances au plus, une heure après la demande puis après la relance précédente (422 followup_too_soon, followup_limit ; closed si la demande est close). Message facultatif de 300 caractères, tracé dans le fil de l'OT au nom du demandeur, diffusé (écart « relancée » dans le jumeau et la cloche) et envoyé par e-mail aux comptes responsables qui voient l'usine (lien vers la fiche de l'OT). 5 appels / 10 min par référence (429) public

Corps

  • message : string

Réponse

204 No Content
POST /api/public/{tenant}/requests/{reference}/rating — Noter la réponse à une demande close : une note de 1 à 5, une seule fois (rating_done), dans les 30 jours après la clôture (rating_expired), avant la clôture refusée (rating_open) ; commentaire facultatif de 500 caractères, gardé sur l'OT seul. Une demande close sortie de la mémoire est notée en base d'un seul geste (deux appels simultanés : une seule note). Comptée au taux de satisfaction de l'usine (rapports). 5 appels / 10 min par référence (429) public

Corps

  • score* : integer
  • comment : string

Réponse

204 No Content

Landing

POST /api/public/demo-requests — Demande de présentation déposée sur la landing commerciale, sans compte : 201 et sa référence (`DP-` suivi de 10 caractères), seule donnée écrite dans les journaux. Globale à la plateforme (aucun tenant). 422 : un code stable par champ. 5 demandes par adresse e-mail et 30 pour toute la plateforme par tranche de 10 minutes (429 rate_limited). Champ piège `website` rempli : réponse 201 ordinaire, rien n'est gardé ni compté. Si `DEMO_REQUESTS_TO` et `SMTP_URL` sont définis, l'équipe reçoit un e-mail en texte public

Corps

DemoRequestInput

Réponse

  • reference* : string
POST /api/public/unsubscribe — Lien personnel de désabonnement d'un mail de rappel (`/desabonnement#gmaounsub_…`, en-tête List-Unsubscribe) : coupe les rappels de cette personne seulement. 410 si le lien est falsifié ; limite par adresse IP public

Corps

  • token* : string

Réponse

  • email : string
  • name : string
POST /api/public/signup — Essai gratuit de 30 jours sans rendez-vous (`SIGNUP=on` et SMTP configuré, sinon 404) : rien n'est créé tant que l'adresse n'est pas vérifiée ; un lien d'activation de 7 jours (`/acces#gmaotrial_…`) part à l'adresse, l'espace s'ouvre au choix du mot de passe (`/api/auth/reset`) et l'équipe commerciale est prévenue (`DEMO_REQUESTS_TO`). Toujours 202, que l'adresse ait déjà un compte ou non ; champ piège `website` ; limite par adresse IP (429). À la fin de l'essai, le compte passe en lecture seule (402 `trial_ended` sur toute écriture ; consultation et export restent ouverts) ; sans souscription, il est effacé 90 jours après la fin de l'essai, au plus tôt 7 jours après l'avertissement des administrateurs. Trois liens d'activation par adresse et par jour au plus ; nom et entreprise sans caractère de contrôle (422) public

Corps

  • company* : string
  • name* : string
  • email* : string
  • phone : string
  • locale : string
  • website : string

Réponse

204 No Content

Éditeur

GET /api/platform/tenants — Clients de l'instance (usines, comptes). Jeton de l'éditeur `PLATFORM_TOKEN` en `Authorization: Bearer` ; sans PLATFORM_TOKEN configuré, la route n'existe pas (404)

Réponse

[
  • id : string
  • name : string
  • sites : integer
  • users : integer
]
POST /api/platform/tenants — Créer un client sans redémarrer : tenant vide (identifiant de 3 à 40 caractères a-z, 0-9 et tirets) et son premier administrateur, invité : il choisit son mot de passe par un lien de 7 jours, envoyé par e-mail et rendu une seule fois. 409 si l'identifiant ou l'adresse existe

Corps

  • id* : string
  • name* : string
  • admin_email* : string
  • admin_name* : string
  • locale : string

Réponse

  • tenant :
    • id : string
    • name : string
  • admin :
    • id : string
    • email : string
    • invite : object
PATCH /api/platform/tenants/{id}/trial — Prolonger l'essai d'un client (`trial_ends_at` en ms) ou le passer sous contrat (`null`). 404 si le client n'existe plus (essai effacé entre-temps)

Corps

  • trial_ends_at : object

Réponse

204 No Content

Schémas

Error
  • error* : string
  • code* : string — Code stable du refus (closed, children_open, too_old, clock, permit, lockout, lockout_active, lockout_missing (clôture d'un OT jamais consigné ni vérifié), qualification, procedure_changed, notes_changed, fire_watch, order, timer_running, no_timer, not_planned, codes (mode ou cause de défaillance manquant), mode_class (mode non admis pour la classe de l'équipement), hygiene_checks, signature, close_with_report, machine_stopped (micro-arrêt pendant un arrêt déjà compté), not_stopped (remise en service d'une machine non arrêtée), in_progress (remise en service pendant une intervention), hygiene_pending (remise en service avant la levée d'hygiène), shortage, nothing_planned, nothing_to_issue, tech_busy, tech_absent, no_technician (affectation : technicien occupé, absent, aucun de libre), followup_limit, followup_too_soon, rating_open, rating_done, rating_expired (portail QR : relance et note), escalated (étape déjà escaladée dont la réparation n'est plus en mémoire), calc_version (calcul joint fait avec une autre version des formules), out_of_range (entrée de calcul hors bornes : `field`, `min`, `max`), rate_limited, not_found, forbidden, invalid, too_large, rejected…). shortage : `error` liste les manques « not enough stock: CODE missing 4 kg; … »
FailureModebreakdown | leak | noise | overheating | electrical | sensor | blockage | wear | adjustment | other
DetectionMethodperiodic_maintenance | functional_test | inspection | periodic_condition_monitoring | continuous_condition_monitoring | production_interference | casual_observation | corrective_maintenance | on_demand | other
Codes
  • failure_mode : FailureMode
  • mechanism : string — Mécanisme ISO 14224 (tableau B.2)
  • cause : string — Cause ISO 14224 (tableau B.3)
  • activity : string — Activité ISO 14224 (tableau B.5)
  • detection : object — Déduite de l'origine de l'OT (réserve de contrôle, mesure, portail QR, panne, plan), jamais d'une fréquence ; null si inconnue
  • inherited : boolean — Réparation définitive : codes complets repris de la réparation temporaire
  • allowed_modes : [FailureMode] — Modes admis pour la classe de l'équipement, du plus au moins probable
  • typical : object — Par mode admis : mécanisme et activité complétés par le serveur à la clôture
WorkOrder
  • id : string
  • code : string
  • site_id : string
  • asset_id : string
  • kind : string
  • priority : low | medium | high | critical
  • status : requested | approved | planned | in_progress | done
  • title : string
  • requested_by : string
  • assignee_id : string
  • history : [
    • status : string
    • at : integer — Horodatage en millisecondes (epoch)
    ]
  • report : object
  • parts : [PartUse]
  • operations : [Operation]
  • parent_id : ['string', 'null'] — OT parent (arborescence)
  • kits : [
    • kit_id : string
    • qty : number — Kits prévus ou réservés (cumul, unité de gestion du kit)
    • issued : number — Kits sortis (cumul) : chaque sortie déstocke la différence entre deux cumuls de composants
    ]
  • time_entries : [
    • who : string
    • started_at : integer — Horodatage en millisecondes (epoch)
    • ended_at : integer — Horodatage en millisecondes (epoch)
    • operation : integer — Numéro de l'opération visée (facultatif)
    ]
  • subcontract : object
  • lockout : object
  • hygiene : object
  • permits : [object]
  • checklist : [ChecklistItem]
  • escalated_from : object — Réparation urgente créée depuis une étape de checklist en échec : OT et rang de l'étape (0 pour la première)
  • followups : [integer] — Relances du demandeur sans compte (portail QR), heure de chacune ; absent si aucune
  • calculations : [CalcRecord] — Calculs joints (20 au plus), recalculés par le serveur ; absent si aucun
  • satisfaction : object — Note du demandeur sans compte, donnée après la clôture (absente sinon)
  • stop : object — Panne déclarée « machine arrêtée » : l'OT tient la machine « En panne » tant qu'il est ouvert et que `until` est null. `minutes` : part de l'arrêt de la machine imputée à cet OT. Les arrêts des OT d'une machine qui se chevauchent forment un seul arrêt, mesuré une fois ; sa durée va à l'OT qui le termine (ou à l'ouvreur en cas de remise en service), moins ce que les autres OT en comptent déjà. Reprise au compte rendu si la clôture ne déclare pas d'arrêt
ChecklistItem
  • label* : string
  • done* : boolean
  • failed : boolean — Étape faite mais non conforme (absent : conforme)
  • escalated_to : ['string', 'null'] — Réparation urgente créée depuis l'étape
  • key : string — Clé stable de l'étape (`calc:<id>` pour l'étape d'un calcul joint) ; absente sinon
CalcRecord
  • id* : string
  • calc_id* : string
  • version* : integer
  • inputs* : object — Entrées retenues (seules les clés du catalogue)
  • values* : [[object]] — Sorties recalculées par le serveur, [clé, valeur] dans l'ordre du catalogue
  • warnings* : [string]
  • step : string — Libellé de l'étape créée, dans la langue de l'usine (absent sans étape)
  • by* : string
  • at* : integer — Horodatage en millisecondes (epoch)
  • client_ref : string
CalcOutcome
  • id : string
  • version : integer
  • values : object — Sorties, dans l'ordre du catalogue
  • warnings : [string]
  • steps : [
    • key : string
    • value : number
    • unit : string
    ]
ReportSuggestion
  • text* : string
  • count* : integer — Pannes passées qui ont employé cette description (0 : symptôme du catalogue de la classe)
PublicAsset
  • code : string
  • name : string
  • site : string
  • locale : string
  • open_requests : [string]
  • suggestions : [string] — Descriptions fréquentes pour la classe de l'équipement (6 au plus), apprises de sa seule usine, dans sa langue
PublicTracking
  • code : string
  • title : string
  • asset : string
  • status : string
  • history : [
    • status : string
    • at : integer — Horodatage en millisecondes (epoch)
    ]
  • remedy : ['string', 'null']
  • followups : integer — Relances déjà faites
  • followups_left : integer — Relances restantes (0 si la demande est close)
  • next_followup_at : object — Heure à partir de laquelle une relance est admise (null : plus de relance possible)
  • can_rate : boolean — Demande close, pas encore notée, dans les 30 jours
  • rating : ['integer', 'null'] — Note déjà donnée (1 à 5)
Asset
  • id : string
  • site_id : string
  • line_id : string
  • code : string
  • name : string
  • kind : string
  • status : running | idle | degraded | down | maintenance — Déduit des faits : « maintenance » (intervention démarrée, machine consignée pour un OT ouvert ou levée d'hygiène en attente) > « down » (un OT ouvert tient la machine arrêtée) > « degraded » (point de mesure en alarme ou OT conditionnel ouvert) > « running ». Chaque changement est diffusé sur /api/live (restreint aux usines du compte). Il est journalisé (`asset.status`) quand il vient d'une commande, du portail QR, de l'IoT (acteur : « IoT » pour MQTT et OPC UA, « <compte> (IoT) » pour HTTP) ou du démarrage ; les pas du simulateur (démo) ne sont pas journalisés
  • stopped_since : object — Début de l'arrêt en cours (null : machine non arrêtée)
  • restarted_at : object — Fin du dernier arrêt (clôture ou remise en service)
  • unassigned_requests : integer — OT « Demande » sans technicien (ni affecté ni planifié) : signe distinct, sans effet sur l'état
  • specs : object — Caractéristiques (clés fermées de calc::specs : power_kw, speed_rpm, voltage_v, current_a, cos_phi, efficiency, poles, frequency_hz, ratio, bore_mm, rod_mm, flow_m3h, head_m, rotor_mass_kg, bearing_d_mm, bearing_od_mm, bearing_width_mm, bearing_c_kn, bearing_c0_kn, bearing_f0), bornées ; absent si vide
  • criticality : A | B | C
  • health : number
  • oee : number
  • mtbf_hours : number
  • mttr_minutes : number
  • bom : [
    • part_id : string
    • qty : number
    ]
  • isolation_points : [IsolationPoint]
  • hazards : [atex | confined_space | height]
  • model3d : object — Modèle 3D propre (null : modèle procédural du type)
IsolationPoint
  • id : string
  • energy : electrical | pneumatic | hydraulic | mechanical | thermal | chemical
  • label : string
  • anchor : object — [x, y, z] en m dans le repère du modèle 3D, ou null
ModelPart
  • shape* : box | cylinder | sphere | lathe
  • size : [number] — box : [largeur x, hauteur y, profondeur z] en m
  • radius : number — box : rayon des arêtes (facultatif) ; cylinder : rayon du bas ; sphere : rayon
  • radius_top : number — cylinder : rayon du haut (facultatif, = radius)
  • height : number — cylinder : hauteur selon y local
  • profile : [[number]] — lathe : 2 à 32 points [rayon, y], révolution autour de y, origine en `at`
  • at* : [number] — Centre de la pièce (lathe : origine du profil), en m
  • rotation : [number] — Euler XYZ en radians (0 par défaut)
  • color* : string — body | body_alt | steel | dark | accent | glass | glow | warning | wood | cardboard | #rrggbb
  • part : string — Sous-ensemble maintenable (motor, gearbox, hmi…), 40 caractères max
Recipe
AssetModelobject
ModelResult
  • asset_ids* : [string]
  • model* : object
AnchorsInput
  • isolation : object — id du point d'isolement → [x, y, z] ou null
  • points : object — id du point de mesure → [x, y, z] ou null
Calendar
  • id : string
  • kind : personal | site | team
  • site_id : string
  • owner_user_id : string
  • team_id : string
  • name : string
  • tz : string
  • default_reminders : [integer]
  • archived : boolean
EventInput
  • calendar_id* : string
  • title* : string
  • description : string
  • location : string
  • when* : object — Horaire : {kind: timed, start: AAAA-MM-JJTHH:MM:SS (heure murale), tz: fuseau IANA, minutes} ou {kind: all_day, start: AAAA-MM-JJ, days}
  • rule : string — RRULE RFC 5545, sous-ensemble : FREQ DAILY à YEARLY, INTERVAL, COUNT ou UNTIL, BYDAY (rang en mensuel, en annuel avec BYMONTH), BYMONTHDAY, BYMONTH, WKST ; toute autre partie refusée avec son nom (422)
  • exdates : [string]
  • rdates : [string]
  • attendees : [
    • technician_id : string
    • user_id : string
    • name : string
    ]
  • reminders : [integer]
  • busy : boolean
  • links : [
    • kind : asset | work_order
    • id : string
    ]
  • accept_conflicts : boolean
Event
  • id : string
  • uid : string
  • calendar_id : string
  • site_id : string
  • sequence : integer
  • status : confirmed | tentative | cancelled
  • title : string
  • when : object — Horaire : {kind: timed, start: AAAA-MM-JJTHH:MM:SS (heure murale), tz: fuseau IANA, minutes} ou {kind: all_day, start: AAAA-MM-JJ, days}
  • rule : string
  • exdates : [string]
  • rdates : [string]
  • overrides : object
  • organizer : string
  • attendees : [object]
  • reminders : [integer]
  • busy : boolean
  • links : [object]
  • split_from : string
  • created_at : integer — Horodatage en millisecondes (epoch)
  • updated_at : integer — Horodatage en millisecondes (epoch)
Occurrence
  • key : string
  • source : string
  • record_id : string
  • calendar_id : string
  • site_id : string
  • title : string
  • start : integer — Horodatage en millisecondes (epoch)
  • end : integer — Horodatage en millisecondes (epoch)
  • all_day : boolean
  • local_date : string
  • tz : string
  • recurring : boolean
  • forecast : boolean
  • deviation : overdue | moved
  • my_partstat : string
Conflict
  • kind : absent | overlap | overload | asset_busy
  • technician_id : string
  • start : integer — Horodatage en millisecondes (epoch)
  • reason : string
  • event_id : string
  • date : string
  • hours : number
  • capacity : number
  • asset_id : string
  • work_order_id : string
Part
  • id : string
  • site_id : string
  • code : string
  • name : string
  • unit : string — Unité de gestion (u, kg, g, L, m, paquet…)
  • unit_cost : number
  • on_hand : number
  • min_qty : number
  • max_qty : number
  • location : string
  • supplier : string
  • critical : boolean
  • last_move_at : integer — Horodatage en millisecondes (epoch)
  • specs : object — Caractéristiques (clés fermées de calc::specs : power_kw, speed_rpm, voltage_v, current_a, cos_phi, efficiency, poles, frequency_hz, ratio, bore_mm, rod_mm, flow_m3h, head_m, rotor_mass_kg, bearing_d_mm, bearing_od_mm, bearing_width_mm, bearing_c_kn, bearing_c0_kn, bearing_f0), bornées ; absent si vide
  • pack : object — Conditionnement d'achat ou de sortie : 1 `unit` = `factor` unités de gestion (1 paquet = 25 u) ; null : aucun
  • components : [
    • part_id* : string
    • qty* : number
    ] — Article composé (kit) : composants pour `kit_base` unités du kit, déstockés à la sortie. Un kit n'a pas de stock propre ; un composant n'est jamais un kit. À la modification, absent : composition inchangée
  • kit_base : number — Quantité de kit (unité de gestion) pour laquelle la composition est donnée (1 990 paquets de 25 = 49 750 u)
Operation
  • seq : integer — Numéro de phase (10, 20, 30…), identifiant stable dans l'OT
  • title : string
  • trade : mechanic | electrician | automation
  • planned_minutes : integer
  • status : todo | in_progress | done
  • done_by : ['string', 'null']
  • done_at : integer — Horodatage en millisecondes (epoch)
OperationTemplate
  • title* : string
  • trade* : mechanic | electrician | automation
  • planned_minutes : integer
Rollup
  • work_order_id : string
  • children : integer — Sous-OT de tous niveaux
  • open_children : integer
  • progress : number — Avancement de l'arbre pondéré par la charge prévue, en %
  • planned_minutes : number
  • actual_minutes : number
  • cost :
    • labor : number
    • parts : number — Pièces sorties (coût figé)
    • external : number
    • total : number — Coût réel : main-d'œuvre + pièces sorties + sous-traitance
    • committed : number — Engagé : pièces réservées pas encore sorties (hors total)
Window
  • work_order_id : string
  • remaining_minutes : integer — Temps prévu restant (opérations pas encore faites), en minutes ; durées mises bout à bout en temps continu
  • earliest_start : integer — Début au plus tôt : maintenant (ou le démarrage réel), décalé par l'arrivée annoncée des pièces attendues
  • earliest_finish : integer — Fin au plus tôt (un parent ne finit pas avant ses sous-OT)
  • latest_finish : object — Fin au plus tard : échéance de l'OT, sinon celle de son parent
  • latest_start : object — Début au plus tard : fin au plus tard − temps restant
  • supply_by : object — Appro au plus tard (= début au plus tard)
  • supply_at : object — Arrivée annoncée de la dernière pièce attendue
  • supply : SupplyState
  • slack_minutes : ['integer', 'null'] — Marge : fin au plus tard − fin au plus tôt (négative : retard prévu)
  • late : boolean
  • held_by : ['string', 'null'] — Sous-OT qui repousse la fin au plus tôt (il finit après le travail propre de l'OT)
  • awaited : [
    • part_id : string
    • code : string
    • name : string
    • unit : string
    • qty : number
    • available : number
    • purchase_id : ['string', 'null']
    • purchase_code : ['string', 'null']
    • expected_at : object
    • state : SupplyState
    ]
Amounts
  • planned : number
  • actual : number
  • variance : number — Écart : réel − prévu
Analysis
  • work_order_id : string
  • code : string
  • title : string
  • site_id : string
  • asset_id : string
  • kind : string
  • status : string
  • parent_id : ['string', 'null']
  • created_at : integer — Horodatage en millisecondes (epoch)
  • closed_at : object
  • labor_minutes : Amounts — Minutes : gamme (sinon estimation de charge) contre temps passés
  • labor_cost : Amounts — Euros : temps prévus × coût horaire moyen du métier dans l'usine, contre temps passés × coût horaire de la personne
  • parts_cost : Amounts — Euros : quantités prévues au coût moyen, contre consommé au coût figé des sorties
  • external_cost : Amounts — Sous-traitance : devis (0 sans devis) contre montant facturé
  • total_cost : Amounts
  • estimated : boolean — Pas de gamme : la main-d'œuvre prévue est l'estimation de charge (hors écarts comparables)
  • unlogged : boolean — OT clôturé sans temps saisi : réel de main-d'œuvre inconnu (hors écarts comparables)
  • external_quoted : boolean — Sous-traitance avec devis (sinon, hors écarts comparables)
  • labor_rate_effect : number — Effet taux : coût réel − temps réel au taux prévu du métier
  • variance : Variances
  • operations : [
    • seq : ['integer', 'null'] — Phase ; null : temps hors gamme (ou OT sans gamme)
    • title : string
    • trade : string
    • status : ['string', 'null']
    • minutes : Amounts
    • cost : Amounts
    • rate_effect : number — Effet taux de l'opération
    ]
  • parts : [
    • part_id : string
    • code : string
    • name : string
    • unit : string
    • kit_code : ['string', 'null']
    • planned_qty : number
    • reserved_qty : number
    • consumed_qty : number
    • cost : Amounts
    ]
Variances
  • labor_minutes : number
  • labor_cost : number
  • parts_cost : number
  • external_cost : number
  • total_cost : number
AnalysisSummary
  • from : integer — Horodatage en millisecondes (epoch)
  • to : integer — Horodatage en millisecondes (epoch)
  • count : integer
  • closed : integer
  • labor_minutes : Amounts
  • labor_cost : Amounts
  • parts_cost : Amounts
  • external_cost : Amounts
  • total_cost : Amounts
  • realized : Variances — Écart réalisé : OT clôturés de la période
  • open : Variances — OT ouverts : un écart négatif est un reste à consommer
  • estimated : integer — OT sans gamme (main-d'œuvre estimée)
  • unlogged : integer — OT clôturés sans temps saisi
  • by_trade : []
  • rows : [Analysis] — Une ligne par OT, sans le détail des opérations et des pièces
SupplyStateready | in_stock | ordered | to_order | late
Explosion
  • part_id : string
  • qty : number — Quantité demandée en unité de gestion
  • kit : boolean
  • lines : [
    • part_id : string
    • code : string
    • name : string
    • unit : string
    • qty : number — Quantité exacte (au millième)
    • available : number — En stock − réservé sur les OT ouverts
    • missing : number
    ]
PartUse
  • part_id : string
  • qty : number — Quantité prévue
  • unit_cost : number
  • reserved_by : string
  • issued_at : integer — Horodatage en millisecondes (epoch)
  • issued_qty : number — Cumul des sorties (au-delà du prévu : écart)
  • reserved : boolean — Faux : prévu, à approvisionner
  • settled : boolean — Reliquat libéré
  • kit_id : ['string', 'null'] — Kit dont la ligne est un composant
Purchase
  • id : string
  • code : string
  • site_id : string
  • supplier : string
  • status : draft | ordered | partial | received | cancelled
  • lines : [
    • part_id : string
    • qty : number
    • unit_cost : number
    • received_qty : number
    ]
  • work_order_id : string
  • expected_at : integer — Horodatage en millisecondes (epoch)
Inspection
  • id : string
  • site_id : string
  • asset_id : string
  • kind : regulatory | calibration | functional
  • title : string
  • reference : string
  • body : string
  • interval_days : integer
  • due_at : integer — Horodatage en millisecondes (epoch)
  • active : boolean
  • history : [object]
Contract
  • id : string
  • site_id : string
  • vendor_id : string
  • reference : string
  • title : string
  • kind : string
  • asset_ids : [string]
  • start_at : integer — Horodatage en millisecondes (epoch)
  • end_at : integer — Horodatage en millisecondes (epoch)
  • notice_days : integer
  • auto_renew : boolean
  • response_hours : integer
  • annual_amount : number
Vendor
  • id : string
  • name : string
  • kind : contractor | inspection_body | supplier
  • contact : string
  • email : string
  • phone : string
  • active : boolean
Snapshot
  • now : integer — Horodatage en millisecondes (epoch)
  • sites : [object]
  • lines : [object]
  • assets : [Asset]
  • work_orders : [WorkOrder]
  • plans : [object]
  • parts : [Part]
  • purchases : [Purchase]
  • inspections : [Inspection]
  • contracts : [Contract]
  • vendors : [Vendor]
  • technicians : [object]
  • messages : [object]
Site
  • id : string
  • code : string
  • name : string
  • activity : string
  • address : string
  • city : string
  • country : string
  • timezone : string
  • locale : string
  • sector : agrifood | automotive
  • origin :
    • x : number
    • z : number
  • footprint :
    • width : number
    • depth : number
  • aisle_z : number
  • workshop :
    • x : number
    • z : number
SiteInput
  • code* : string
  • name* : string
  • activity : string
  • address : string
  • city : string
  • country* : string — ISO 3166-1 alpha-2
  • timezone* : string
  • locale* : string
  • sector* : agrifood | automotive
  • width : number — Emprise du bâtiment en m (20 à 400, 60 par défaut)
  • depth : number — En m (20 à 400, 40 par défaut)
ProductionLine
  • id : string
  • site_id : string
  • code : string
  • name : string
  • product : string
  • nominal_rate : integer
LineInput
  • site_id* : string
  • code* : string
  • name* : string
  • product : string
  • nominal_rate : integer
LayoutResult
Indicator
  • key* : availability | oee | mtbf | mttr | lead_time | coded_share | preventive_share_hours | preventive_share_count | pm_compliance | planned_share | backlog_weeks | labor_hours | cost_total | cost_to_rav | satisfaction — satisfaction : notes de 4 ou 5 ÷ notes reçues des demandeurs sans compte (portail QR), au jour de la note
  • code : ['string', 'null'] — Code EN 15341:2019+A1:2022 vérifié sur le texte de la norme (PHA6, PHA6 · R1), sinon null
  • value* : ['number', 'null'] — null : non calculable (voir missing)
  • unit* : % | h | min | wk | EUR
  • numerator* : number
  • denominator* : number
  • missing : ['string', 'null'] — production_counts, no_failure, no_repair, no_corrective, no_labor, no_work_order, no_plan_work_order, no_technician, no_replacement_value, no_asset, no_elapsed_time, no_rating
Report
  • from : integer — Horodatage en millisecondes (epoch)
  • to : integer — Fin exclue ; bornes alignées sur des jours UTC entiers
  • generated_at : integer — Horodatage en millisecondes (epoch)
  • site_ids : [string]
  • granularity : day | week | month
  • days : integer
  • required_hours : number
  • assets_in_scope : integer
  • technicians : integer
  • indicators : [Indicator]
  • closed :
    • corrective : integer
    • preventive : integer
    • improvement : integer
  • failures : integer — Défaillances demandées sur la période : correctifs, hors réparation définitive (même défaillance que la réparation temporaire)
  • failure_modes : [
    • key : string
    • count : integer
    • cumulative_pct : number
    ] — Pareto des défaillances clôturées (correctifs hors réparation définitive)
  • causes : [
    • key : string
    • count : integer
    • cumulative_pct : number
    ]
  • assets : [
    • asset_id : string
    • site_id : string
    • failures : integer
    • repairs : integer
    • downtime_minutes : integer
    • mttr_minutes : number
    • mtbf_hours : number
    • availability : number
    • labor_hours : number
    • cost : object
    ]
  • costs :
    • labor : number
    • parts : number
    • external : number
    • total : number
    • replacement_value : number
  • backlog :
    • open : integer
    • hours : number
    • weeks : number
    • capacity_hours_per_week : number
  • micro_stops :
    • count : integer
    • minutes : integer
    • by_reason : [object]
  • series : [
    • start : integer — Horodatage en millisecondes (epoch)
    • closed : object
    • failures : integer
    • downtime_minutes : integer
    • labor_hours : number
    • cost : number
    ]
  • by_site : [
    • site_id : string
    • assets_in_scope : integer
    • technicians : integer
    • closed : object
    • failures : integer
    • costs : object
    • indicators : [Indicator]
    ] — Comparatif entre usines (vue réseau) ; vide pour une seule usine
  • assumptions :
    • required_hours_per_day : number
    • weekly_hours_per_technician : number
    • day_boundary : object
    • pm_on_time_days : integer
DemoRequestInput
  • name* : string — Nom et prénom, 1 à 100 caractères après rognage (blancs d'une ligne réduits)
  • company* : string — Société, 1 à 120 caractères
  • email* : string — E-mail professionnel (messageries grand public admises) ; gardé en minuscules
  • phone : ['string', 'null'] — Facultatif : 6 à 20 chiffres, « + » en tête, groupes séparés par une espace ou un point
  • sites* : 1 | 2-3 | 4-10 | 10+ — Nombre de sites : 1, 2 à 3, 4 à 10, plus de 10
  • message : ['string', 'null'] — Facultatif : 2 000 caractères au plus (un saut de ligne compte pour un)
  • consent* : boolean — Consentement au traitement de la demande : doit valoir true
  • locale* : fr | en | de | es — Langue de la page qui envoie la demande
  • website : string — Champ piège caché aux humains, à laisser vide : rempli, la demande est jetée (réponse 201 ordinaire)
DemoRequestErrors
  • error* : string
  • code* : object
  • errors* : object — Champ → code stable : required, invalid, too_long, consent_required
WebhookPayload
  • id : string
  • event : string
  • tenant : string
  • at : integer — Horodatage en millisecondes (epoch)
  • actor : string
  • target : string
  • detail : object
  • data : object — État courant de l'enregistrement (OT, achat, contrôle, article, contrat, équipement)