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

01 — Product Overview (Notifications Module)

Single notification engine across all channels. Scope for this design pass: the in-app notification inbox as implemented in src/modules/notifications/. Multi-channel dispatch (email, push, WhatsApp, WebSocket) is planned — see studylyon-blueprint/04-Modules/Notifications.md:11-17.


1. Product Statement

StudyLyon users (students, teachers, parents, staff, org admins) receive a persistent, per-tenant in-app notification inbox generated from system events (account lifecycle today; homework/attendance/exams in the event pipeline). Each notification is a small record: type, title, body, optional data payload, and a readAt flag (notification.schema.ts:15-32). The inbox supports list + pagination, single & bulk mark-read, and an unread-count badge.

2. Scope — In (v1, implemented)

AreaStatus
Persisted in-app notifications, tenant-scopedsrc/modules/notifications/
Event-driven creation (EventBus fan-in)notifications.handler.ts
List w/ pagination + unreadOnly filterGET /api/v1/notifications
Unread countGET /api/v1/notifications/unread-count
Mark one read / mark all readPATCH /api/v1/notifications/:id/read, PATCH /api/v1/notifications/read-all

3. Scope — Out (planned / forward-looking)

AreaWhere
Email / Push / WhatsApp / WebSocket dispatchNotifications.md:13; QUEUE.EMAILS / PUSH / WHATSAPP exist (queue.constants.ts:2-4) but no workers consume them for notifications
POST /api/v1/notifications/send (internal send)Notifications.md:24(planned)
Notification templates (i18n + interpolation)Notifications.md:7(planned)
Per-user channel preferencesNotifications.md:7,27-28(planned)
Push/FCM device tokensPOST /api/v1/notifications/device-token (future)docs/user-flows/END_TO_END_USER_FLOWS.md:788(forward-looking)
Push for coaching test reminders / DPP alerts / batch startdocs/IMPLEMENTATION_PLAN.md:769,859(forward-looking)
Analytics events {module}.{screen}.{action}(proposed) — SDK open, see 00-shared/10 §8

4. PRD Exclusion: Native Mobile App

Per docs/IMPLEMENTATION_PLAN.md:859 the mobile app is an open clarifying question, not a v1 deliverable. The PRD scopes the web app + API first; this design therefore covers the web/app-agnostic in-app inbox and keeps mobile push behind the (forward-looking) markers above. Any native-app-specific screen is out of scope.

5. How Notifications Are Created

  1. Any module emits a DomainEvent on the shared EventBus.
  2. NotificationsHandler subscribes via eventBus.onAny (notifications.handler.ts:61) and maps event → notification config (handler.ts:8-31, 33-50).
  3. Recipient resolves from payload.userId ?? payload.recipientId ?? actorId (handler.ts:76-79).
  4. Persist happens inside a synthetic tenant context (handler.ts:81-99).
  5. Client reads via the four authenticated endpoints.

Today only four event types produce notifications (see 03_User_Journey and 12_API_Mapping for the list).

6. Non-Goals (v1)

  • No read-receipt analytics or per-recipient delivery stats.
  • No notification detail endpoint (GET /:id) — detail is derived client-side from the list item + data payload.
  • No server-side push to external providers.
  • No admin-facing send UI (see 08_Form_Specifications).