Documentation Index
Fetch the complete documentation index at: https://grantmaster.dev/llms.txt
Use this file to discover all available pages before exploring further.
Engineering reference: For service contracts, EventBus events, and data-layer details see src/features/notifications/notifications.md.
last_updated: 2026-03-14
Notifications System
Overview
GrantMaster uses a custom push notification system built on Firebase Cloud Messaging (FCM). This replaced the previous Novu integration. Notifications are delivered via push (browser/PWA), in-app toast, and email digest.
Architecture
| Component | Path | Purpose |
|---|
PushNotificationManager | notifications/components/PushNotificationManager.tsx | FCM token registration, permission handling, browser detection |
NotificationPreferencesPanel | notifications/components/NotificationPreferencesPanel.tsx | Per-user preference UI with 14 categories across 6 groups |
NotificationPermissionPrompt | notifications/components/NotificationPermissionPrompt.tsx | Progressive permission request component |
NotificationHistory | notifications/components/NotificationHistory.tsx | Historical notifications list with read state |
SystemNotificationComposer | notifications/components/SystemNotificationComposer.tsx | Admin tool: compose and broadcast system-wide notifications |
InlineActions | notifications/components/InlineActions.tsx | Renders actionable buttons inside notification cards |
NotificationAnalyticsDashboard | notifications/components/pages/NotificationAnalyticsDashboard.tsx | Delivery metrics, open rates, channel breakdown |
Notification Categories (14)
Categories are defined in NotificationPreferencesPanel.tsx and organized into 6 groups:
| Group | Key | Label | Description |
|---|
| Time Tracking | journalReminders | Journal Reminders | Reminders to submit your journals |
| journalApprovals | Journal Approvals | When your journals are approved |
| journalRejections | Journal Rejections | When your journals are rejected |
| Expenses | expenseApprovals | Expense Approvals | When expenses are approved |
| expenseRejections | Expense Rejections | When expenses are rejected |
| expenseFlags | Expense Flags | When expenses are flagged for audit |
| Projects | projectUpdates | Project Updates | Changes to projects you work on |
| projectAssignments | Project Assignments | When you are assigned to a project |
| Budget | budgetAlerts | Budget Alerts | Critical budget threshold warnings |
| budgetWarnings | Budget Warnings | Budget approaching limits |
| Deadlines | deadlineReminders | Deadline Reminders | Upcoming deadline notifications |
| deadlineOverdue | Overdue Deadlines | When deadlines have passed |
| System | systemUpdates | System Updates | Platform updates and changes |
| securityAlerts | Security Alerts | Security-related notifications |
Each category supports independent per-channel configuration (push and email).
Delivery Channels
| Channel | Mechanism | When Used |
|---|
| Push | FCM browser/PWA | Real-time alerts requiring immediate attention |
| Email | Postmark | Digests, formal notifications, offline users |
| In-app | Toast + Notification History | Non-urgent status updates |
User Preferences
Preferences are stored per user per organization via getNotificationPreferences(uid, orgId) and updateNotificationPreferences(uid, orgId, prefs) from @/features/users/services/userPreferences.
Frequency Options
- Immediate — delivered as they occur
- Daily digest — batched and sent at 8:00 AM
- Weekly digest — batched and sent Monday at 8:00 AM
Quiet Hours
Users can configure a quiet period during which push notifications are suppressed:
- Configurable start and end time
- Enable/disable toggle
- Does not affect email delivery
FCM Token Management
PushNotificationManager handles the full FCM lifecycle via PushNotificationService (@/shared/notifications/pushNotificationService):
| Method | Purpose |
|---|
isSupported() | Check browser push notification support |
getPermissionStatus() | Current permission state (granted / denied / default) |
getRegistrationToken(userId) | Request permission and register FCM token |
hasActiveToken(userId) | Check if user has an active device token |
refreshToken(userId) | Refresh an existing FCM token |
deleteRegistrationToken(userId) | Remove token (disable push) |
sendTestNotification() | Send a test push to verify setup |
Service worker at public/firebase-messaging-sw.js. FCM tokens are stored per device in employees/{uid}/devices/{deviceId} subcollection and refreshed on login.
Admin Features
- SystemNotificationComposer — allows admins to compose and broadcast system-wide notifications to all users or specific roles
- NotificationAnalyticsDashboard — provides delivery metrics, open rates, and channel breakdown analytics for monitoring notification effectiveness
Migration from Novu
The previous Novu integration (@novu/react, @novu/js) was fully removed and replaced by:
PushNotificationManager + FCM for push delivery
- Postmark for email delivery
- Custom
NotificationPreferencesPanel for user preferences
- Custom
NotificationHistory for in-app notification list