Skip to main content

Documentation Index

Fetch the complete documentation index at: https://grantmaster.dev/llms.txt

Use this file to discover all available pages before exploring further.

shared/notifications

Notification delivery infrastructure. All features that need to send in-app or push notifications call into this module — never directly to Firestore.

Module Map

FileRole
notificationDispatch.tsPrimary entry pointsendNotification(payload, recipientRole)
notificationCrud.tsLow-level Firestore CRUD wrappers (get, markRead, delete, snooze)
notificationRepository.tsFirestore query layer for the notifications collection
notificationAudienceResolver.tsResolves recipients by SystemRole from the employees collection
notificationOrchestrator.tsChains audience resolution → message building → delivery
notificationMessageBuilders.tsPer-type message formatters (subject, body, action URL)
notificationDeliveryPlanner.tsPlans delivery channels (in-app, push, email) based on user preferences
deadlineReminderComposer.tsComposes deadline-specific reminder notifications
journalNotifications.tsJournal submission and approval notification builders
fcmService.tsFirebase Cloud Messaging (push notification) delivery
notificationAnalyticsService.tsDelivery and open-rate analytics
templateInterpolation.ts{{placeholder}} substitution in notification templates
portalNotificationBuilders.tsNotification builders for portal stakeholder events

Primary API

// Send a notification to a specific user
await sendNotification(
  {
    organizationId: 'org123',
    recipientId: 'user456',
    type: NotificationType.EXPENSE_SUBMITTED,
    title: 'Expense awaiting approval',
    message: 'Alice submitted a €250 expense for Project A.',
    actionUrl: '/admin/approvals',
    isRead: false,
    severity: 'warning',
    requiresAction: true,
    actionType: 'approve',
    data: { sourceId: 'exp789', sourceType: 'expense' },
  },
  SystemRole.MANAGER,    // recipient's role (for channel planning)
);

// CRUD wrappers
const notifications = await getNotifications(orgId, recipientId, limit);
const unread = await getUnreadCount(orgId, recipientId);
await markAsRead(notificationId);
await markAllAsRead(orgId, recipientId);
await deleteNotification(notificationId);
await snoozeNotification(notificationId, until: Date);

Audience Resolution

notificationAudienceResolver.ts can resolve recipients by role across an organization:
// Get all active managers in an org
const managers = await getOrganizationRecipientsBySystemRole(orgId, [SystemRole.MANAGER]);

// Filter an existing user array by role (no Firestore call)
const admins = filterOrganizationRecipientsBySystemRole(users, [SystemRole.ADMIN]);
Inactive users (status !== 'active') are excluded from all audience resolution.

Firestore Collection

notifications/{notificationId} — Notification documents. Queried by (organizationId, recipientId).

Callers

Every feature that produces actionable notifications calls sendNotification():
  • features/expenses — submission, approval, rejection
  • features/journals — submission, approval, rejection
  • features/admin — assignment notifications
  • features/users — time-off decisions, invitations
  • features/compliance — alert notifications
  • features/grants — outcome notifications