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/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

FileResponsibility
integrationService.tsCRUD 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.tsLow-level Firestore read/write for audit log entries (used by shared/audit)
referralDataAccess.tsSingle-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/)

FileResponsibility
HubSpotAuthService.tsOAuth 2.0 authorisation code flow, token storage/refresh
HubSpotDevOAuth.tsDev-mode OAuth bypass for local emulator testing
HubSpotApiClient.tsAuthenticated HTTP client wrapping the HubSpot v3 REST API
HubSpotSyncService.tsBidirectional contact and deal sync; conflict resolution
HubSpotMappingService.tsField 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/)

FileResponsibility
XeroAuthService.tsOAuth 2.0 authorisation, token storage/refresh
index.tsBarrel 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

CallerUses
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()