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.
States = idle / loading / success / empty / error(offline, rate, invalid) / disabled / permission.
Analytics events follow {module}.{screen}.{action} (proposed) — 00-shared/10 §8 .
Field Detail
Purpose Newest-first list of my persisted notifications w/ pagination
Entry shell bell icon, deep link /notifications, badge tap
Exit tap item → mark-read + optional route via data payload; back to shell
Data GET /api/v1/notifications?page=1&limit=20[&unreadOnly=true] → { data, meta } (notifications.controller.ts:21-29)
Composition AppBar ("Notifications" + Mark-all action), lazy list of NotificationListTile, pagination footer, empty state
Primary CTA Mark all read (PATCH /api/v1/notifications/read-all) — only when unread > 0
States idle, loading (first page skeleton), pagination loading (footer), empty (J5), error offline w/ retry, error 4xx/5xx
Analytics notifications.list.open, notifications.list.loaded, notifications.item.tap, notifications.mark_all
Adaptive phone single pane; tablet/desktop max-width ~640 dp centered list
a11y unread items announced as "unread", live-region on badge change
Motion list m-base fade-in; read swipe m-fast (see 00-shared/08 )
Field Detail
Purpose Persistent unread count on the app shell
Data GET /api/v1/notifications/unread-count → { count } (controller.ts:31-35)
States 0 (hidden), n ≤ 99 (numeric), > 99 ("99+"), error (hidden, silent)
Refresh on app foreground, on inbox mutations, after mark-read responses
a11y semantics label "N unread notifications"
Field Detail
Trigger meta.totalItems === 0, or unreadOnly=true with zero unread
Copy "No notifications" + contextual subline (unread filter → "You're all caught up")
CTA none (v1); (proposed) "Clear filter" when unreadOnly active
a11y no live-region spam; static illustration is decorative (00-shared/09 )
Field Detail
Purpose Read full body + act on data payload (deep-link target)
Entry tap item whose data carries a route hint; today no link field exists in the model (notification.schema.ts:28-29 — free-form data only)
Data no GET /:id endpoint — must pass the full item client-side (see 01 §6 )
Deep link data payload carries the source event fields (e.g. userId); a targetUrl/entityId convention is (proposed) for v2
Note The API gap makes this screen client-derived; mark route dormant until a targetUrl convention lands
Field Detail
Purpose Per-user channel prefs (email/push/in-app)
Data GET /api/v1/notifications/preferences, PATCH /api/v1/notifications/preferences (Notifications.md:27-28)
Status Not implemented — keep route dormant
Field Detail
Purpose Org admin pushes a notification to a target audience
Data POST /api/v1/notifications/send (internal/service) (Notifications.md:24)
Permissions requires notification.send — absent from ALL_PERMISSIONS (permissions.constants.ts) — (planned)
Status Not implemented — see 08_Form_Specifications
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).