Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

05 — Screen Inventory (Notifications Module)

Every screen of the Notifications module, its intent, route, composition, states, permissions, platform behavior and events. Authoritative components in 00-shared/03; this file enumerates which ones each screen uses with module specifics.


Legend

States = idle / loading / success / empty / error(offline, rate, invalid) / disabled / permission. Analytics events follow {module}.{screen}.{action} (proposed)00-shared/10 §8.


1. Notification Inbox Screen (/notifications)

FieldDetail
PurposeNewest-first list of my persisted notifications w/ pagination
Entryshell bell icon, deep link /notifications, badge tap
Exittap item → mark-read + optional route via data payload; back to shell
DataGET /api/v1/notifications?page=1&limit=20[&unreadOnly=true]{ data, meta } (notifications.controller.ts:21-29)
CompositionAppBar ("Notifications" + Mark-all action), lazy list of NotificationListTile, pagination footer, empty state
Primary CTAMark all read (PATCH /api/v1/notifications/read-all) — only when unread > 0
Statesidle, loading (first page skeleton), pagination loading (footer), empty (J5), error offline w/ retry, error 4xx/5xx
Analyticsnotifications.list.open, notifications.list.loaded, notifications.item.tap, notifications.mark_all
Adaptivephone single pane; tablet/desktop max-width ~640 dp centered list
a11yunread items announced as "unread", live-region on badge change
Motionlist m-base fade-in; read swipe m-fast (see 00-shared/08)

2. Unread Badge (Shell Widget — not a screen)

FieldDetail
PurposePersistent unread count on the app shell
DataGET /api/v1/notifications/unread-count{ count } (controller.ts:31-35)
States0 (hidden), n ≤ 99 (numeric), > 99 ("99+"), error (hidden, silent)
Refreshon app foreground, on inbox mutations, after mark-read responses
a11ysemantics label "N unread notifications"

3. Empty State (state of §1, not a separate route)

FieldDetail
Triggermeta.totalItems === 0, or unreadOnly=true with zero unread
Copy"No notifications" + contextual subline (unread filter → "You're all caught up")
CTAnone (v1); (proposed) "Clear filter" when unreadOnly active
a11yno live-region spam; static illustration is decorative (00-shared/09)

4. Notification Detail (/notifications/:id) (planned)

FieldDetail
PurposeRead full body + act on data payload (deep-link target)
Entrytap item whose data carries a route hint; today no link field exists in the model (notification.schema.ts:28-29 — free-form data only)
Datano GET /:id endpoint — must pass the full item client-side (see 01 §6)
Deep linkdata payload carries the source event fields (e.g. userId); a targetUrl/entityId convention is (proposed) for v2
NoteThe API gap makes this screen client-derived; mark route dormant until a targetUrl convention lands

5. Notification Preferences (planned)

FieldDetail
PurposePer-user channel prefs (email/push/in-app)
DataGET /api/v1/notifications/preferences, PATCH /api/v1/notifications/preferences (Notifications.md:27-28)
StatusNot implemented — keep route dormant

6. Admin Manual Send (planned)

FieldDetail
PurposeOrg admin pushes a notification to a target audience
DataPOST /api/v1/notifications/send (internal/service) (Notifications.md:24)
Permissionsrequires notification.send — absent from ALL_PERMISSIONS (permissions.constants.ts) — (planned)
StatusNot implemented — see 08_Form_Specifications

Permission Map

All five implemented surfaces are user-scoped reads/writes of own data; notification.read + notification.update (permissions.constants.ts:32-33) are declared, and every controller endpoint is @UseGuards(JwtAuthGuard) (notifications.controller.ts:16).