UC-09 — Détection d'anomalies
Acteur : Système (jobs automatisés) But : Détecter automatiquement les anomalies (soldes bas, écarts de stock, produits périmés)
Trigger
Plusieurs jobs planifiés analysent les données et créent des anomalies.
Préconditions
- Un seuil d'anomalie configuré par organisation (
default_anomaly_threshold_cents) - Les jobs planifiés actifs
Postconditions
- Les anomalies sont enregistrées avec un
kind, uneseverityet unstatus = open - Les anomalies
balance_lowdéclenchent une notification email (anti-spam 8 jours)
Jobs de détection
Type (kind) | Job | Fréquence | Sévérité |
|---|---|---|---|
balance_low | extract_anomalies | 06:00 | selon écart |
stock_inconsistency | reconcile_stock | 6 h | high |
expired_product | check_expiry | 1 h | medium |
Endpoints
1. Configurer le seuil
PUT /api/v1/admin/system/organizations/{id}
Content-Type: application/json
{
"default_anomaly_threshold_cents": 30000
}
2. Lister les anomalies
GET /api/v1/admin/org/anomalies?status=open&severity=medium
3. Acquitter / résoudre
POST /api/v1/admin/org/anomalies/{id}/acknowledge
POST /api/v1/admin/org/anomalies/{id}/resolve
Flow
sequenceDiagram
participant Job as Job (06:00)
participant API
participant DB
participant Outbox
participant Admin
Job->>DB: Pour chaque org active
Job->>DB: SELECT cards WHERE balance < seuil<br/>ET non notifiée depuis 8 jours
Job->>DB: INSERT anomaly (kind: balance_low)
Job->>Outbox: Emit AnomalyDetected
Outbox->>DB: INSERT notification (template anomaly_alert, email)
Note over Admin: Plus tard...
Admin->>API: GET /admin/org/anomalies
API-->>Admin: {items: [anomaly], total}
Admin->>API: POST /admin/org/anomalies/{id}/resolve
API->>DB: UPDATE status = resolved
API-->>Admin: {status: "resolved"}
Exemple de réponse (liste)
{
"items": [
{
"id": "uuid",
"kind": "balance_low",
"severity": "medium",
"status": "open",
"message": "La carte #123456 a un solde de 500 XOF sous le seuil de 3000 XOF",
"details": { "balance_cents": 500, "threshold_cents": 3000 },
"card_id": "uuid",
"holder_name": "Fatou Diallo",
"detected_at": "2025-06-01T06:00:00Z",
"acknowledged_at": null,
"resolved_at": null,
"resolved_by": null,
"created_at": "2025-06-01T06:00:00Z"
}
],
"total": 5
}
Permissions
| Permission | Description |
|---|---|
anomaly.manage | Consulter, acquitter, résoudre |
anomaly.threshold.configure | Configurer le seuil |
La détection est automatique (aucune permission utilisateur requise).
Erreurs
error_code | Description |
|---|---|
NotFound | Anomalie introuvable |
Forbidden | Permission insuffisante |