Assets & Maintenance
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.
/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
| Terme | Entité | Définition |
|---|---|---|
| Asset | Asset | Instance physique unique d'un équipement, identifiée par un N° inventaire et un N° de série. |
| Modèle | AssetModel | Référence catalogue (ex : « Liebherr GKv 6460 »), rattaché à une marque et une famille. |
| Marque | AssetBrand | Fabricant (ex : « Liebherr »). |
| Famille | AssetFamily | Catégorie hiérarchique (ex : Réfrigération › Armoire réfrigérée › Vitrine positive). |
| Dépôt | StorageLocation | Entrepôt physique géré par Pulse ou un prestataire logistique. |
| Lien de service | ServiceLink + ServiceLinkScan / Asset.serviceShortCode | QR 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. |
| OT | MaintenanceOperation | Ordre de Travail. Enum MaintenanceType : PREVENTIVE, CURATIVE, INSPECTION, INSTALLATION, DECOMMISSIONING. Statut MaintenanceStatus : PLANNED, IN_PROGRESS, DONE, CANCELED. |
| Mouvement | AssetMovement | Enregistrement daté de tout déplacement d'asset entre localisations. |
| Événement de cycle de vie | AssetLifecycleEvent | Journal append-only des décisions de reconditionnement / recyclage / revente (AssetLifecycleEventType : INSPECTION, REFURBISH, RECYCLE, SELL). Immuable. |
| Demande de transport | TransportRequest | Livraison / enlèvement / transfert inter-dépôts, rattachée à un transporteur. |
| Transporteur | Carrier | Prestataire logistique (nom, contact, capacité, agréments, assurance). |
| Pièce — référence | SparePartReference | Référence catalogue d'une pièce détachée, liée à des modèles d'asset compatibles. |
| Pièce — instance | SparePartInstance | Stock physique d'une référence de pièce (SparePartState). |
| MTBF | — | Mean Time Between Failures — agrégat de fiabilité par modèle (/maintenance/reliability, /mtbf-by-model). |
| MTTR | — | Mean 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
| Écran | Route | Contenu |
|---|---|---|
| Liste assets | /workspace/assets | DataTable (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/new | Sé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/settings | Famille par défaut + gabarit de schéma de propriétés dynamiques (singleton par org). |
| Catalogue (marques & familles) | /workspace/asset-catalog | Marques (CRUD, désactivation, unicité du nom) + arbre des familles. |
| Modèles | /workspace/asset-models | Liste, création, fiche/édition, propriétés dynamiques (spec-schema), MTBF cumulé. |
| Stockages | /workspace/storage-locations | Liste dépôts (occupation, capacité m²/m³, parc en stock) + carte géo (/map) + tarifs de stockage. |
| Liens de service | /workspace/service-links | Parc de QR codes pré-imprimés (statuts IN_STOCK/ASSIGNED/LINKED/RETIRED), affectation à un détenteur. |
| Tâches d'impression | /workspace/printing-tasks | Suivi 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-overview | KPI cards : OT ouverts, en retard, MTTR moyen, taux SLA respectés, coût moyen, top modèles. |
| Planning maintenance | /workspace/maintenance-planning | Opérations ouvertes par échéance, retards en tête. |
| Liste OT | /workspace/maintenance | Kanban 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-parts | Références catalogue + instances en stock + mouvements + alertes seuil bas. |
| Transport | /workspace/transport | Kanban REQUESTED→DELIVERED, création demandes, étapes (stops), transporteurs candidats, PDF Demande de Transport. |
| Transporteurs | /workspace/carriers | CRUD (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 leStorageLocationcourant — mis à jour atomiquement à chaque mouvement.AssetMovement: journal daté de tout déplacement (fromLocationId/toLocationId,movedAt,reason), porte aussitransportKmettransportCarbonKg(empreinte transport, Lot D).Asset.serviceShortCode: code court unique (collision check), porté directement sur l'asset, sert de jeton public. Partagé avecServiceLink.codelors de l'association.- États physiques
AssetCondition(NEW,EXCELLENT,GOOD,NEEDS_REPAIR,NON_FUNCTIONAL_PARTS,LOST,RECYCLED,REFURBISHED,SOLD,TO_DEFINE) et fonctionnelsAssetFunctional(FUNCTIONAL,NON_FUNCTIONAL,NOT_TESTED) : deux enums indépendants. Asset.carbonFootprintKg(empreinte carbone cumulée) etAsset.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). ÉtatsSparePartState:NEW,GOOD,USED,DEFECTIVE.- MTBF/MTTR : agrégats de fiabilité (
refreshReliabilityViews()), rafraîchis viaPOST /maintenance/reliability-refresh(à brancher sur un job nocturne). StorageMovementRequest(PENDING → CONFIRMED → VERIFIED) : gère le workflow WARM'UP ; génère atomiquement lesAssetMovementà 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éthode | Route | Permission |
|---|---|---|
GET | /api/workspace/assets | assets.asset:read |
POST | /api/workspace/assets | assets.asset:manage |
GET | /api/workspace/assets/[id] | assets.asset:read |
PATCH | /api/workspace/assets/[id] | assets.asset:manage |
GET / POST | /api/workspace/assets/[id]/movements | assets.asset:read / :manage |
POST | /api/workspace/assets/[id]/refurbish · /recycle · /sell · /inspect | assets.asset:manage |
GET | /api/workspace/assets/[id]/lifecycle | assets.asset:read |
GET | /api/workspace/assets/[id]/label | assets.asset:read |
POST | /api/workspace/assets/[id]/service-link | assets.asset:read |
PATCH | /api/workspace/assets/[id]/dynamic-specs | assets.asset:manage |
GET / POST | /api/workspace/assets/[id]/missing-parts | assets.asset:read / :manage |
PATCH | /api/workspace/asset-missing-parts/[id] | assets.asset:manage |
POST | /api/workspace/assets/qr-labels | assets.asset:read |
POST | /api/workspace/assets/ocr-plate | assets.asset:manage |
GET | /api/workspace/assets/deee/[reference] | assets.asset:read |
GET / PUT | /api/workspace/assets/settings | assets.catalog:read / :manage |
Assets — énergie, carbone & prédiction IA (Lot D)
| Méthode | Route | Permission |
|---|---|---|
GET / POST | /api/workspace/assets/[id]/energy | assets.asset:read / :manage |
GET | /api/workspace/assets/[id]/carbon | assets.asset:read |
GET | /api/workspace/assets/[id]/prediction | assets.asset:read |
POST | /api/workspace/assets/prediction/run | assets.asset:manage |
Assets — actions de masse
| Méthode | Route | Permission |
|---|---|---|
POST | /api/workspace/assets/bulk/change-state | assets.asset:manage |
POST | /api/workspace/assets/bulk/transfer | assets.asset:manage |
POST | /api/workspace/assets/bulk/export | assets.asset:read |
Impression d'étiquettes (async)
| Méthode | Route | Permission |
|---|---|---|
GET / POST | /api/workspace/assets/printing-tasks | assets.asset:read |
GET | /api/workspace/assets/printing-tasks/[id] | assets.asset:read |
GET | /api/workspace/assets/printing-tasks/[id]/download | assets.asset:read |
Catalogue (marques, modèles, familles, pièces, stockages)
| Méthode | Route | Permission |
|---|---|---|
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]/instances | assets.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 · /map | assets.asset:read |
GET / POST | /api/workspace/storage-locations/[id]/rates · /[rateId] (PATCH/DELETE) · /compute (POST) | storage.config:read / :manage |
Maintenance — OT & fiabilité
| Méthode | Route | Permission |
|---|---|---|
GET / POST | /api/workspace/maintenance-operations | maintenance.operation:read / :manage |
GET / PATCH | /api/workspace/maintenance-operations/[id] | maintenance.operation:read / :manage |
GET / POST | /api/workspace/maintenance-operations/[id]/signatures | maintenance.operation:read / :manage |
POST | /api/workspace/maintenance-operations/[id]/parts | maintenance.operation:manage |
DELETE | /api/workspace/maintenance-operations/[id]/parts/[partId] | maintenance.operation:manage |
GET | /api/workspace/maintenance/reliability | maintenance.operation:read |
POST | /api/workspace/maintenance/reliability-refresh | maintenance.operation:manage |
GET | /api/workspace/maintenance/stats · /mtbf-by-model | assets.asset:read |
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éthode | Route | Permission |
|---|---|---|
GET / POST | /api/workspace/transport-requests | assets.asset:read / :manage |
GET / PATCH | /api/workspace/transport-requests/[id] | assets.asset:read / :manage |
GET | /api/workspace/transport-requests/[id]/document | assets.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-eve | assets.asset:manage |
GET / POST | /api/workspace/carriers · /[id] (GET/PATCH) | assets.asset:read / :manage |
SAV public (sans session)
| Méthode | Route | Permission |
|---|---|---|
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 :
/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)
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 Nitrolease:maintenance-billingfacture quotidiennement les échéances dues (horizon J+15, Lot L2 Phase 6). Voir le domaine Location.
OT curatif
- Client via QR →
POST /api/public/asset/[shortCode]/report→ OTPLANNED CURATIVE. - Portail client
/client/maintenance/new→ idem. - Interne → création depuis fiche asset.
- Notification responsable SAV → affectation technicien.
- Technicien :
PATCHversIN_PROGRESSà l'arrivée, diagnostic + résolution + pièces + photos + signature client, puisPATCH status: "DONE". - Rapport PDF généré, envoyé au client, archivé.
- Si coût OT > seuil configuré par org → devis exigé avant intervention.
SLA & escalade
slaDueAtcalculé à 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 unEstablishmentlié à unLeaseContractactif (sinon warning). - Transfert inter-dépôts → enregistre un
AssetMovement(fromLocationId/toLocationId) et met à jourAsset.currentLocationId. - L'historique des emplacements se lit via
AssetMovement(routeGET /assets/[id]/movements).
QR code / Lien de service
- Un
ServiceLinkpeut être pré-imprimé et affecté à un détenteur (statutIN_STOCK→ASSIGNED), puis associé à un asset (LINKED) ; soncodeest alors partagé avecAsset.serviceShortCode(collision check). POST /assets/[id]/service-linkgé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 versDONEouCANCELEDuniquement (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/MTTRpar modèle rafraîchis viaPOST /maintenance/reliability-refresh(à brancher sur un job nocturne). - Workflow WARM'UP :
StorageMovementRequest PENDING → CONFIRMED → VERIFIED; génération atomique desAssetMovementà 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énement | Canal | Destinataire |
|---|---|---|
| OT créé (curatif) | In-app | Responsable SAV |
| OT assigné | In-app + email | Technicien |
| OT proche SLA | In-app + email | Responsable SAV |
| OT en retard SLA | In-app + email + SMS | Responsable SAV + direction |
| OT complété | In-app + email + PDF | Client demandeur |
| Asset perdu | In-app | Manager logistique |
| Stock pièces bas | In-app + email | Responsable logistique |
| QR code visité | In-app (low priority) | Commercial du compte |
| Maintenance préventive due | In-app | Responsable SAV |
Location
Référence technique du domaine Location — affaires, contrats, financement PMT, agréments bailleurs, cessions, assurance, maintenance, prélèvements et engagements bancaires.
Comptabilité
Référence technique du domaine Comptabilité analytique & clôture — plan comptable, affectation des charges, immobilisations, clôture annuelle, pivots.