Aller au contenu

Story Index: notifications (NOTIF) — sub-version v0.0.0

This file indexes v0.0.0 only. The notifications module is decomposed across the whole V0 envelope; each sub-version lives in its own directory and index. See the V0 sub-version roadmap below.

Module: notifications Sub-version: v0.0.0 (architecture-backed) Total stories (v0.0.0): 8 Decomposed from: docs/architecture/notifications-arch.md (v0.0.0 scope; founder-approved per /decompose invocation) PRD reference: docs/prd/notifications-prd.md (V0 Envelope §"V0 Envelope Scope" + V1 §§A/B/C as forward-compat reference) + docs/prd/prd-v0.md Design reference: N/A — NOTIF is a backend Control-plane primitive; no UI in v0.0.0 (the consent UI is v0.0.1, owned by CP) Date: 21/05/2026 (v0.0.0); 28/05/2026 (v0 roadmap + later sub-versions added)


V0 sub-version roadmap (whole module)

Sub-version Directory Stories Architecture status Theme
v0.0.0 docs/stories/v0.0.0/notifications/ NOTIF-S0, NOTIF-001a/b/c/d, NOTIF-002, NOTIF-003, NOTIF-004 (8) ✅ architecture-backed Real SMS at T0 + WhatsApp cascade at T+5d (flagged), suppression, webhooks, CI-only seed
v0.0.1 docs/stories/v0.0.1/notifications/ NOTIF-005, NOTIF-006 (2) ⚠️ [ARCH-PENDING] PRÉLIMINAIRE Functional opt-out link end-to-end + consent/disclosure copy contract (CP renders)
v0.0.2 docs/stories/v0.0.2/notifications/ NOTIF-007 (1) ⚠️ [ARCH-PENDING] PRÉLIMINAIRE Per-agency dispatch queue partitioning (agency_id)
v0.1.0 docs/stories/v0.1.0/notifications/ NOTIF-008, NOTIF-009, NOTIF-010 (3) ⚠️ [ARCH-PENDING] PRÉLIMINAIRE Tenant daily cap + platform kill-switch + Redis rate-limit & idempotent retry
14 stories total

[ARCH-PENDING] note: notifications-arch.md is explicitly v0.0.0-only; v0.0.1 / v0.0.2 / v0.1.0 are forward-compatibility checkpoints there, not designed slices. Their stories (NOTIF-005…010) are drafted from the PRD V0 Envelope + design + the v0.0.0 architecture's reserved hooks (reserved status values, stubbed admin paths, pre-provisioned agency_id). Each later-sub-version story carries an [ARCH-PENDING] banner and must be reconciled with an ARCHITECT pass for its sub-version before dev-start. Story IDs are continuous (NOTIF-002/003/004 are v0.0.0 sub-slices, NOT the PRD's original one-story-per-sub-version mapping; the later sub-versions use NOTIF-005+ to avoid collision).


