diff --git a/apps/api/src/work-orders/work-orders.service.ts b/apps/api/src/work-orders/work-orders.service.ts index 7e67447..68de110 100644 --- a/apps/api/src/work-orders/work-orders.service.ts +++ b/apps/api/src/work-orders/work-orders.service.ts @@ -92,12 +92,14 @@ export class WorkOrdersService { asset: { include: { location: { include: { parent: true } } } }, assignees: true, }, - orderBy: [{ status: 'asc' }, { createdAt: 'desc' }], + // Dernière activité d'abord : un OT qui vient d'être clôturé remonte + // (« Interventions récentes » du tableau de bord = tête de liste). + orderBy: { updatedAt: 'desc' }, }); - // « personne bloquée » saute en tête, toujours - rows.sort((a, b) => - Number(b.priority === 'PERSON_TRAPPED') - Number(a.priority === 'PERSON_TRAPPED'), - ); + // « personne bloquée » ACTIVE saute en tête, toujours (tri stable) + const urgenceActive = (r: (typeof rows)[number]) => + r.priority === 'PERSON_TRAPPED' && r.status !== 'DONE' && r.status !== 'CANCELLED'; + rows.sort((a, b) => Number(urgenceActive(b)) - Number(urgenceActive(a))); return { workOrders: rows.map((r) => this.toSummary(r)) }; } diff --git a/apps/api/test/exploitation.e2e-spec.ts b/apps/api/test/exploitation.e2e-spec.ts index 32d8548..947c9f5 100644 --- a/apps/api/test/exploitation.e2e-spec.ts +++ b/apps/api/test/exploitation.e2e-spec.ts @@ -131,6 +131,22 @@ describe('Exploitation (e2e)', () => { ); expect(laMienne.workOrder.status).toBe('DONE'); + // 6 bis. Régression recette R2 : l'OT fraîchement clôturé remonte EN TÊTE + // de la liste de Salma (après les urgences actives) — il doit apparaître + // dans les « Interventions récentes » de tout le monde, pas seulement + // chez l'assigné. + const { body: listeSalma } = await http() + .get('/work-orders') + .set(auth(salma)) + .expect(200); + const position = listeSalma.workOrders.findIndex((w: { id: string }) => w.id === id); + const urgencesActives = listeSalma.workOrders.filter( + (w: { priority: string; status: string }) => + w.priority === 'PERSON_TRAPPED' && w.status !== 'DONE' && w.status !== 'CANCELLED', + ).length; + expect(position).toBeGreaterThanOrEqual(0); + expect(position).toBeLessThanOrEqual(urgencesActives); + // 7. Terminal : plus aucune transition await http() .post(`/work-orders/${id}/transition`) diff --git a/docs/journal/journal.md b/docs/journal/journal.md index 81ad2d1..1a936c2 100644 --- a/docs/journal/journal.md +++ b/docs/journal/journal.md @@ -4,6 +4,16 @@ Trace chronologique des sessions (la plus récente en premier). Le **playbook** --- +## 2026-07-16 — Pr. Daaif (+ Claude) — Recette R2 : anomalie du référent corrigée + +**Anomalie (recette du référent)** : un OT créé, assigné à Ahmed, traité et clôturé apparaissait dans le tableau de bord d'Ahmed mais PAS dans celui de Salma ni de l'administrateur. + +**Diagnostic** : la liste API triait **par statut d'abord** (les Terminés relégués en queue) et le tableau de bord affiche les 5 premières lignes. Ahmed, sans « voir autre », a une liste courte → son OT clôturé restait dans le top 5 ; Salma et l'admin voient tout le parc → l'OT clôturé était éjecté des « Interventions récentes ». (La liste OT filtrait aussi « actifs » par défaut, conforme à la maquette — c'est le tableau de bord qui trompait.) + +**Correctif** : la liste trie par **dernière activité** (`updatedAt` desc) — un OT qui vient d'être clôturé remonte en tête pour tout le monde ; les urgences « personne bloquée » **actives** restent épinglées au sommet (un OT d'urgence annulé ne squattait plus la tête, corrigé au passage). Reproduit avant / vérifié après sur le scénario exact du référent ; **test de régression** ajouté à la recette e2e (position de l'OT clôturé dans la liste de Salma ≤ nombre d'urgences actives). 50 tests API + 11 Playwright verts. + +--- + ## 2026-07-16 — Pr. Daaif (+ Claude) — R2.4 : portail public QR — l'étiquette prend vie **Actions**