Story OP-014: Backend résolution anomalies (façade vers ING)¶
Module: operator-console
Slice: Architecture §11 OP-004c + US-OP-08
Side: [BACKEND]
Version target: V0.0.3
Priority: 15
Depends on: OP-007 (édition cc + AnomalyQueryAdapter), ING (AnomalyService.findOpen + resolve)
Can develop concurrently with: OP-012, OP-013, OP-015
Merge order: Before OP-018 (frontend anomalies)
Estimated complexity: S
PRD User Stories: US-OP-08 AC1+AC2+AC3+AC4
Wireframe: N/A — backend only
Objective¶
Exposer les endpoints OP qui projettent les anomalies du module ING dans le namespace operator (/api/operator/anomalies) et permettent de les marquer résolues. La logique métier vit dans ING ; OP ajoute le scoping operator + l'audit ANOMALY_RESOLVED.
Backend Scope¶
Service Layer¶
AnomaliesController:GET /api/operator/anomalies?type=&status=&cursor=&pageSize=50— délègue àAnomalyService.findOpen(tenantId, agencyId, filters).-
PATCH /api/operator/anomalies/{id}body{ "status": "RÉSOLUE"|"IGNORÉE", "note"?: "string" }:- Validation : statut transition légale (OUVERTE→RÉSOLUE/EN_COURS→RÉSOLUE/EN_COURS→IGNORÉE/etc — déléguée à ING).
- Note obligatoire pour anomalies de type SURVEILLANCE marquées RÉSOLUE (US-OP-08 AC4) — sinon 400
OP_NOTE_REQUIRED. - Délègue à
AnomalyService.resolve(tenantId, anomalyId, status, note, operatorId). - Audit OP
ANOMALY_RESOLVED {anomalyId, contractId, type, oldStatus, newStatus, note?, operatorId, timestamp}(en plus de l'audit ING propre).
-
AnomalySummaryProjection(read) :
API Endpoints¶
| Method | Path | Request | Response | Auth |
|---|---|---|---|---|
GET |
/api/operator/anomalies?type=&status=&cursor=&pageSize=50 |
— | { data, nextCursor, hasMore } |
Tous OP |
PATCH |
/api/operator/anomalies/{id} |
{ status, note? } |
200 { id, status } |
agency_operator+cabinet_admin |
Validation Rules¶
type∈ enum.statuscible ∈ {RÉSOLUE, IGNORÉE, EN_COURS}.noterequis si transition RÉSOLUE sur SURVEILLANCE.pageSize∈ [1, 100].
Multi-Tenant Considerations¶
- Scope
tenant_id. agency_id:AnomalyService.findOpen(tenantId, agencyId, ...)filtre côté ING ; AgencyScopeFilter OP transparent (déjà appliqué à l'adapter).
Audit & Logging¶
ANOMALY_RESOLVEDcorrelation_id =anomalyId, payload détaillé.
Acceptance Criteria¶
AC-001: GET /anomalies retourne la queue scoped agence
Given un tenant avec 5 anomalies (3 agence A, 2 agence B)
When agency_operator A appelle GET /anomalies
Then 3 anomalies retournées (toutes de A).
When cabinet_admin appelle GET /anomalies sans filtre
Then 5 anomalies retournées.
AC-002: Résolution anomalie standard → 200 + audit
Given une anomalie OUVERTE de type NON_BLOCKING
When PATCH /anomalies/{id} body={"status":"RÉSOLUE"}
Then 200, et ANOMALY_RESOLVED audit créé.
AC-003: Résolution SURVEILLANCE sans note → 400 (US-OP-08 AC4)
Given anomalie SURVEILLANCE OUVERTE
When PATCH body={"status":"RÉSOLUE"} (sans note)
Then 400 OP_NOTE_REQUIRED.
When body={"status":"RÉSOLUE","note":"Vérifié avec client par téléphone"}
Then 200 + ANOMALY_RESOLVED avec note.
AC-004: Filtre par type
Given mix d'anomalies
When GET /anomalies?type=BLOCKING
Then seules les BLOCKING retournées.
Compliance Rules¶
- US-OP-08 AC4 : note obligatoire SURVEILLANCE.
VÉRIFIÉ. - Audit critical rule #3 :
ANOMALY_RESOLVED.VÉRIFIÉ.
Standards & Conventions¶
docs/standards/api-guidelines.md— pagination, validation.docs/standards/multi-tenant-model.md— agency scoping via adapter.
Testing Requirements¶
Unit Tests¶
AnomaliesControllerTest: validation note SURVEILLANCE.
Integration Tests¶
AnomalyResolutionITAC-001..AC-004 avec ING fixtures.
What QA Will Validate¶
- Smoke : résoudre une anomalie → ING + OP audit logs cohérents.
Out of Scope¶
- Frontend page anomalies → OP-018.
- Assignment d'anomalies par operator (V2).
Definition of Done¶
- [ ] Les 2 endpoints retournent 200 conformes
- [ ] AC-001..AC-004 passent
- [ ] ANOMALY_RESOLVED audité
- [ ] Note obligatoire SURVEILLANCE enforcée
- [ ] Scope agence respecté
- [ ] Tests verts