mirror of
https://github.com/siop-spelev/siop2.git
synced 2026-08-08 12:41:54 +00:00
feat(r2.3): écrans web exploitation — OT, demandes, préventif, compteurs, urgence
- liste OT (filtres, strie rouge, « immédiat ») ; fiche OT : transitions pilotées par allowedTransitions, clôture grisée avec la garde expliquée, bilan codé (6 selects sur référentiels), checklist Fait→N-A→à faire, activité + commentaires, assignation, annulation motivée - nouvel OT : interrupteur « personne bloquée » qui force la priorité - demandes : table + panneau d'approbation (priorité, assignation, approuver → fiche OT), rejet en modale à motif obligatoire, signalement interne ; statut « Résolue » dérivé de l'OT lié - préventif : tuiles réelles, générer + résumé (« regénérer ne double rien »), gabarits administrables ; compteurs : saisie + historique - tableau de bord réel : bandeau urgence cliquable, KPIs, OT par statut, interventions récentes ; accueil dédié aux rôles sans exploitation - urgence traversante : chip topbar pulsante (60 s), badges de nav - GET /assets/options (auth seule) : le Demandeur peut désigner l'appareil qu'il signale — trou débusqué par l'e2e (49 opérations au contrat) - génération préventive durcie : collision de référence RETENTÉE (plus de saut silencieux), P2003 toléré ; 3 runs Jest complets consécutifs verts - 9 tests Playwright (recette R2 officielle rejouée intégralement), 50 tests API (94,6 % / 78,9 %) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -31,6 +31,13 @@ export class AssetsController {
|
||||
return this.assetsService.list();
|
||||
}
|
||||
|
||||
/** Avant ':id' (ordre des routes) — authentification seule : le demandeur
|
||||
* doit pouvoir désigner l'appareil qu'il signale. */
|
||||
@Get('options')
|
||||
options() {
|
||||
return this.assetsService.options();
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@RequirePermission('ASSETS', 'view')
|
||||
get(@Param('id', ParseUUIDPipe) id: string) {
|
||||
|
||||
@@ -11,6 +11,7 @@ import type {
|
||||
AssetCreate,
|
||||
AssetDetail,
|
||||
AssetDto,
|
||||
AssetOptionsResponse,
|
||||
AssetsResponse,
|
||||
AssetUpdate,
|
||||
} from '@siop/shared';
|
||||
@@ -28,6 +29,21 @@ type AssetRow = Prisma.AssetGetPayload<{ include: typeof assetInclude }>;
|
||||
export class AssetsService {
|
||||
constructor(private readonly prisma: PrismaService) {}
|
||||
|
||||
/** Options minimales pour le signalement — ouvert à tout rôle authentifié. */
|
||||
async options(): Promise<AssetOptionsResponse> {
|
||||
const rows = await this.prisma.asset.findMany({
|
||||
include: { location: { include: { parent: true } } },
|
||||
orderBy: { reference: 'asc' },
|
||||
});
|
||||
return {
|
||||
options: rows.map((r) => ({
|
||||
id: r.id,
|
||||
reference: r.reference,
|
||||
siteName: r.location.parent?.name ?? r.location.name,
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
async list(): Promise<AssetsResponse> {
|
||||
const rows = await this.prisma.asset.findMany({
|
||||
include: assetInclude,
|
||||
|
||||
Reference in New Issue
Block a user