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/*, 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 serviceAssetServiceLink / Asset.serviceShortCodeURL courte unique imprimée sur l'asset, ouvre la page publique SAV sans login.
OTMaintenanceOperationOrdre de Travail — curatif, préventif ou inspection.
MouvementAssetMovementEnregistrement daté de tout déplacement d'asset entre localisations.
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 — calculé par modèle via job nocturne.
MTTRMean Time To Repair — calculé par modèle via job nocturne.

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 (étiquettes QR, transfert, recyclage, 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, Historique emplacements, Maintenance, Contrats, Pièces détachées, Fichiers, Commentaires, Audit log.
Marques/workspace/assets/brandsListe, création, édition, désactivation (unicité du nom).
Modèles/workspace/assets/modelsListe, création, fiche/édition, propriétés dynamiques key/value/unit, MTBF cumulé.
Familles/workspace/assets/familiesArbre hiérarchique drag-drop, édition libre.
Stockages/workspace/assets/storage-locationsListe dépôts (occupation, capacité m²/m³, liste du parc en stock).
Étiquettes/workspace/assets/printingTâche d'impression QR / étiquettes / fiches, templates PDF, job async > 100 assets.
Dashboard maintenance/workspace/maintenance-overview6 KPI 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, signature client 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, génération BL/CMR PDF, suivi tracking.
Transporteurs/workspace/transport/carriersCRUD (nom unique par organisation).
SAV public/public/asset/[shortCode]Formulaire sans login : identité, description, photos, niveau d'urgence → crée OT curatif.
Suivi SAV public/public/maintenance/[publicCode]Consultation statut OT sans login.

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

  • Asset.currentLocationId : référence vers l'AssetLocation courante — mise à jour atomiquement à chaque mouvement.
  • AssetLocation : chaque emplacement reçoit arrivedAt à la création et leftAt à la sortie (historique immuable).
  • Asset.serviceShortCode : code 8 chars aléatoire (collision check), porté directement sur l'asset, sert de jeton public.
  • États physiques AssetCondition et fonctionnels AssetFunctional : deux enums indépendants.
  • 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).
  • MTBF/MTTR : recalculés chaque nuit par job maintenance:mtbf-refresh (vue matérialisée par modèle).
  • 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}, assets.asset:{read,manage}, maintenance.operation:{read,manage}.

MéthodeRoutePermission
GET/api/workspace/assetsasset:read
GET/api/workspace/assets/[id]asset:read
POST/api/workspace/assetsasset:create
PATCH/api/workspace/assets/[id]asset:update
DELETE/api/workspace/assets/[id]asset:delete
POST/api/workspace/assets/[id]/moveasset.location:move
POST/api/workspace/assets/[id]/stateasset:update
GET/api/workspace/assets/[id]/qr.pngasset:read
POST/api/workspace/assets/printasset:read
GET / POST/api/workspace/asset-brandsasset:read / asset.brand:manage
GET / POST/api/workspace/asset-modelsasset:read / asset.model:manage
GET/api/workspace/asset-familiesasset:read
GET / POST/api/workspace/storage-locationsasset:read / asset:update
GET / POST/api/workspace/maintenanceasset.maintenance:read / :create
PATCH/api/workspace/maintenance/[id]asset.maintenance:update
POST/api/workspace/maintenance/[id]/completeasset.maintenance:complete
GET / POST/api/workspace/spare-parts/referencesasset:read / asset:update
GET / POST/api/workspace/spare-parts/instancesasset:read / asset:update
GET / POST/api/workspace/transport/requestsasset.transport:manage
GET/api/workspace/transport/carriersasset.transport:manage
GET/api/public/asset/[shortCode](public, sans session)
POST/api/public/asset/[shortCode]/report-issue(public, rate-limit strict)

Exemple de référence d'endpoint :

POST/api/public/asset/[shortCode]/report-issueAuth

Crée un MaintenanceOperation curatif depuis la page publique SAV (QR code scanné). Route sans session — rate-limit strict. Aucune donnée interne de l'organisation n'est exposée dans la réponse.

Corps (JSON)

reporterName
string
Nom du déclarant (facultatif si lien personnalisé avec identité connue).
reporterEmail
string
Email pour envoi de la confirmation et du N° d'intervention.
description
string required
Description du problème constaté.
urgencyLevel
string required
Niveau d'urgence auto-évalué par le déclarant.
photoUrls
string[]
URLs des photos uploadées avant soumission.

Réponse

{
  "maintenanceOperationId": "mop_…",
  "publicCode": "SAV-2026-04217",
  "trackingUrl": "https://qr.pulsegroup.fr/public/maintenance/SAV-2026-04217"
}

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 asset.state_changed, AssetMovement créé, AssetLocation.currentLocationId mis à jour, notifications éventuelles.

OT préventif (job quotidien)

  1. maintenance-preventive 1×/j scanne les LeaseContract actifs avec clause de maintenance.
  2. Calcule la prochaine échéance ; si J−30 sans OT planifié → crée MaintenanceOperation PLANNED PREVENTIVE.
  3. Notification responsable SAV pour affectation technicien.

OT curatif

  1. Client via QRPOST /api/public/asset/[shortCode]/report-issue → 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 : IN_PROGRESS à l'arrivée, diagnostic + résolution + pièces + photos + signature client → 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 → génère automatiquement une TransportRequest TRANSFER.
  • AssetLocation précédente reçoit leftAt, nouvelle créée avec arrivedAt.

QR code / Lien de service

  • AssetServiceLink créé automatiquement à la création de l'asset ; shortCode 8 chars (collision check).
  • publicUrl = https://qr.pulsegroup.fr/{shortCode} — QR PNG généré à la demande (cache 30j).
  • Étiquette PDF générée par buildAssetLabelPdf (N° inventaire + lien + QR code).

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).
  • Suppression hard interdite si asset lié à un contrat ou une facture.
  • MaintenanceOperation IN_PROGRESS non supprimable — annulation avec raison obligatoire.
  • Pièces décrémentées à la complétion de l'OT, pas à l'ajout de la ligne pièce.
  • Job nocturne : recalcul MTBF/MTTR par modèle (vue matérialisée).
  • 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