🎬 Simulate:
UC-NOT.04 harness · 3 scenarios
Delivery Transport Log
Filter
Delivery list
6 records · sorted by Queued at ↓ · click row to preview payload
| Channel | Delivery status | Event type | Recipient | Queued at | Sent at | Delivered at | Retries | Error code | Provider message ID | Payload preview |
|---|---|---|---|---|---|---|---|---|---|---|
| Delivered | Renewal Reminder | Somchai Jaidee s***@example.com |
2026-06-01 08:15:01 +07 | 2026-06-01 08:15:02 +07 | 2026-06-01 08:15:05 +07 | 0 | — | sg-a1b2c3 | ||
| Push | Delivered | Renewal Reminder | Somchai Jaidee s***@example.com |
2026-06-01 08:15:01 +07 | 2026-06-01 08:15:03 +07 | 2026-06-01 08:15:06 +07 | 0 | — | fcm-9x8y7z | |
| Delivered | Course Announcement | Suda Kaewmanee s***@gmail.com |
2026-05-30 09:00:01 +07 | 2026-05-30 09:00:02 +07 | 2026-05-30 09:00:08 +07 | 0 | — | sg-d4e5f6 | ||
| In-App | Delivered | Deadline Reminder | Wichai Maneeratana w***@school.la |
2026-05-28 14:30:00 +07 | 2026-05-28 14:30:01 +07 | 2026-05-28 14:30:01 +07 | 0 | — | inapp-77aa | {"message":"Assignment due in 24h"} |
| Failed | Payment Receipt | Malee Thongdee m***@college.la |
2026-05-26 16:45:30 +07 | 2026-05-26 16:45:31 +07 | — | 3 | 550 Mailbox full | sg-g7h8i9 | Payload no longer available (90-day retention policy) | |
| SMS | Delivered | OTP Verification | Nattaporn Srisuk +66-8x-xxx-x789 |
2026-05-27 11:02:10 +07 | 2026-05-27 11:02:11 +07 | 2026-05-27 11:02:15 +07 | 0 | — | dtac-001122 | (OTP masked — not stored in payload) |
Showing 1–6 of 6 records
25 per page
Screen Flow (from flow.puml):
📝 Spec notes — UC-NOT.04 / SCR-NOT.07 (fields, actions, requirements)
Identity
- Screen: SCR-NOT.07 — Delivery Transport Log
- Use case: UC-NOT.04 — View Delivery Transport Logs
- Primary actor: Super Admin
Brief description
Super Admin page for viewing the full transport-level delivery log — one row per channel per notification event. Two entry points: (1) Admin menu — full log, default date-range filter; (2) "Transport log →" from SCR-NOT.01 — pre-filtered to selected event with context label and back-navigation. Clicking any row opens Payload preview panel. Read-only — no edit, delete, or resend.
Fields — Filter panel
channel"Channel" — enum (all / email / sms / push / in_app) · default: alldelivery_status"Delivery status" — enum (all / pending / retrying / delivered / failed / failed_dlq) · default: allevent_type"Event type" — enum (all / otp / course_announcement / course_approval / course_rejection / deadline_reminder / live_class_start / forum_reply / payment_receipt / renewal_reminder / certificate_issued / security_alert) · default: allrecipient_search"Recipient (name / email / mobile partial)" — text · max 100 chars · default: ""date_from"Queued date from" — datetime · default: now − 7 days · ref:NotificationDelivery.queued_atdate_to"Queued date to" — datetime · default: now · ref:NotificationDelivery.queued_atcontext_event_label"Filtered event" — text · read-only · visible whenentry_source == event_log· computed: event_type + " — " + masked(recipient_contact) + " — " + created_at (+07) · ref:NotificationEvent.id
Fields — Delivery list (columns, all read-only)
row_channel"Channel" — enum ·NotificationDelivery.channelrow_delivery_status"Delivery status" — enum ·NotificationDelivery.statusrow_event_type"Event type" — text ·NotificationEvent.event_typerow_recipient"Recipient" — computed: full_name + " / " + masked(email or mobile) · always partially maskedrow_queued_at"Queued at" — datetime UTC → +07 ·NotificationDelivery.queued_atrow_sent_at"Sent at" — datetime · null → "—" ·NotificationDelivery.sent_atrow_delivered_at"Delivered at" — datetime · null → "—" ·NotificationDelivery.delivered_atrow_retry_count"Retries" — number ·NotificationDelivery.retry_countrow_error_code"Error code" — text · null → "—" ·NotificationDelivery.error_coderow_provider_message_id"Provider message ID" — text · null → "—" ·NotificationDelivery.provider_message_idrow_payload_preview"Payload preview" — text · truncated in column; full in panel · if expired → "Payload no longer available (90-day retention policy)" [SS-NOT.02]
Fields — Payload preview panel (visible when selected_row != null)
preview_row_context"Selected row" — computed: channel · event_type · masked(recipient_contact) · queued_at (+07) · read-onlypreview_payload_content"Full payload" —NotificationDelivery.payload_preview· fallback: "Payload no longer available (90-day retention policy)" · read-only
Actions
apply_filter"Search" — always enabled · triggers UC-NOT.04-M-3clear_filter"Clear filter" — enabled when any filter changed from default · triggers UC-NOT.04-M-1back_to_event_log"← Event Log" — visible whenentry_source == event_log· navigates to UC-NOT.01page_prev"← Previous" — enabled when current_page > 1page_next"Next →" — enabled when has_next_pageselect_row(Row click) — always enabled · opens Payload preview paneldismiss_preview"Close" — enabled when selected_row != null · dismisses Payload preview panel
Additional requirements
- The transport log is read-only — Admins cannot edit, delete, or trigger resend of any record.
- Recipient contact (email, mobile) always partially masked. No unmask function.
- Super Admin sees all institutions. No institution scope filter.
- All timestamps stored in UTC; displayed as "YYYY-MM-DD HH:mm:ss +07". Null → "—". Tooltip: UTC + relative time.
row_payload_preview: if nulled after 90-day retention → "Payload no longer available (90-day retention policy)" — not "—". [SS-NOT.02]- Empty state: icon + "No delivery records found — try adjusting the filter or expanding the date range." + [Clear filter].
- WCAG-AA: label-input pairing; status + channel columns use color and icon; row striping contrast ≥ 4.5:1. [NFR-09]
- Min width 1024px; below → horizontal scroll. Mobile not supported. [NFR-08]
- Clicking a row opens Payload preview panel below the list. Clicking same row again or "Close" dismisses it. Different row replaces panel content.
- Payload preview panel: if payload expired, shows "Payload no longer available (90-day retention policy)". [SS-NOT.02]