mirror of
https://github.com/siop-spelev/siop2.git
synced 2026-08-08 12:41:54 +00:00
feat(r2.2): préventif — génération mensuelle idempotente — et compteurs
- migration : Asset.underContract + WorkOrder.periodKey avec unicité [assetId, periodKey] — l'idempotence de la génération est EN BASE (deux appels concurrents ne doublent jamais une grille) - génération : une grille par appareil sous contrat, périodicités ancrées sur la mise en service (mensuelles toujours dues), premier contrôle (toutes les tâches) pour un appareil sans historique, échéance fin de mois, événement GENERATED ; déclenchement manuel (cron au durcissement) - gabarits administrables (désactivé = exclu des générations suivantes) ; GET /preventive/status (générées, terminées, en retard, premiers contrôles) - compteurs : GET meters (2 compteurs, récents d'abord) ; relevé strictement croissant, refus motivé sinon - contrat +7 opérations (48) ; 50 tests verts (94,7 % / 78 %) ; smoke test prod : juillet généré (9 grilles, 8 premiers contrôles), 2e appel à zéro Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
370
apps/web/src/api/schema.d.ts
vendored
370
apps/web/src/api/schema.d.ts
vendored
@@ -355,6 +355,109 @@ export interface paths {
|
||||
patch: operations["updateUser"];
|
||||
trace?: never;
|
||||
};
|
||||
"/preventive/templates": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
/** Gabarits de tâches du préventif (périodicité en mois) */
|
||||
get: operations["listTaskTemplates"];
|
||||
put?: never;
|
||||
/** Ajouter un gabarit */
|
||||
post: operations["createTaskTemplate"];
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/preventive/templates/{id}": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get?: never;
|
||||
put?: never;
|
||||
post?: never;
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
/** Modifier / (dés)activer un gabarit — jamais de suppression si utilisé */
|
||||
patch: operations["updateTaskTemplate"];
|
||||
trace?: never;
|
||||
};
|
||||
"/preventive/generate": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get?: never;
|
||||
put?: never;
|
||||
/** Générer la grille du mois — IDEMPOTENT (regénérer ne double rien) */
|
||||
post: operations["generatePreventive"];
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/preventive/status": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
/** État du mois courant (générées, terminées, en retard, premiers contrôles) */
|
||||
get: operations["getPreventiveStatus"];
|
||||
put?: never;
|
||||
post?: never;
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/assets/{id}/meters": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
/** Compteurs de l’appareil (relevés récents d’abord) */
|
||||
get: operations["getAssetMeters"];
|
||||
put?: never;
|
||||
post?: never;
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/assets/{id}/meter-readings": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get?: never;
|
||||
put?: never;
|
||||
/** Enregistrer un relevé — strictement croissant */
|
||||
post: operations["addMeterReading"];
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/work-orders": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
@@ -941,6 +1044,83 @@ export interface components {
|
||||
teamIds?: string[];
|
||||
isActive?: boolean;
|
||||
};
|
||||
TaskTemplatesResponse: {
|
||||
templates: {
|
||||
/** Format: uuid */
|
||||
id: string;
|
||||
label: string;
|
||||
periodMonths: number;
|
||||
isRegulatory: boolean;
|
||||
isActive: boolean;
|
||||
componentTypeId: string | null;
|
||||
componentTypeName: string | null;
|
||||
}[];
|
||||
};
|
||||
TaskTemplate: {
|
||||
/** Format: uuid */
|
||||
id: string;
|
||||
label: string;
|
||||
periodMonths: number;
|
||||
isRegulatory: boolean;
|
||||
isActive: boolean;
|
||||
componentTypeId: string | null;
|
||||
componentTypeName: string | null;
|
||||
};
|
||||
TaskTemplateCreate: {
|
||||
label: string;
|
||||
periodMonths: number;
|
||||
/** Format: uuid */
|
||||
componentTypeId?: string;
|
||||
isRegulatory?: boolean;
|
||||
};
|
||||
TaskTemplateUpdate: {
|
||||
label?: string;
|
||||
periodMonths?: number;
|
||||
componentTypeId?: string | null;
|
||||
isRegulatory?: boolean;
|
||||
isActive?: boolean;
|
||||
};
|
||||
PreventiveGenerationResult: {
|
||||
month: string;
|
||||
created: number;
|
||||
skipped: number;
|
||||
firstControls: number;
|
||||
references: string[];
|
||||
};
|
||||
PreventiveGenerate: {
|
||||
month?: string;
|
||||
};
|
||||
PreventiveStatus: {
|
||||
month: string;
|
||||
assetsUnderContract: number;
|
||||
generated: number;
|
||||
done: number;
|
||||
late: number;
|
||||
firstControls: number;
|
||||
};
|
||||
MetersResponse: {
|
||||
meters: {
|
||||
/** @enum {string} */
|
||||
kind: "RUNNING_HOURS" | "STARTS";
|
||||
readings: {
|
||||
/** Format: uuid */
|
||||
id: string;
|
||||
value: number;
|
||||
readBy: {
|
||||
/** Format: uuid */
|
||||
id: string;
|
||||
displayName: string;
|
||||
} | null;
|
||||
/** Format: date-time */
|
||||
createdAt: string;
|
||||
}[];
|
||||
}[];
|
||||
};
|
||||
MeterReadingCreate: {
|
||||
/** @enum {string} */
|
||||
kind: "RUNNING_HOURS" | "STARTS";
|
||||
value: number;
|
||||
};
|
||||
WorkOrdersResponse: {
|
||||
workOrders: {
|
||||
/** Format: uuid */
|
||||
@@ -1947,6 +2127,196 @@ export interface operations {
|
||||
};
|
||||
};
|
||||
};
|
||||
listTaskTemplates: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
/** @description Liste */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["TaskTemplatesResponse"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
createTaskTemplate: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["TaskTemplateCreate"];
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
/** @description Créé */
|
||||
201: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["TaskTemplate"];
|
||||
};
|
||||
};
|
||||
/** @description Libellé déjà utilisé */
|
||||
409: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
updateTaskTemplate: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path: {
|
||||
id: string;
|
||||
};
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["TaskTemplateUpdate"];
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
/** @description Mis à jour */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["TaskTemplate"];
|
||||
};
|
||||
};
|
||||
/** @description Inconnu */
|
||||
404: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
generatePreventive: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["PreventiveGenerate"];
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
/** @description Résumé de génération */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["PreventiveGenerationResult"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
getPreventiveStatus: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
/** @description État */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["PreventiveStatus"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
getAssetMeters: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path: {
|
||||
id: string;
|
||||
};
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
/** @description Compteurs */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["MetersResponse"];
|
||||
};
|
||||
};
|
||||
/** @description Appareil inconnu */
|
||||
404: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
addMeterReading: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path: {
|
||||
id: string;
|
||||
};
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["MeterReadingCreate"];
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
/** @description Relevé enregistré */
|
||||
201: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["MetersResponse"];
|
||||
};
|
||||
};
|
||||
/** @description Relevé inférieur ou égal au précédent */
|
||||
400: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
listWorkOrders: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
|
||||
Reference in New Issue
Block a user