# wallet_notifications

Notification service for user-directed messages: transaction alerts, security events, OTP delivery, and promotional communications.

## Responsibility
- Queue and deliver notifications across multiple channels (email, SMS, push, in-app).
- Enforce per-user, per-channel notification preferences and suppression rules.
- Track delivery status (queued → sending → sent | failed) with retry history.
- Provide idempotent notification queueing to prevent duplicate sends.

## Public Interface

### Commands
| Module | Action |
|---|---|
| `WalletNotifications.Commands.QueueNotification` | Queue a notification for async delivery |
| `WalletNotifications.Commands.SendNotification`  | Synchronously send a single notification |
| `WalletNotifications.Commands.UpdatePreferences` | Set/update user channel preferences |

### Queries
| Module | Action |
|---|---|
| `WalletNotifications.Queries.GetNotification`        | Get notification by ID |
| `WalletNotifications.Queries.ListUserNotifications`  | List notifications for a user (filterable) |

### Events Emitted
| Event | Trigger |
|---|---|
| `NotificationQueued.v1`  | Notification created and enqueued |
| `NotificationSent.v1`    | Notification delivered (or preference-suppressed) |
| `NotificationFailed.v1`  | Delivery attempt failed |

## Channel Adapters
Phase 5 uses `WalletNotifications.Adapters.StubAdapter` for all channels.
Phase 6 replaces with production adapters per channel:

| Channel | Adapter |
|---|---|
| `:email`  | SES / SendGrid |
| `:sms`    | Twilio / Clickatell |
| `:push`   | FCM / APNs |
| `:in_app` | Phoenix PubSub broadcast |

Override per channel via Application env:

    config :wallet_notifications, :email_adapter, MyEmailAdapter

## Preference Model
- Per-user, per-channel: enabled boolean + suppression_rules map.
- Suppression rules: `quiet_hours`, `opt_out_types`, `daily_limit`.
- Default: all channels enabled when no preference is set.

## Idempotency
- Provide an `idempotency_key` to `QueueNotification` for safe retries.
- Duplicate queue requests with the same key return the existing notification.

## Queue Topology
Notifications are queued via `WalletSettlement.JobQueue` (Phase 5 CI):
- `:notifications_high` — OTP, security alerts, transaction alerts.
- `:notifications_low`  — promotional, system.

## Dependencies
- `wallet_shared_kernel`, `wallet_api_contracts`, `wallet_observability`, `wallet_events`
- `wallet_settlement` (shared `JobQueue` for CI; in production, own Oban queues)

## Allowed Callers
- `wallet_web` (user notification endpoints)
- `wallet_auth` (OTP delivery)
- `wallet_transfers` (transaction alerts post-completion)
- `wallet_journey` (end-of-journey summary notification)
