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/integrations — API Reference
The shared/integrations module provides data-access and service layers for third-party integrations: HubSpot CRM sync, Xero accounting, generic integration export records, API key management, and webhook configuration. It also includes the thin referralDataAccess.ts helper for referral record persistence.
Module Map
| File | Responsibility |
|---|
integrationService.ts | CRUD for integration exports, API keys, and webhook config (all org-scoped) |
hubspot/ | HubSpot OAuth, API client, contact/deal sync, field mapping |
xero/ | Xero OAuth and accounting data sync |
auditLogDataAccess.ts | Low-level Firestore read/write for audit log entries (used by shared/audit) |
referralDataAccess.ts | Single-operation Firestore write for Referral documents |
integrationService
Generic data-access layer for integration records, API keys, and webhooks. All operations are scoped to organizationId via Firestore subcollections.
Integration Exports
import {
fetchIntegrationExports,
createIntegrationExport,
deleteIntegrationExport,
} from '@/shared/integrations/integrationService';
// Read all exports configured for an org
const exports = await fetchIntegrationExports(orgId);
// Persist a new integration export record
await createIntegrationExport(orgId, record);
// Remove
await deleteIntegrationExport(orgId, exportId);
Firestore path: organizations/{orgId}/integration_exports/{exportId}
API Keys
import {
fetchApiKeys,
createApiKey, // raw record write — use apiKeyService for full lifecycle
updateApiKey,
deleteApiKey,
} from '@/shared/integrations/integrationService';
Firestore path: organizations/{orgId}/api_keys/{keyId}
For API key generation with scope validation and rate-limit config, use shared/auth/apiKeyService instead — it provides the full lifecycle API including secret hashing.
Webhooks
import {
fetchWebhooks,
createWebhook,
updateWebhook,
deleteWebhook,
logWebhookEvent,
fetchWebhookLogs,
} from '@/shared/integrations/integrationService';
// Configure a new outbound webhook
await createWebhook(orgId, {
url: 'https://example.com/webhook',
events: ['expense.approved', 'grant.awarded'],
secret: generateWebhookSecret(),
});
// Log a delivery attempt
await logWebhookEvent(orgId, webhookId, { status: 'delivered', statusCode: 200 });
Firestore paths:
organizations/{orgId}/webhooks/{webhookId}
organizations/{orgId}/webhook_logs/{logId}
HubSpot Integration (hubspot/)
| File | Responsibility |
|---|
HubSpotAuthService.ts | OAuth 2.0 authorisation code flow, token storage/refresh |
HubSpotDevOAuth.ts | Dev-mode OAuth bypass for local emulator testing |
HubSpotApiClient.ts | Authenticated HTTP client wrapping the HubSpot v3 REST API |
HubSpotSyncService.ts | Bidirectional contact and deal sync; conflict resolution |
HubSpotMappingService.ts | Field mapping between GrantMaster and HubSpot schemas |
Auth Flow
import { HubSpotAuthService } from '@/shared/integrations/hubspot';
// Step 1 — generate OAuth URL and redirect user
const authUrl = HubSpotAuthService.getAuthorizationUrl(orgId, redirectUri);
// Step 2 — exchange code for tokens (called from callback route)
const tokens = await HubSpotAuthService.exchangeCodeForTokens(code, redirectUri);
await HubSpotAuthService.storeTokens(orgId, tokens);
// Step 3 — use in sync operations (tokens refreshed automatically)
const client = await HubSpotApiClient.create(orgId);
Sync
import { HubSpotSyncService } from '@/shared/integrations/hubspot';
// Sync GrantMaster contacts → HubSpot contacts
await HubSpotSyncService.syncContactsToHubSpot(orgId);
// Pull HubSpot deal stages → GrantMaster grant pipeline
await HubSpotSyncService.syncDealsFromHubSpot(orgId);
// Full bidirectional sync
await HubSpotSyncService.runFullSync(orgId);
Field Mapping
HubSpotMappingService translates between GrantMaster’s Contact type and HubSpot’s contact/company objects. Custom field mappings per org are stored in organizations/{orgId}/hubspotConfigs/{configId}.
Xero Integration (xero/)
| File | Responsibility |
|---|
XeroAuthService.ts | OAuth 2.0 authorisation, token storage/refresh |
index.ts | Barrel export of Xero sync operations |
Auth Flow
import { XeroAuthService } from '@/shared/integrations/xero';
const authUrl = XeroAuthService.getAuthorizationUrl(orgId);
const tokens = await XeroAuthService.exchangeCodeForTokens(code);
await XeroAuthService.storeTokens(orgId, tokens);
The Xero integration is used by src/features/expenses/ to push approved expense records to Xero as bank transactions, and by src/features/reports/ to pull account balances for financial reporting.
auditLogDataAccess
Low-level Firestore primitives for audit log documents. Called by shared/audit — do not use directly in feature code.
import { writeAuditLog, queryAuditLogs } from '@/shared/integrations/auditLogDataAccess';
// Write a raw AuditLog document
await writeAuditLog(auditLogEntry);
// Query with filters
const logs = await queryAuditLogs({
organizationId,
userId?,
action?,
resourceType?,
from?, to?,
limit?,
});
Firestore collection: auditLogs/{logId}
referralDataAccess
A single thin wrapper for persisting a Referral document. Called by ReferralCreditService in shared/partnerships after a successful referral conversion.
import { createReferral } from '@/shared/referrals/referralDataAccess';
await createReferral(referral); // writes to referrals/{referral.id}
Firestore collection: referrals/{referralId}
EventBus Events
This module emits no EventBus events directly. HubSpot and Xero sync completions are surfaced via Postmark emails and in-app notifications dispatched from shared/notifications.
Gap: There are no HUBSPOT_SYNC_COMPLETED, XERO_SYNC_FAILED, or WEBHOOK_DELIVERY_FAILED EventBus events. If downstream features need to react to integration state changes, emissions should be added to HubSpotSyncService.runFullSync() and the webhook delivery logger.
Callers
| Caller | Uses |
|---|
src/features/integrations/ | Full surface — UI for all integration configuration |
src/features/expenses/ | Xero push after expense approval |
src/features/reports/ | Xero balance pull for financial reports |
src/features/relations/ | HubSpot contact sync |
src/shared/audit/ | auditLogDataAccess — all audit log writes |
src/shared/partnerships/ | referralDataAccess.createReferral() |