fix(r2): un OT clôturé disparaissait des « Interventions récentes » des rôles voyant tout

Anomalie de recette (référent) : OT assigné à Ahmed, traité, clôturé —
visible dans son tableau de bord mais pas dans celui de Salma ni de
l'admin. Cause : liste triée par statut (Terminés en queue) alors que le
tableau de bord prend les 5 premières lignes ; les listes scopées
(technicien) sont courtes, celles des rôles « voir autre » non.

- tri par dernière activité (updatedAt desc) : un OT fraîchement clôturé
  remonte en tête pour tous
- urgences « personne bloquée » ACTIVES épinglées au sommet (une urgence
  annulée ne squatte plus la tête — corrigé au passage)
- test de régression dans la recette e2e (position ≤ urgences actives)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
pr-daaif
2026-07-16 18:01:17 +01:00
parent 50254daea4
commit f7c0da1b0f
3 changed files with 33 additions and 5 deletions

View File

@@ -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)) };
}

View File

@@ -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`)

View File

@@ -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**