Skip to content

IE.8: In-App Notification Delivery

Summary

In-app notifications are rendered from notification templates, stored as notification records, and pushed to connected clients over SSE. Users see them through the notification dropdown and Inbox notification tab, where they can mark notifications read, mark all read, or archive them.

Role

  • Primary: Client, Counselor, Admin
  • Secondary: System

Entry Point

  • Notification producer services: booking, meeting, assessment, messaging, and other system events
  • Realtime stream: /api/v1/realtime/stream
  • Frontend UI: notification dropdown, /inbox?tab=notifications
  • APIs: GET /notifications, GET /notifications/unread-count, POST /notifications/:id/read, POST /notifications/:id/archive, POST /notifications/read-all

Preconditions

  • Recipient has a user account.
  • Notification template exists for templated notifications, or caller provides simple content.
  • SSE service is initialized for realtime delivery.

Steps

  1. A backend service requests a templated or simple in-app notification.
  2. For templated notifications, backend resolves template key and language, with English fallback.
  3. Backend renders the notification body.
  4. Backend creates a notifications row with notification_type=in_app, category, recipient, sender, content, and delivered status.
  5. Backend publishes an SSE notification event to the recipient's user notification channel.
  6. Frontend realtime provider receives the notification event and adds it to the notification store.
  7. If browser notification permission is granted, frontend can show a browser notification.
  8. Notification dropdown and Inbox notification tab fetch unread/list state from the API.
  9. User selects a notification; the Inbox auto-marks it read after a short delay.
  10. User can mark a notification read, mark all read, or archive/delete a notification.

Diagram

Edge Cases

  • Template missing: Templated notification send returns/logs an error depending on the caller; domain actions usually continue.
  • SSE failure: Notification remains persisted even if realtime publish fails.
  • Reconnect gap: Frontend realtime provider fetches missed notifications after reconnect.
  • Ownership: Notification read/archive/get APIs verify recipient ownership.
  • HTML content: Inbox sanitizes notification HTML before rendering.
  • Message notifications: Message notification templates exist for message_received; realtime message events and notification events are handled separately by the frontend provider.

Current Implementation Notes

  • Backend: backend/internal/services/in_app_notification_service.go, backend/internal/services/notification_service.go, backend/internal/services/sse_service.go
  • Frontend: frontend/src/features/conversations/components/realtime-provider.tsx, frontend/src/shared/store/notification-store.ts, frontend/src/app/pages/inbox.tsx, frontend/src/shared/components/notifications/notification-dropdown.tsx
  • Templates: backend/scripts/seed_notification_templates.sql, backend/scripts/seeds/007_seed_message_notification_templates.sql

Screenshot Status

  • Not captured.