feat(notification): implement the notification delivery platform
Maps the 31-module plan onto the registry's 19 leaves as packages; the two edges the registry forbids (provider->httpclient, inbox->messaging) are replaced by application-owned ports. See docs/notification/module-mapping.md. Acceptance is not delivery: ProviderSubmissionResult refuses to carry a delivery outcome, and AMBIGUOUS is a first-class terminal state that blocks automatic retry and fallback until reconciliation resolves it. Providers: SES (SigV4 + SNS callback), Twilio (X-Twilio-Signature + reconciliation), FCM (FID-primary batch), APNs, Web Push (RFC 8030/8291/8292), SMTP and webhook. Contact points are AES-256-GCM encrypted with a separate HMAC lookup fingerprint; nothing raw reaches a log, metric tag or exception. Dispatch commits the attempt row, calls the provider with no transaction open, then records the outcome; the durable queue uses FOR UPDATE SKIP LOCKED. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
3b5aee50e3
commit
701ba67456
@@ -0,0 +1,31 @@
|
||||
# Migration guide
|
||||
|
||||
## From the R0 routing seam
|
||||
|
||||
The pre-existing `dev.caskeleton.adapter.outbound.notification` router (`RoutingNotifier`,
|
||||
`FailOpenNotificationProvider`, the Google email and Slack webhook seams) stays untouched. The
|
||||
delivery platform lives beside it under `…notification.platform` and does not modify or delete any
|
||||
R0 class.
|
||||
|
||||
Migration order per capability:
|
||||
|
||||
1. Register the contact points behind `ContactPointStorePort` so the platform owns protected values.
|
||||
2. Publish the template version, and pin the template id, version and locale at every call site.
|
||||
3. Move the call site from the router to the N1 typed facade for the channel.
|
||||
4. Verify evidence in the snapshot rather than in the caller's return value: `submit()` is durable
|
||||
acceptance and nothing more.
|
||||
5. Remove the R0 route only after the platform route has produced provider evidence in the target
|
||||
environment.
|
||||
|
||||
## Return-value semantics change
|
||||
|
||||
The R0 seam returned a send-shaped result. `NotificationReceipt` returns `notificationId`, a request
|
||||
status and an acceptance time. Callers that treated the old return value as proof of delivery must be
|
||||
changed; there is no compatibility shim, because a shim would have to invent the delivery claim this
|
||||
platform exists to avoid.
|
||||
|
||||
## FCM target migration
|
||||
|
||||
Registration tokens keep working through `LegacyFcmRegistrationToken`. New registrations should use
|
||||
`FcmInstallationId`. The two are distinct types, so a migration is a compile-time task rather than a
|
||||
runtime guess.
|
||||
Reference in New Issue
Block a user