arch-atlas

Notifications Controller

controllers/notifications_controller.dart · Notifier<NotificationsState>

domain

Overview

Notifier that fetches both customer and seller notification streams in parallel, merges them by id, preserves prior read state, sorts newest-first, and exposes markAsRead / markAllAsRead / deleteNotification.

User Flow

  1. build() schedules Future.microtask(refresh) — initial fetch on first watch.
  2. refresh reads both tokens from AuthStorageService and fetches in parallel via Future.wait.
  3. Per-token fetches use a raw Dio (not DioHelper) so each call carries its own Authorization explicitly.
  4. De-dup by id with putIfAbsent → preserves read flags from previous state → newest-first sort.
  5. markAsRead writes optimistic state, then fires /social/fcm-notifications/toggle-read with the original authToken.

Cases & Edge Cases

  • If only one role is present, the other future is omitted — the list still works.
  • If a per-token fetch throws, the other is preserved — failures don't cascade.
  • Preserving read status from existing state across refresh is intentional — the server might not yet reflect a just-tapped 'read' state.
  • deleteNotification is local-only — no backend delete endpoint today, so swiping just hides until next refresh.
  • markAllAsRead fires one toggle-read POST per unread notification — could be batched but isn't yet.

Code References

  • lib/src/features/shared/notifications/controllers/notifications_controller.dart:42 // NotificationsController
  • lib/src/features/shared/notifications/controllers/notifications_controller.dart:51 // refresh (parallel both tokens)
  • lib/src/features/shared/notifications/controllers/notifications_controller.dart:114 // _fetchNotifications (raw Dio)
  • lib/src/features/shared/notifications/controllers/notifications_controller.dart:178 // _toggleReadApi

API Calls

  • GET/social/fcm-notifications?limit=50&offset=0no status

    Fetch a page of in-app notifications for a specific token (called per role when both customer + seller tokens exist).

    Request
    Query: limit, offset + header `Authorization: Bearer <authToken>`
    Response
    { notifications: [{ id, template, data: { title, description }, created_at, read }, ...], count, limit, offset }
    lib/src/features/shared/notifications/controllers/notifications_controller.dart:114 // _fetchNotifications (raw Dio)

    auth: bearer (per role). Fetched once per token, then merged client-side. Uses a raw Dio to bypass DioHelper's role-based path heuristic.

Notes

Using a raw Dio bypasses DioHelper's path heuristic — necessary because both /social paths would otherwise resolve to whichever role is 'active' and you'd miss the other token's notifications.