Epic 10 — Notifications & Preferences
Covers in-app and external (email/Slack) notifications on PR-created and run-failed events, per-project subscription management, quiet hours, and user-level theme and locale preferences.
Personas: BU (primary subscriber) AP (approval notifications) OP
Shared modules:
CorrelationChip
EnvProvenance
Story 10.1 — Receive In-App Notifications
- As a
- BU
- I want
- to receive in-app notifications when a run completes or fails
- So that
- I know immediately when my pipeline needs attention without watching the timeline
Scenario: In-app notification on run failure
Giventhe user has an active in-app notification subscription for the project and a run transitions to
failed
Whenthe notification arrives (via polling or WebSocket push)
Thena notification badge increments in the global navigation; the notification panel shows: project name, run_id (truncated), status badge Failed, timestamp, and a deep-link to the run timeline
Scenario: In-app notification on PR created
Whenthe notification arrives for a completed PR delivery
Thenthe notification panel shows: project name,
run_id, PR created, PR URL (external link), and timestamp
| Endpoint / DB | Purpose |
|---|---|
GET /notifications | Poll or WebSocket push for notification list |
POST /notifications/{id}/read | Mark notification as read |
Story 10.2 — Per-Project Subscription Management
- As a
- BU
- I want
- to subscribe or unsubscribe to notifications for specific projects
- So that
- I only receive notifications for the repositories I care about
Scenario: Subscribe to a project's notifications
Whenthe user toggles the subscription on in the project settings
Then
POST /subscriptions is issued with { "project_id": "...", "events": ["run_failed", "pr_created"] }; the toggle reflects the subscribed state
Scenario: Unsubscribe from a project's notifications
Whenthe user toggles the subscription off
Then
DELETE /subscriptions/{subscription_id} is issued; the toggle reflects the unsubscribed state; no further notifications arrive from that project
| Endpoint / DB | Purpose |
|---|---|
POST /subscriptions | Create subscription; events array selects event types |
DELETE /subscriptions/{subscription_id} | Remove subscription |
GET /subscriptions | List active subscriptions |
Story 10.3 — External Delivery Channels (Email and Slack)
- As a
- BU
- I want
- to receive run-failed and PR-created notifications via email or Slack
- So that
- I am alerted even when I am not actively using the AMTP app
Scenario: Email and Slack delivery on subscribed event
Giventhe user has set a delivery email address and/or Slack incoming webhook URL in notification preferences and has an active subscription for a project
Whena subscribed event fires (e.g. run failed)
Thenan email/Slack message is sent containing the project name,
run_id, status, and a deep-link to the run timeline
Scenario: No delivery channel configured — in-app only
Giventhe user has no email address and no Slack webhook in preferences
Thenonly the in-app notification (Story 10.1) is generated; no external delivery is attempted
| Endpoint / DB | Purpose |
|---|---|
PATCH /preferences/notifications | Set delivery channels (email, slack_webhook_url) |
Story 10.4 — Quiet Hours
- As a
- BU
- I want
- to set quiet hours during which external notification delivery is suppressed
- So that
- overnight runs do not send alerts while I am unavailable
Scenario: Quiet hours suppress external delivery
Giventhe user has configured quiet hours 22:00–08:00 in their locale timezone and a
run_failed event fires at 23:30
Whenthe notification system evaluates delivery
Thenthe in-app notification is still created immediately; email and Slack delivery are deferred until 08:00
| Endpoint / DB | Purpose |
|---|---|
PATCH /preferences/notifications | Includes quiet_hours: { start, end, timezone } |
Story 10.5 — Theme and Locale Preferences
- As a
- BU
- I want
- to set my preferred colour theme (light / dark / auto) and locale
- So that
- the interface matches my working environment and language
Scenario: User sets dark theme
Whenthe user selects Dark in preferences
Then
PATCH /preferences/display is issued with { "theme": "dark" }; document.documentElement receives data-theme="dark"; the preference persists across sessions
Scenario: Locale change updates date formatting and RTL layout
When
PATCH /preferences/display is issued with { "locale": "ar-AE" }
Thenall date/time values are reformatted using the ar-AE locale; text directionality follows RTL conventions (logical properties enforce the correct layout per the i18n NFR)
| Endpoint / DB | Purpose |
|---|---|
PATCH /preferences/display | Set theme, locale |
GET /preferences | Load persisted display preferences on app boot |