Story Index: Operator Console (OP) — V0 Envelope¶
Module: operator-console
Total stories: 20 (V0 envelope only — V0.0.0 → V0.1.0)
Decomposed from: docs/architecture/operator-console-arch.md (Draft 2026-05-22, founder-approved per PO decision 2026-05-23)
PRD reference: docs/prd/operator-console-prd.md (V1) + docs/prd/prd-v0.md §4 ligne OP, §8
Design reference: docs/design/op-design.md v1.0
Date: 23/05/2026
Décisions PO : (1) Re-numérotation fine OP-001..OP-019 ; (2) V0 envelope uniquement ; (3) OP-000 Foundation dédiée (back+front) pour éliminer dérives schéma/RBAC/audit/hooks.
Contrainte de découpage¶
Chaque story ≤ 15 fichiers source ET ≤ 600 lignes. Les dépendances sont minimisées : sauf OP-000 (foundation universelle), chaque story dépend au plus de 2 stories OP. Exception documentée : OP-005 (premier flow E2E démo V0.0.0) dépend de 3 stories OP (OP-001 + OP-002 + OP-003) car le bouton « Créer et envoyer » enchaîne GET /contracts?eligible → POST /campaigns → POST /campaigns/{id}/send dans une seule UI. Les composants UI partagés découverts en cours de route (Drawer, InlineBanner, EmptyState, StatusPill, KpiTile) sont créés dans la story qui les utilise EN PREMIER puis réutilisés ; aucune story de refactor n'est planifiée pour V0.
Mapping V0 envelope → stories¶
| Sous-version | Périmètre arch | Stories OP-NNN |
|---|---|---|
[V0.0.0] |
UI création + envoi fire-and-forget, liste read-only, worker + recovery, listener no-op | OP-000, OP-001, OP-002, OP-003, OP-004 |
[V0.0.1] |
Édition inline pré-envoi (admin), vue statut polling, garde anomalies | OP-005, OP-006, OP-007, OP-008 |
[V0.0.2] |
Routing multi-agence | OP-009, OP-010 |
[V0.0.3] |
Annulation, hors-plateforme, anomalies UI, import UI | OP-011, OP-012, OP-013, OP-014, OP-015, OP-016, OP-017, OP-018 |
[V0.1.0] |
Observabilité | OP-019 |
Dependency Graph¶
OP-000 (Foundation)
│
┌─────────────────────┼─────────────────────┐
▼ ▼ ▼
OP-001 OP-002 ───► OP-003 ───► OP-004 (frontend list+créer-envoyer)
(cohort GET) (création) (envoi+worker) │
│ │
▼ │
OP-019 (obs) │
│
OP-005 ─────────┤ [V0.0.1]
(polling status) │
│
OP-006 ─────────┤
(édition + audit) │
│
OP-007 (frontend BROUILLON v2 — drawer + garde)
OP-008 (frontend ENVOYÉE — polling + KPI)
│
OP-009 ─────────┤ [V0.0.2]
(routing multi-agence backend)
OP-010 (frontend TopBar agency selector)
│
OP-011..OP-014 │ [V0.0.3] backend
OP-015..OP-018 │ [V0.0.3] frontend
│
OP-019 ─────────┘ [V0.1.0] obs
Story List¶
| # | Story ID | Title | Side | Sous-ver | Depends On | Complexité | Status |
|---|---|---|---|---|---|---|---|
| 1 | OP-000 | Foundation backend + frontend | BACKEND+OP | V0.0.0 | TENANT S0, AUDIT S0, ING-001 | M | TODO |
| 2 | OP-001 | Backend cohort éligibilité endpoint | BACKEND | V0.0.0 | OP-000, ING (ContractQueryService) | S | TODO |
| 3 | OP-002 | Backend création campagne BROUILLON | BACKEND | V0.0.0 | OP-000, ING (ContractQueryService) | M | TODO |
| 4 | OP-003 | Backend envoi campagne + CampaignSendWorker | BACKEND | V0.0.0 | OP-002, AUTH-001, NOTIF-001 | M | TODO |
| 5 | OP-004 | Backend CampaignDispatchRecovery | BACKEND | V0.0.0 | OP-003 | S | TODO |
| 6 | OP-005 | Frontend liste campagnes + flow Créer-et-envoyer | OPERATOR | V0.0.0 | OP-001, OP-002, OP-003 | M | TODO |
| 7 | OP-006 | Backend polling endpoint GET /campaigns/{id}/status |
BACKEND | V0.0.1 | OP-003 | S | TODO |
| 8 | OP-007 | Backend édition pré-envoi + garde anomalies bloquantes | BACKEND | V0.0.1 | OP-002, ING (AnomalyService) | M | TODO |
| 9 | OP-008 | Frontend détail BROUILLON v2 (Drawer édition + garde) | OPERATOR | V0.0.1 | OP-005, OP-007 | M | TODO |
| 10 | OP-009 | Frontend détail ENVOYÉE (polling + KPI strip) | OPERATOR | V0.0.1 | OP-005, OP-006 | M | TODO |
| 11 | OP-010 | Backend routing multi-agence (AgencyScopeFilter active) | BACKEND | V0.0.2 | OP-002, OP-007, TENANT-002 | S | TODO |
| 12 | OP-011 | Frontend TopBar agency selector + URL persistence | OPERATOR | V0.0.2 | OP-005, OP-010 | S | TODO |
| 13 | OP-012 | Backend annulation campagne (POST /campaigns/{id}/cancel) |
BACKEND | V0.0.3 | OP-003, AUTH (revokeLinks), NOTIF (cancelPending) | M | TODO |
| 14 | OP-013 | Backend exclusion en lot + marquage hors-plateforme | BACKEND | V0.0.3 | OP-007 | S | TODO |
| 15 | OP-014 | Backend résolution anomalies (delegate ING) | BACKEND | V0.0.3 | OP-007, ING (AnomalyService) | S | TODO |
| 16 | OP-015 | Backend import UI passthrough (POST/GET /imports) |
BACKEND | V0.0.3 | OP-000, ING (ImportService) | S | TODO |
| 17 | OP-016 | Frontend annulation campagne (modale + cleanup) | OPERATOR | V0.0.3 | OP-009, OP-012 | S | TODO |
| 18 | OP-017 | Frontend bulk exclude + modale hors-plateforme | OPERATOR | V0.0.3 | OP-008, OP-009, OP-013 | M | TODO |
| 19 | OP-018 | Frontend page Anomalies (queue + tabs + drawer) | OPERATOR | V0.0.3 | OP-008, OP-014 | M | TODO |
| 20 | OP-019 | Frontend page Imports (drop-zone + résultat + history) | OPERATOR | V0.0.3 | OP-015 | M | TODO |
| 21 | OP-020 | Observabilité Micrometer + health + MDC enrichment | BACKEND | V0.1.0 | OP-003, OP-004 | S | TODO |
Concurrency Tiers¶
| Tier | Stories | Peut commencer après |
|---|---|---|
| T0 | OP-000 | TENANT S0 + AUDIT S0 + ING-001 |
| T1 | OP-001, OP-002, OP-015 | OP-000 |
| T2 | OP-003 | OP-002 |
| T3 | OP-004, OP-006 | OP-003 |
| T4 | OP-005 | OP-001 + OP-002 + OP-003 |
| T5 | OP-007 | OP-002 + ING AnomalyService |
| T6 | OP-008, OP-009 | OP-005 + (OP-006 ou OP-007) |
| T7 | OP-010 | OP-002 + OP-007 + TENANT-002 |
| T8 | OP-011 | OP-005 + OP-010 |
| T9 | OP-012, OP-013, OP-014 | OP-003 + OP-007 |
| T10 | OP-016, OP-017, OP-018, OP-019 | OP-008/009 + leur backend |
| T11 | OP-020 (observabilité) | OP-003 + OP-004 |
Parallélisation maximale : T1 (3 stories en parallèle), T9 (3 backend), T10 (4 frontend).
PRD Acceptance Criteria Coverage (V0 envelope)¶
Les ACs V1 hors V0 envelope sont non assignés ici par décision (V1 sera décomposé séparément). Les ACs V0 sont définis dans l'architecture §0 et le PRD V0 §4 ligne OP, pas dans la table US-OP-* du PRD V1.
| PRD V1 User Story / V0 envelope item | ACs concernés en V0 | Assigné à |
|---|---|---|
| V0.0.0 — Liste campagnes read-only | (envelope) | OP-005 |
| V0.0.0 — Création + envoi fire-and-forget | (envelope) | OP-001, OP-002, OP-003, OP-004, OP-005 |
V0.0.0 — ImportCommitted listener no-op |
(envelope) | OP-000 |
| V0.0.1 — Édition inline pré-envoi (admin) | US-OP-04 AC3 | OP-007, OP-008 |
| V0.0.1 — Vue statut post-envoi (polling) | US-OP-05 AC1 (polling subset) | OP-006, OP-009 |
| V0.0.1 — Garde anomalies bloquantes | US-OP-04 AC2 / FR-OP-02 | OP-007, OP-008 |
| V0.0.1 — DOB masqué en liste | US-OP-04 AC1 / FR-OP-06 | OP-008 |
| V0.0.2 — Routing multi-agence | US-OP-02 AC3 / FR rules | OP-010, OP-011 |
| V0.0.3 — Annulation campagne | US-OP-07 AC1+AC2 / FR-OP-05 | OP-012, OP-016 |
| V0.0.3 — Bulk exclude | US-OP-04 AC4 | OP-013, OP-017 |
| V0.0.3 — Marquage hors-plateforme | US-OP-06 AC1+AC2+AC3 / FR-OP-08 | OP-013, OP-017 |
| V0.0.3 — UI anomalies + résolution | US-OP-08 AC1+AC2+AC3+AC4 | OP-014, OP-018 |
| V0.0.3 — UI upload import (delegate ING) | US-OP-01 AC1+AC2+AC3+AC4 | OP-015, OP-019 |
| V0.1.0 — Observabilité | (envelope) | OP-020 |
Couverture V0 : 100 % des items du V0 envelope assignés ; ACs V1 hors envelope explicitement marqués hors scope dans la section "Out of Scope" de chaque story.
Implementation Order (recommandé)¶
- OP-000 — débloque tout le reste, doit être merge AVANT toute autre story OP.
- OP-001 + OP-002 + OP-015 (parallèle) — endpoints backend.
- OP-003 — déclenche l'envoi (depends OP-002).
- OP-004 + OP-006 (parallèle) — recovery + polling endpoint.
- OP-005 — premier frontend, prouve le flow fire-and-forget end-to-end (milestone démo V0.0.0).
- OP-007 — édition + garde (V0.0.1 backend).
- OP-008 + OP-009 (parallèle) — détail BROUILLON v2 + détail ENVOYÉE (V0.0.1 frontend, démo V0.0.1).
- OP-010 + OP-011 — multi-agence (démo V0.0.2).
- OP-012 + OP-013 + OP-014 (parallèle backend V0.0.3).
- OP-016 + OP-017 + OP-018 + OP-019 (parallèle frontend V0.0.3, démo V0.0.3).
- OP-020 — observabilité (démo V0.1.0).
Hors Scope V0 (re-décomposés ultérieurement)¶
Toutes les fonctionnalités V1 absentes du V0 envelope : Dashboard (US-OP-09), Recherche globale (US-OP-10), Exports (US-OP-11), Paramètres cabinet édition (US-OP-12 — GET settings est inclus en V0.0.0, PATCH est V1), Gestion utilisateurs (US-OP-13), Ajout contrat à campagne envoyée (US-OP-14), Création ad hoc avec sélecteur (US-OP-03), Rappel + renvoi lien (US-OP-05 AC4 / FR-OP-09), SSE temps réel (US-OP-05 AC1 SSE), Cohort planifiée 2×/sem (FR-OP-01), Notes localStorage offline (FR-OP-15), Badge URGENT (TD-2). Réservé V1 PO pass.
Bloquants à lever avant dev-start¶
Hérités de l'architecture §Appendice B :
- OQ-OP-04 (BLOQUE OP-002 dev-start) : NOTIF dispatch() no-op silencieux sur conflit UNIQUE(campaign_contract_id) — confirmer avec NOTIF ARCHITECT.
- OQ-X14 (BLOQUE OP-001 dev-start) : catalog AUDIT AuditEventType doit admettre les 14 types OP avant tout dev OP.
- OQ-OP-02 : masquage partiel téléphone — décision ARTCI avant V1 ; en V0 affichage clair (architecture §7.4).
Conformité — synthèse¶
| Statut | Items | Politique |
|---|---|---|
VÉRIFIÉ |
Positionnement plateforme (PRD §C.1), piste audit suffisante | Implémentable |
PRÉLIMINAIRE ([LEGAL-REVIEW]) |
TV-01 mentions CIMA, TV-02 lien 72h, TV-03 WhatsApp/ARTCI | Implémentable avec warning |
INCERTAIN |
aucun en V0 | — |
Chaque story porte la liste explicite des règles compliance qu'elle touche, avec article et statut.