Documentation Index
Fetch the complete documentation index at: https://grantmaster.dev/llms.txt
Use this file to discover all available pages before exploring further.
External Integrations
GrantMaster sits at the center of a specialized NGO ecosystem. This document details the 3rd-party services we integrate with and the technical mechanics of those connections.1. Notifications (Internal Orchestration)
- Purpose: Multi-channel notifications (In-App + Email + Push) without a third-party orchestration provider.
- Workflow:
EventBusemits a system event (e.g.JOURNAL_SUBMITTED).- A notification handler constructs a
NotificationRequest. notificationOrchestrator.tsevaluates per-user preferences + quiet hours and dispatches:- In-app: Firestore
notificationsdocuments - Email: Postmark
- Push: FCM
- In-app: Firestore
- Files:
src/shared/notifications/notificationOrchestrator.tssrc/shared/notifications/notificationService.tsfunctions/src/notificationEmailTrigger.ts
2. HubSpot (CRM Synchronization)
- Purpose: Syncing partner (Grantor) correspondence and relationship status.
- Direction: Bi-directional.
- Outbound: GrantMaster logs interaction notes to HubSpot contact timelines.
- Inbound: Pulling foundation data and key contacts into the Registry.
- Auth: OAuth 2.0 (Handled in Cloud Functions).
- Files:
src/features/relations/services/HubSpotSyncService.ts.
3. KoboToolbox / ODK (Field Data Collection)
- Purpose: Importing M&E (Monitoring & Evaluation) data from mobile field servers.
- Workflow:
- Field staff upload surveys to Kobo.
- A webhook from Kobo hits our
onKoboSubmissionCloud Function. - Data is parsed and mapped to
ImpactMetricrecords in Firestore.
- Files:
functions/src/integrations/kobo.ts.
4. Stripe (Billing & Payments)
- Purpose: Subscription management, payment processing, and credit-based AI billing for SaaS tenants.
- Model: Per-user pricing with tiers based on “Active Grant” volume. AI features use a credit system.
- Webhook:
stripeWebhookCloud Function processescustomer.subscription.*,invoice.*, andcheckout.session.completedevents. - State Machine: Subscription lifecycle enforced via
functions/src/stripe/stateMachine.ts— validates transitions (e.g.,trialing→active→past_due→canceled). Seedocs/product/domain/state-machines.md. - Secrets:
STRIPE_SECRET_KEY,STRIPE_WEBHOOK_SECRET(Firebase Secrets). - Files:
src/features/billing/,functions/src/stripe/.
5. Postmark (Transactional Email)
- Purpose: Sending transactional emails — billing receipts, invitation links, scheduled reminders, and feedback requests.
- Client:
postmarknpm package (ServerClient). Initialized lazily in Cloud Functions. - Template-based: Uses Postmark email templates via
sendEmailWithTemplate()for consistent branding. - Secrets:
POSTMARK_SERVER_TOKEN(Firebase Secrets). - Files:
functions/src/email/billingEmails.ts,functions/src/email/invitationEmails.ts,functions/src/postmarkAdmin.ts,functions/src/notificationEmailTrigger.ts.
6. Typesense (Full-Text Search)
- Purpose: Tenant-isolated full-text search across projects, users, expenses, journals, documents, contacts, and compliance rules.
- Architecture: Backend syncs Firestore data to Typesense collections; frontend queries via
typesenseSearchService.ts. - Collections:
gm_projects,gm_users,gm_expenses,gm_journals,gm_documents,gm_contacts,gm_compliance_rules. - Tenant isolation: All queries include mandatory
organizationIdfilter. Results are post-filtered by RBAC permissions. - Files:
src/shared/platform/typesenseSearchService.ts,src/shared/platform/searchService.ts.
7. Sentry (Error Monitoring & Performance)
- Purpose: Error tracking, performance monitoring, and session replay.
- Integration:
@sentry/reactwith React error boundaries (SentryErrorBoundary), logger integration, and performance tracing. - Files:
src/lib/logger.ts,src/lib/performanceMonitoring.ts,src/errors/AppError.ts,src/components/SentryErrorBoundary.tsx. - Secrets:
VITE_SENTRY_DSN(environment variable).
8. Google Gemini / Genkit (AI)
- Purpose: AI-powered features including journal generation, compliance auditing, forecasting, receipt OCR, grant proposal writing, and Impact (M&E) analytics.
- Dual mode: Defaults to Cloud Functions (Genkit-powered with tracing) but can fall back to direct client-side Gemini SDK calls.
- Usage tracking: All AI generations are tracked per organization for credit-based billing via
trackAiGeneration(). - Client:
@google/genaiSDK. Backend uses Genkit framework. - Secrets:
VITE_GEMINI_API_KEY(env var),GOOGLE_AI_API_KEY(Firebase Secrets for Functions). - Files:
src/features/ai/services/geminiService.ts,src/features/ai/services/ragService.ts,src/features/ai/services/visionService.ts.
9. MCP Server (AI Client Integration)
- Purpose: Model Context Protocol server that exposes GrantMaster data to external AI clients (Claude Desktop, Claude Code, and other MCP-compatible tools).
- Transport: HTTP with Bearer token authentication via API keys generated in the Integrations UI.
- Capabilities: 35+ tools and 5 resources covering projects, grants, expenses, compliance, documents, and agent execution.
- Tenant isolation: All requests are scoped to the authenticated user’s organization and respect RBAC permissions.
- Endpoint:
https://<region>-<project-id>.cloudfunctions.net/api/mcp - Files:
functions/src/api/mcp/,src/features/integrations/components/MCPView.tsx.
Technical Patterns for Integrations
Webhook Reliability
We use a DLQ (Dead Letter Queue) pattern for incoming webhooks.- Verify signature.
- Store raw payload in
webhookLogscollection immediately. - Process asynchronously via Cloud Function background trigger.
- If processing fails, mark document status as
failedfor manual retry.
API Rate Limiting
Managed viasrc/core/rateLimiter.ts to avoid hitting HubSpot or Postmark limits during bulk operations.
Maintenance
Update this document when:- Adding a new external provider.
- Changing a webhook endpoint URL.
- Modifying the sync frequency for background jobs.