Dependency Graph

                  ┌────────────┐
                  │  NOTIF-S0  │  Tier 0 (serial)
                  └─────┬──────┘
        ┌───────────────┼───────────────┐
        │               │               │
        ▼               ▼               ▼
  ┌──────────┐   ┌──────────┐
  │NOTIF-001a│   │NOTIF-001d│             (Tier 1, parallel)
  └────┬─────┘   └────┬─────┘
       │              │
       └──────┬───────┘
        ┌──────────┐   ┌──────────┐
        │NOTIF-001b│◄──│NOTIF-001c│       (NOTIF-001c can ship before 001b's prod cutover)
        └────┬─────┘   └──────────┘
   ┌─────────┼─────────────────────────┐
   ▼         ▼                         ▼
┌──────┐ ┌──────┐                   ┌──────┐
│NOTIF-│ │NOTIF-│ (parallel)        │NOTIF-│
│ 002  │ │ 003  │                   │ 004  │
└──────┘ └──────┘                   └──────┘
         CROSS-MODULE
         dependencies:
         - AUTH SignedLinkService.reissueForCascade (OQ-NOTIF-13)
         - CP customer.session_opened event (OQ-NOTIF-14)
         - AUDIT-002 catalog extension for NOTIF_SUPPRESSED_OPT_OUT

Story List

# Story ID Title Side Depends On Complexity Status
1 NOTIF-S0 Dev environment + test infrastructure for NOTIF (v0.0.0) [BACKEND] TENANT S0, AUDIT S0 S Draft
2 NOTIF-001a Dispatch endpoint + DB persistence + idempotency dual-guard [BACKEND] NOTIF-S0, AUDIT-002 M Draft
3 NOTIF-001d Country-profile resolver + provider strategy bean wiring (CI seeded) [BACKEND] NOTIF-S0, TENANT country_profile migration S Draft
4 NOTIF-001b SMS provider adapter + @Async submit + status webhook + delivery_attempt lifecycle [BACKEND] NOTIF-001a, NOTIF-001d, AUDIT-002 M Draft
5 NOTIF-001c Suppression table + pre-dispatch lookup + NOTIF_SUPPRESSED_OPT_OUT emission [BACKEND] NOTIF-001a, AUDIT-002 S Draft
6 NOTIF-002 Inbound STOP detection (capture side of mitigation #5) [BACKEND] NOTIF-001a, NOTIF-001b, NOTIF-001c M Draft
7 NOTIF-003 WhatsApp cascade at T+5d (with AUTH reissue + cancel-on-click) [BACKEND] NOTIF-001a/b/c/d + AUTH reissueForCascade + CP event L Draft
8 NOTIF-004 Crash-recovery startup job (SmsSubmitRecovery) [BACKEND] NOTIF-001b S Draft

Concurrency Tiers

Tier Stories Can Start After
0 NOTIF-S0 TENANT S0 merged, AUDIT S0 merged
1 NOTIF-001a, NOTIF-001d NOTIF-S0 merged; AUDIT-002 in flight (NOTIF-001a hard-blocks on AUDIT-002 cutover)
2 NOTIF-001b, NOTIF-001c NOTIF-001a + NOTIF-001d merged (001c can develop in parallel with 001b; merge order matters)
3 NOTIF-002, NOTIF-003, NOTIF-004 NOTIF-001b + NOTIF-001c merged (NOTIF-003 additionally needs AUTH reissueForCascade + CP customer.session_opened)

PRD Acceptance Criteria Coverage

Note on scope: this index covers the v0.0.0 architecture-level slices only. The V1 PRD §A.3 lists 11 user stories (NOTIF-US-01 through NOTIF-US-11); architecture §0 explicitly defers most ACs to later sub-versions. The table below maps the v0.0.0-relevant ACs to stories. ACs marked "deferred" land in v0.0.1 / v0.0.2 / v0.1.0 / V1 stories not in this index.

PRD User Story ACs Assigned To
NOTIF-US-01 (idempotent dispatch) AC-01.1 NOTIF-001a + NOTIF-001b (completion)
NOTIF-US-01 AC-01.2 (Idempotency-Key) NOTIF-001a
NOTIF-US-01 AC-01.3 (natural-key conflict) NOTIF-001a
NOTIF-US-01 AC-01.4 (mandatory-field gate) NOTIF-001a
NOTIF-US-02 (WA-first cascade) AC-02.1 / AC-02.2 / AC-02.3 / AC-02.4 Deferred — v0.0.0 ships SMS-first → WA at T+5d (NOTIF-ADR-02); the V1 PRD WA-first model is replaced. NOTIF-003 covers the v0.0.0 cascade.
NOTIF-US-03 (quiet hours) AC-03.1 / AC-03.2 / AC-03.3 Deferred to V1 (architecture §0 "Not in v0.0.0")
NOTIF-US-04 (cap + kill switch) AC-04. / AC-10. Deferred to v0.1.0 (architecture §0)
NOTIF-US-05 (operator timeline + retry) AC-05.* Deferred to V1
NOTIF-US-06 (webhook + reconciliation) AC-06.1 (signature) / AC-06.2 (idempotency) NOTIF-001b (status webhook), NOTIF-002 (inbound)
NOTIF-US-06 AC-06.3 (status timeline persisted) NOTIF-001b
NOTIF-US-06 AC-06.4 (5-min reconciliation polling) / AC-06.5 (event idempotency) Deferred to V1 (architecture §5 row 4)
NOTIF-US-07 (STOP suppression) AC-07.1 (SMS STOP detection) NOTIF-002
NOTIF-US-07 AC-07.2 (WA block detection) Deferred to V1 (no WA suppression source in v0.0.0)
NOTIF-US-07 AC-07.3 (suppression honored before dispatch) NOTIF-001c
NOTIF-US-07 AC-07.4 (per-tenant scope) NOTIF-001c + NOTIF-002
NOTIF-US-07 AC-07.5 (visible in operator history) Deferred to V1
NOTIF-US-07 AC-07.6 (platform-admin removal) Deferred to V1
NOTIF-US-08 (cross-border disclosure UI) AC-08.* Deferred to v0.0.1 (CP-owned)
NOTIF-US-09 (AUDIT producer contract) AC-09.1 (NOTIF_SENDING) NOTIF-001a + NOTIF-001b
NOTIF-US-09 AC-09.2 (NOTIF_FAILURE) NOTIF-001b
NOTIF-US-09 AC-09.3 (NOTIF_OPTED_OUT → renamed NOTIF_SUPPRESSED_OPT_OUT v0.0.0) NOTIF-001c
NOTIF-US-09 AC-09.4 (latency budget) / AC-09.5 (PII pseudonymization) NOTIF-001a + NOTIF-001b
NOTIF-US-10 (platform kill switch) AC-10.* Deferred to v0.1.0
NOTIF-US-11 (payment-receipt push) AC-11.* Deferred to V1
(Native architecture ACs) NOTIF-003 cascade ACs (4); NOTIF-002 STOP-write ACs (3); NOTIF-004 recovery ACs (2); NOTIF-001d resolver ACs (2); NOTIF-S0 infra ACs (3) Assigned to native owners as drafted
TOTAL (v0.0.0 scope) 24 ACs in-scope across 8 stories 24 assigned ✅

Implementation Order

  1. NOTIF-S0 — must merge first (Tier 0 serial). Unblocks Tier 1.
  2. NOTIF-001d — country-profile resolver. No business logic dependency on NOTIF-001a; can land in parallel.
  3. NOTIF-001a — dispatch endpoint + persistence + idempotency. Blocks every downstream slice. AUDIT-002 catalog extension MUST be merged first (R1 in architecture §12).
  4. NOTIF-001c — suppression read-side. MUST land before NOTIF-001b reaches production (no real SMS goes out without suppression honored — ARTCI mitigation #5).
  5. NOTIF-001b — SMS adapter + async submit + status webhook. Completes the v0.0.0 SMS happy path.
  6. NOTIF-002 — inbound STOP capture. Closes ARTCI mitigation #5 on the write side.
  7. NOTIF-004 — crash-recovery startup job. Operational hardening; can ship alongside NOTIF-002.
  8. NOTIF-003 — WhatsApp cascade at T+5d. Ships last because it cross-depends on AUTH reissueForCascade (OQ-NOTIF-13) and CP customer.session_opened (OQ-NOTIF-14); ships behind FEATURE_NOTIF_WHATSAPP_CASCADE_ENABLED until ARTCI B5+B10 are notified.

Cross-module dependencies summary

Direction Counterpart Contract Story consuming Status
Inbound AUDIT Catalog extension admits NOTIF_SUPPRESSED_OPT_OUT NOTIF-001c AUDIT-002 must ship first (R1)
Inbound TENANT country_profile columns + CI seed row NOTIF-001d TENANT-owned migration
Inbound TENANT TenantConfigCache bean NOTIF-001a/d Shared bean from TENANT S0
Inbound AUTH SignedLinkService.reissueForCascade(originalLinkId, ttl) Spring named interface NOTIF-003 OQ-NOTIF-13 — AUTH-side slice needed
Inbound CP Spring application event customer.session_opened NOTIF-003 OQ-NOTIF-14 — CP-side slice needed
Outbound AUDIT Outbox events NOTIF_SENDING, NOTIF_SENT, NOTIF_FAILURE, NOTIF_SUPPRESSED_OPT_OUT All NOTIF-001 sub-slices AUDIT consumer side
Outbound OP Spring app events notification.dispatched, notification.sent, notification.failed, notification.opted_out, notification.cascade_cancelled NOTIF-001b/c, NOTIF-003 OP consumer = V1 UI

BLOQUANTs (production GA, not pilot)

  • OQ-NOTIF-02 — ARTCI B5 + B10 authorizations for cross-border WA flowINCERTAIN — avocat requis. WhatsApp cascade ships behind FEATURE_NOTIF_WHATSAPP_CASCADE_ENABLED until both authorizations are notified. SMS-only path remains available regardless. Pilot proceeds under [FOUNDER-RISK-ACCEPTED 2026-05-20].
  • OQ-NOTIF-01 — Concrete WA BSP + SMS aggregator choice — blocks NOTIF-001b and NOTIF-003 dev-start (adapter implementation needs a target). Adapter interfaces are fixed; concrete picks land before dev-start.