Documentation Index
Fetch the complete documentation index at: https://grantmaster.dev/llms.txt
Use this file to discover all available pages before exploring further.
Core Workflows
| Status | Updated | Covered File |
|---|---|---|
| 🟢 Stable | 2026-04-14 | ServerGrantService.ts, ServerProjectService.ts, ServerComplianceService.ts, EventBus.ts |
1. Grant Lifecycle (End-to-End)
This is the primary business flow of the system, taking a funding opportunity from discovery to close-out.Steps & Technical Drivers
- Trigger: User finds a
GrantOpportunityand clicks “Add to Pipeline”. - Pipeline Stage Change:
GrantService.updatePipelineStageupdates the stage, history, and recalculates weighted probability. - Conversion: When a grant is “Won”,
ServerActiveGrantServiceClass.convert()(infunctions/src/api/services/ServerGrantService.ts) runs a composite transaction that:- Creates an
ActiveGrantdocument with award details. - Moves the pipeline entry to the
wonstage. - Looks up the pipeline entry to derive the grant title.
- Auto-creates a linked
Projectdocument viaserverProjectService.create()withgrantId,managerId,startDate/endDate, andbudgetderived from the award. - Back-links the new
projectIdonto theActiveGrant. - Auto-provisions draft compliance policies from the opportunity’s
complianceRequirementsandgrantorTypeviaserverCompliancePolicyService.create()— scoped to the new project, withstatus: 'draft'andadoptionSource: 'grant_conversion'. Failures are non-fatal (Promise.allSettled). - Emits
GRANT_WONwith{ grantId, pipelineId, projectId }so downstream features (compliance, reports, notifications) receive the project link.
- Creates an
- Client cache:
useGrants.convertToActiveGrantinvalidatesutils.projects.listandutils.projects.statsin itsonSuccesshandler so the new project appears in the UI immediately. - Auditing: Every transition is logged via
BaseService.logSuccessand emits an event to theEventBus.
docs/overview/decision-log.md for the decision record.
2. Effort Tracking & Journals
Ensures personnel costs are accurately recorded and validated for grant compliance.- Trigger: User records time on a specific project.
- Validation: Service layer checks if the hours are within reasonable bounds and if the project is active.
- Integration: Journals are stored in the
journalscollection. - Reporting: Monthly rollups are generated for donor-specific reporting packs.
3. Notification Flow (Event → Novu → FCM)
Decoupled orchestration of user alerts.Sequence:
- Event Emission: A service emits an event via
EventBus.emit.- Example:
EXPENSE_APPROVED.
- Example:
- Listener:
src/shared/notifications/portalEventService.ts(or similar) listens for the event. - Novu Trigger: The listener calls the Novu API with the event payload and subscriber ID.
- Delivery: Novu sends a Push notification (via FCM), Email, or In-App alert based on the user’s preferences.
4. User Onboarding & RBAC
- Invitation: Admin creates an
invitationfor a specific email and role. - Email: Novu sends the invitation link.
- Acceptance: New user signs in via Firebase Auth; the system links their
uidto the existingemployeerecord. - Tenancy Binding: The user’s JWT is updated with
organizationIdclaims (handled via Cloud Functions).
5. Report Generation (Grant-Contextual AI Narrative)
The reporting flow closes the MVP loop by generating donor-ready narratives backed by real operational data.Sequence:
- Select type & project: User picks a report type and target project via
ReportSelectionView→ReportConfigureView. - Compose financial context: The Reports container (
src/features/reports/components/Reports.tsx) readsexpensesandjournalEntriesfromuseExpenses()anduseJournals(), then computes aReportFinancialContextviauseMemo:totalExpenses,expensesByCategory,currencybudgetUtilization(derived from project budget)totalJournalHours,journalHoursByProject
- Generate narrative:
useReportGeneration({ projects, user, financialContext })callsgenerateReportNarrative()ingeminiForecast.ts. The financial context is formatted into the Gemini system prompt so the AI cites specific figures. - Dev fallback: If no Gemini API key is present (
import.meta.env.DEV && !hasUsableGeminiApiKey()),buildDevReportNarrative()produces a deterministic narrative that includes the financial overview when the context is populated. - Persist & export: On confirmation,
generateReport()stores theGeneratedReportin Firestore. Export usesuseReportExport(PDF/Word/Excel). - Events:
GRANT_REPORT_SUBMITTEDemits when the report is linked to an active grant.
docs/overview/decision-log.md.
Maintenance
Update this document when:- Adding a new stage to the
PipelineStagetype. - Implementing a new background automation (e.g., AI-driven data extraction).
- Changing the notification delivery provider.
Update Checklist
- Trace the flow from UI click to Firestore write.
- Identify all intermediate events emitted.
- Identify all downstream side effects (Audit logs, Notifications, Integrations).