Assets & Maintenance

Référence technique du domaine Assets & Maintenance — cycle de vie équipements, OT, pièces détachées, transport, SAV public.

Assets & Maintenance

Périmètre : cycle de vie des équipements de la grande distribution alimentaire (réfrigérateurs, vitrines, chambres froides, fours, climatisation…) — entrée en stock, installation client, maintenance préventive/curative, pièces détachées, transport, reconditionnement, revente/recyclage. Inclut le référentiel marques/modèles/familles, les dépôts, le SAV public via QR code et la facturation de stockage par prestataire.

Écrans sous /workspace/assets/*, /workspace/maintenance*, /workspace/spare-parts, /workspace/transport/*. Routes API sous /api/workspace/assets/*, /api/workspace/maintenance-operations/*, /api/workspace/transport-requests/*, etc. La Phase 6 est fonctionnellement complète. Source : docs/08-domain-assets.md.

Vocabulaire & entités

TermeEntitéDéfinition
AssetAssetInstance physique unique d'un équipement, identifiée par un N° inventaire et un N° de série.
ModèleAssetModelRéférence catalogue (ex : « Liebherr GKv 6460 »), rattaché à une marque et une famille.
MarqueAssetBrandFabricant (ex : « Liebherr »).
FamilleAssetFamilyCatégorie hiérarchique (ex : Réfrigération › Armoire réfrigérée › Vitrine positive).
DépôtStorageLocationEntrepôt physique géré par Pulse ou un prestataire logistique.
Lien de serviceServiceLink + ServiceLinkScan / Asset.serviceShortCodeQR code pré-imprimé autonome, affectable à un détenteur avant pose, puis associé à un asset. Le code est partagé avec Asset.serviceShortCode (compat page publique). Statuts ServiceLinkStatus : IN_STOCK, ASSIGNED, LINKED, RETIRED. Chaque scan est tracé dans ServiceLinkScan.
OTMaintenanceOperationOrdre de Travail. Enum MaintenanceType : PREVENTIVE, CURATIVE, INSPECTION, INSTALLATION, DECOMMISSIONING. Statut MaintenanceStatus : PLANNED, IN_PROGRESS, DONE, CANCELED.
MouvementAssetMovementEnregistrement daté de tout déplacement d'asset entre localisations.
Événement de cycle de vieAssetLifecycleEventJournal append-only des décisions de reconditionnement / recyclage / revente (AssetLifecycleEventType : INSPECTION, REFURBISH, RECYCLE, SELL). Immuable.
Demande de transportTransportRequestLivraison / enlèvement / transfert inter-dépôts, rattachée à un transporteur.
TransporteurCarrierPrestataire logistique (nom, contact, capacité, agréments, assurance).
Pièce — référenceSparePartReferenceRéférence catalogue d'une pièce détachée, liée à des modèles d'asset compatibles.
Pièce — instanceSparePartInstanceStock physique d'une référence de pièce (SparePartState).
MTBFMean Time Between Failures — agrégat de fiabilité par modèle (/maintenance/reliability, /mtbf-by-model).
MTTRMean Time To Repair — agrégat de fiabilité par modèle, rafraîchi via /maintenance/reliability-refresh.

Le schéma complet est dans docs/04-data-model.md §6.

Écrans

ÉcranRouteContenu
Liste assets/workspace/assetsDataTable (N° inventaire, N° série, modèle, famille, états, localisation, dernière maintenance) + vue Cartes + vue Carte géo + actions de masse (changement d'état, transfert, export).
Création asset/workspace/assets/newSélecteur modèle, N° inventaire auto ou manuel, N° série, état initial, date + montant d'acquisition, localisation initiale, multi-upload photos.
Fiche asset/workspace/assets/[id]Onglets : Synthèse, Caractéristiques, SAV, Logistique, Liens (QR), Énergie, Documents.
Paramètres assets/workspace/assets/settingsFamille par défaut + gabarit de schéma de propriétés dynamiques (singleton par org).
Catalogue (marques & familles)/workspace/asset-catalogMarques (CRUD, désactivation, unicité du nom) + arbre des familles.
Modèles/workspace/asset-modelsListe, création, fiche/édition, propriétés dynamiques (spec-schema), MTBF cumulé.
Stockages/workspace/storage-locationsListe dépôts (occupation, capacité m²/m³, parc en stock) + carte géo (/map) + tarifs de stockage.
Liens de service/workspace/service-linksParc de QR codes pré-imprimés (statuts IN_STOCK/ASSIGNED/LINKED/RETIRED), affectation à un détenteur.
Tâches d'impression/workspace/printing-tasksSuivi des jobs async de génération d'étiquettes QR (lancés depuis la liste assets), téléchargement du PDF.
Dashboard maintenance/workspace/maintenance-overviewKPI cards : OT ouverts, en retard, MTTR moyen, taux SLA respectés, coût moyen, top modèles.
Planning maintenance/workspace/maintenance-planningOpérations ouvertes par échéance, retards en tête.
Liste OT/workspace/maintenanceKanban PLANNED/IN_PROGRESS/DONE/CANCELED + calendrier drag-drop (FullCalendar).
Fiche OT/workspace/maintenance/[id]Diagnostic, résolution, pièces utilisées, coût estimé/réel, signatures canvas, photos avant/après, PDF rapport.
Pièces détachées/workspace/spare-partsRéférences catalogue + instances en stock + mouvements + alertes seuil bas.
Transport/workspace/transportKanban REQUESTED→DELIVERED, création demandes, étapes (stops), transporteurs candidats, PDF Demande de Transport.
Transporteurs/workspace/carriersCRUD (nom unique par organisation).
SAV public/public/asset/[shortCode]Formulaire sans login : nom du déclarant, contact, description → crée OT curatif.

Modèle de données (points clés)

  • Asset.currentLocationId : référence vers le StorageLocation courant — mis à jour atomiquement à chaque mouvement.
  • AssetMovement : journal daté de tout déplacement (fromLocationId/toLocationId, movedAt, reason), porte aussi transportKm et transportCarbonKg (empreinte transport, Lot D).
  • Asset.serviceShortCode : code court unique (collision check), porté directement sur l'asset, sert de jeton public. Partagé avec ServiceLink.code lors de l'association.
  • États physiques AssetCondition (NEW, EXCELLENT, GOOD, NEEDS_REPAIR, NON_FUNCTIONAL_PARTS, LOST, RECYCLED, REFURBISHED, SOLD, TO_DEFINE) et fonctionnels AssetFunctional (FUNCTIONAL, NON_FUNCTIONAL, NOT_TESTED) : deux enums indépendants.
  • Asset.carbonFootprintKg (empreinte carbone cumulée) et Asset.aiFailureScore (+aiFailureScoreAt) : score de panne prédit par l'IA (Lot D Phase 6).
  • MaintenanceOperation.slaDueAt : calculé à la création selon la priorité du contrat (J+4h critique, J+24h normal, J+5j basse).
  • SparePartInstance : décrémentée du stock à la complétion de l'OT (pas à l'ajout de la ligne pièce). États SparePartState : NEW, GOOD, USED, DEFECTIVE.
  • MTBF/MTTR : agrégats de fiabilité (refreshReliabilityViews()), rafraîchis via POST /maintenance/reliability-refresh (à brancher sur un job nocturne).
  • StorageMovementRequest (PENDING → CONFIRMED → VERIFIED) : gère le workflow WARM'UP ; génère atomiquement les AssetMovement à la vérification.

API

Permissions de base : assets.catalog:{read,manage} (marques, modèles, familles, pièces, settings), assets.asset:{read,manage} (assets, mouvements, transport, transporteurs), maintenance.operation:{read,manage} (OT, signatures, pièces, fiabilité). Les tarifs de stockage utilisent storage.config:{read,manage}.

Assets — CRUD & cycle de vie

MéthodeRoutePermission
GET/api/workspace/assetsassets.asset:read
POST/api/workspace/assetsassets.asset:manage
GET/api/workspace/assets/[id]assets.asset:read
PATCH/api/workspace/assets/[id]assets.asset:manage
GET / POST/api/workspace/assets/[id]/movementsassets.asset:read / :manage
POST/api/workspace/assets/[id]/refurbish · /recycle · /sell · /inspectassets.asset:manage
GET/api/workspace/assets/[id]/lifecycleassets.asset:read
GET/api/workspace/assets/[id]/labelassets.asset:read
POST/api/workspace/assets/[id]/service-linkassets.asset:read
PATCH/api/workspace/assets/[id]/dynamic-specsassets.asset:manage
GET / POST/api/workspace/assets/[id]/missing-partsassets.asset:read / :manage
PATCH/api/workspace/asset-missing-parts/[id]assets.asset:manage
POST/api/workspace/assets/qr-labelsassets.asset:read
POST/api/workspace/assets/ocr-plateassets.asset:manage
GET/api/workspace/assets/deee/[reference]assets.asset:read
GET / PUT/api/workspace/assets/settingsassets.catalog:read / :manage

Assets — énergie, carbone & prédiction IA (Lot D)

MéthodeRoutePermission
GET / POST/api/workspace/assets/[id]/energyassets.asset:read / :manage
GET/api/workspace/assets/[id]/carbonassets.asset:read
GET/api/workspace/assets/[id]/predictionassets.asset:read
POST/api/workspace/assets/prediction/runassets.asset:manage

Assets — actions de masse

MéthodeRoutePermission
POST/api/workspace/assets/bulk/change-stateassets.asset:manage
POST/api/workspace/assets/bulk/transferassets.asset:manage
POST/api/workspace/assets/bulk/exportassets.asset:read

Impression d'étiquettes (async)

MéthodeRoutePermission
GET / POST/api/workspace/assets/printing-tasksassets.asset:read
GET/api/workspace/assets/printing-tasks/[id]assets.asset:read
GET/api/workspace/assets/printing-tasks/[id]/downloadassets.asset:read

Catalogue (marques, modèles, familles, pièces, stockages)

MéthodeRoutePermission
GET / POST/api/workspace/asset-brands · /asset-brands/[id] (PATCH)assets.catalog:read / :manage
GET / POST/api/workspace/asset-models · /[id] (GET/PATCH) · /[id]/spec-schema (PATCH)assets.catalog:read / :manage
GET / POST/api/workspace/asset-families · /[id] (PATCH)assets.catalog:read / :manage
GET / POST/api/workspace/spare-parts · /[id] (GET/PATCH)assets.catalog:read / :manage
GET / POST/api/workspace/spare-parts/[id]/instancesassets.catalog:read / :manage
PATCH/api/workspace/spare-part-instances/[id]assets.catalog:manage
GET / POST/api/workspace/storage-locations · /[id] (GET/PATCH) · /[id]/geo (PATCH)assets.asset:read / :manage
GET/api/workspace/storage-locations/[id]/assets · /[id]/occupancy · /mapassets.asset:read
GET / POST/api/workspace/storage-locations/[id]/rates · /[rateId] (PATCH/DELETE) · /compute (POST)storage.config:read / :manage

Maintenance — OT & fiabilité

MéthodeRoutePermission
GET / POST/api/workspace/maintenance-operationsmaintenance.operation:read / :manage
GET / PATCH/api/workspace/maintenance-operations/[id]maintenance.operation:read / :manage
GET / POST/api/workspace/maintenance-operations/[id]/signaturesmaintenance.operation:read / :manage
POST/api/workspace/maintenance-operations/[id]/partsmaintenance.operation:manage
DELETE/api/workspace/maintenance-operations/[id]/parts/[partId]maintenance.operation:manage
GET/api/workspace/maintenance/reliabilitymaintenance.operation:read
POST/api/workspace/maintenance/reliability-refreshmaintenance.operation:manage
GET/api/workspace/maintenance/stats · /mtbf-by-modelassets.asset:read
La complétion d'un OT se fait par PATCH /maintenance-operations/[id] avec status: "DONE" (transition d'état validée côté service) — il n'existe pas de route /complete dédiée.

Transport & transporteurs

MéthodeRoutePermission
GET / POST/api/workspace/transport-requestsassets.asset:read / :manage
GET / PATCH/api/workspace/transport-requests/[id]assets.asset:read / :manage
GET/api/workspace/transport-requests/[id]/documentassets.asset:read
POST/api/workspace/transport-requests/[id]/stops · /[stopId] (PATCH/DELETE)assets.asset:manage
POST / DELETE/api/workspace/transport-requests/[id]/stops/[stopId]/assets · /[assetLineId]assets.asset:manage
POST/api/workspace/transport-requests/[id]/carriers · /[carrierLineId] (PATCH/DELETE)assets.asset:manage
GET/api/workspace/transport-requests/[id]/bcs/[carrierLineId]assets.asset:read
POST/api/workspace/transport-requests/[id]/notify-eveassets.asset:manage
GET / POST/api/workspace/carriers · /[id] (GET/PATCH)assets.asset:read / :manage

SAV public (sans session)

MéthodeRoutePermission
GET/api/public/asset/[shortCode](public, sans session)
POST/api/public/asset/[shortCode]/report(public, le code de service fait office de jeton)

Exemple de référence d'endpoint :

POST/api/public/asset/[shortCode]/reportAuth

Crée un MaintenanceOperation de type CURATIVE depuis la page publique SAV (QR code scanné). Route sans session — le code de service fait office de jeton. Aucune donnée interne de l'organisation n'est exposée dans la réponse.

Corps (JSON)

description
string required
Description du problème constaté (1–4000 caractères).
reporterName
string
Nom du déclarant (facultatif).
reporterContact
string
Email ou téléphone de contact (facultatif).

Réponse

{
  "submitted": true
}

Workflows

Cycle de vie d'un asset

ACQUISITION (état NEW, localisation dépôt)
     │
  EN STOCK
     │  affectation contrat LLD / vente
     │
CHEZ LE CLIENT
   ├──→ MAINTENANCE (OT)  ──→ retour dépôt
   └──→ DEFAILLANT        ──→ RETOUR SAV
                                  │
                        RECONDITIONNEMENT
                         ├──→ REVENTE
                         └──→ RECYCLAGE

À chaque transition : audit log, AssetMovement créé, Asset.currentLocationId mis à jour, AssetLifecycleEvent consigné pour les décisions de reconditionnement, notifications éventuelles.

OT préventif & maintenance contractuelle

  • Les OT préventifs (MaintenanceType: PREVENTIVE) sont créés depuis le planning / la fiche asset, puis affectés à un technicien.
  • La facturation de la maintenance contractuelle est gérée par l'échéancier de maintenance du contrat (LeaseMaintenance) : le cron Nitro lease:maintenance-billing facture quotidiennement les échéances dues (horizon J+15, Lot L2 Phase 6). Voir le domaine Location.

OT curatif

  1. Client via QRPOST /api/public/asset/[shortCode]/report → OT PLANNED CURATIVE.
  2. Portail client /client/maintenance/new → idem.
  3. Interne → création depuis fiche asset.
  4. Notification responsable SAV → affectation technicien.
  5. Technicien : PATCH vers IN_PROGRESS à l'arrivée, diagnostic + résolution + pièces + photos + signature client, puis PATCH status: "DONE".
  6. Rapport PDF généré, envoyé au client, archivé.
  7. Si coût OT > seuil configuré par org → devis exigé avant intervention.

SLA & escalade

  • slaDueAt calculé à la création selon priorité contractuelle (J+4h / J+24h / J+5j).
  • J−1 du SLA sans IN_PROGRESS → notification urgence responsable SAV.
  • Dépassement SLA → escalade direction + email d'excuse client.

Mouvement / transfert

  • Localisation CUSTOMER_ESTABLISHMENT : exige un Establishment lié à un LeaseContract actif (sinon warning).
  • Transfert inter-dépôts → enregistre un AssetMovement (fromLocationId/toLocationId) et met à jour Asset.currentLocationId.
  • L'historique des emplacements se lit via AssetMovement (route GET /assets/[id]/movements).

QR code / Lien de service

  • Un ServiceLink peut être pré-imprimé et affecté à un détenteur (statut IN_STOCKASSIGNED), puis associé à un asset (LINKED) ; son code est alors partagé avec Asset.serviceShortCode (collision check).
  • POST /assets/[id]/service-link génère (si besoin) et renvoie le code de service de l'équipement.
  • Chaque consultation publique trace un ServiceLinkScan (source = PUBLIC).
  • Étiquette PDF générée à la demande via GET /assets/[id]/label ; impression en masse via les tâches d'impression async (/assets/printing-tasks).

Reconditionnement

  • Retour dépôt fin de contrat → OT INSPECTION.
  • Décision : REFURBISHED (ré-allouable) · RECYCLED (bordereau DEEE) · SOLD (sortie stock).

Règles métier

  • N° inventaire unique par organisation. N° série unique par org s'il est renseigné.
  • LOST / RECYCLED → asset non sélectionnable pour de nouveaux contrats.
  • SOLD → asset en lecture seule (non modifiable).
  • Les assets sont en soft-delete (Asset.deletedAt) ; pas de route de suppression exposée — on archive plutôt qu'on supprime.
  • OT IN_PROGRESS → transition autorisée vers DONE ou CANCELED uniquement (transitions verrouillées côté service).
  • Pièces décrémentées à la complétion de l'OT, pas à l'ajout de la ligne pièce.
  • Agrégats MTBF/MTTR par modèle rafraîchis via POST /maintenance/reliability-refresh (à brancher sur un job nocturne).
  • Workflow WARM'UP : StorageMovementRequest PENDING → CONFIRMED → VERIFIED ; génération atomique des AssetMovement à la vérification.

KPIs

Nombre d'assets par état · taux d'occupation par dépôt · MTBF/MTTR par modèle et par famille · taux de respect SLA SAV (% OT clos dans SLA) · coût moyen d'intervention par modèle · top 10 modèles les plus problématiques · volume mouvements par mois.

Notifications

ÉvénementCanalDestinataire
OT créé (curatif)In-appResponsable SAV
OT assignéIn-app + emailTechnicien
OT proche SLAIn-app + emailResponsable SAV
OT en retard SLAIn-app + email + SMSResponsable SAV + direction
OT complétéIn-app + email + PDFClient demandeur
Asset perduIn-appManager logistique
Stock pièces basIn-app + emailResponsable logistique
QR code visitéIn-app (low priority)Commercial du compte
Maintenance préventive dueIn-appResponsable SAV