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/intelligence — API Reference
The shared/intelligence module provides opt-in access to cross-organisation intelligence data — sector benchmarks, funder profiles, AI predictions, and sector trends — aggregated at the platform level. A GDPR-compliant consent layer gates all reads: an organisation must explicitly opt in before any intelligence data is accessible.
Module Map
| File | Responsibility |
|---|
intelligenceService.ts | Read-only access to benchmarks, funder profiles, and trends; org-level caching |
consentService.ts | Consent record CRUD; GDPR-compliant opt-in/withdrawal/deletion |
All writes to the platform-level intelligence collections are handled by Cloud Functions (aggregation jobs), not by these services.
ConsentService
Manages IntelligenceConsent records stored at platform/intelligence/consent/{organizationId}.
Export
import { consentService } from '@/shared/intelligence';
// or
import { consentService } from '@/shared/intelligence/consentService';
Data Categories
type IntelligenceDataCategory =
| 'grants'
| 'finance'
| 'compliance'
| 'users'
| 'projects';
The default full-consent grant includes all five categories.
Key Methods
// Read consent status
consentService.getConsentStatus(organizationId): Promise<IntelligenceConsent | null>
// Grant consent (GDPR Article 7 — explicit opt-in)
consentService.grantConsent(
organizationId,
userId,
categories?: IntelligenceDataCategory[] // defaults to all 5
): Promise<ServiceResult<IntelligenceConsent>>
// Withdraw consent
consentService.withdrawConsent(organizationId, userId): Promise<ServiceResult<void>>
// Delete all platform-held data (GDPR Article 17 — right to erasure)
consentService.requestDataDeletion(organizationId, userId): Promise<ServiceResult<void>>
// Update data categories without full withdrawal
consentService.updateConsentCategories(
organizationId,
userId,
categories: IntelligenceDataCategory[]
): Promise<ServiceResult<IntelligenceConsent>>
IntelligenceConsent Schema
interface IntelligenceConsent {
organizationId: string;
isActive: boolean;
grantedAt: string; // ISO 8601
grantedBy: string; // userId
withdrawnAt?: string;
withdrawnBy?: string;
dataCategories: IntelligenceDataCategory[];
deletionRequestedAt?: string;
version: string; // consent policy version
}
EventBus Events
ConsentService emits the following via emitCanonicalSystemEvent:
| Event | When |
|---|
INTELLIGENCE_CONSENT_GRANTED | Organisation opts in |
INTELLIGENCE_CONSENT_WITHDRAWN | Organisation opts out |
INTELLIGENCE_DATA_DELETION_REQUESTED | Organisation requests erasure |
IntelligenceService
Provides read-only access to platform intelligence data. Before any read, verifyConsent() is called internally — requests from organisations that have not opted in receive an AuthorizationError.
Export
import { intelligenceService } from '@/shared/intelligence';
Caching Strategy
- Check
organizations/{orgId}/intelligenceCache/{cacheKey} (org-scoped cache).
- If cache is stale (older than 24 hours), fall back to platform-level aggregate collections under
platform/intelligence/.
- Cloud Functions refresh org caches on a nightly schedule.
Key Methods
// Sector benchmarks — how does this org compare to peers?
intelligenceService.getBenchmarks(
organizationId,
options?: BenchmarkQueryOptions
): Promise<OrgBenchmarkPosition>
// Funder intelligence — success rates, preferences, decision timelines
intelligenceService.getFunderProfile(
organizationId,
funderName: string
): Promise<FunderProfile | null>
intelligenceService.getFunderInsights(
organizationId,
funderName: string
): Promise<FunderInsight[]>
// Sector trends — thematic funding shifts, emerging priorities
intelligenceService.getSectorTrends(
organizationId,
sector?: string
): Promise<SectorTrend[]>
// Invalidate org cache (called after consent withdrawal)
intelligenceService.clearOrgCache(organizationId): Promise<void>
BenchmarkQueryOptions
interface BenchmarkQueryOptions {
sector?: string;
country?: string;
subscriptionTier?: SubscriptionTier; // compare like-for-like
metrics?: string[]; // subset of benchmark dimensions
}
OrgBenchmarkPosition
interface OrgBenchmarkPosition {
organizationId: string;
sector: string;
peerCount: number;
metrics: {
[metricName: string]: {
value: number;
percentile: number; // 0–100
average: number;
median: number;
};
};
lastRefreshed: string;
}
Firestore Collections
| Path | Contents |
|---|
platform/intelligence/benchmarks/{benchmarkId} | Sector-level benchmark aggregates |
platform/intelligence/funderProfiles/{funderId} | Per-funder intelligence summaries |
platform/intelligence/trends/{trendId} | Sector trend analysis |
platform/intelligence/consent/{orgId} | Consent records |
organizations/{orgId}/intelligenceCache/{cacheKey} | Org-scoped cached intelligence |
Privacy Notes
- No individual organisation’s data is exposed to another. All platform aggregates are computed from anonymous, aggregate statistics by Cloud Functions.
- Consent records are stored at the platform level (not org-scoped) so they remain accessible even if an org’s data is deleted.
requestDataDeletion() sets deletionRequestedAt and triggers a Cloud Function to anonymise the org’s contribution to platform aggregates within 30 days (GDPR Article 17 compliance).
Callers
| Caller | Uses |
|---|
src/features/organizations/ | Consent management UI (ConsentService) |
src/features/dashboard/ | Intelligence widgets reading benchmarks and trends |
src/features/grantors/ | Funder profile and insight lookups |
| Firebase Cloud Functions | Platform aggregate computation; org cache refresh |