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.

Complete Data Model Reference

Single-read reference for the entire GrantMaster data model. Covers every Firestore collection, entity schema, enum, validation rule, relationship, and query pattern in one document. See also:

Table of Contents

  1. Multi-Tenancy Model
  2. Collection Inventory (71 collections)
  3. Aggregate 1: Identity & Access
  4. Aggregate 2: Grant Lifecycle
  5. Aggregate 3: Project Engine
  6. Aggregate 4: Finance
  7. Aggregate 5: Time Tracking
  8. Aggregate 6: Compliance & Audit
  9. Aggregate 7: Relations / CRM
  10. Aggregate 8: Documents & Knowledge
  11. Aggregate 9: People & HR
  12. Aggregate 10: Platform & Extensions
  13. Aggregate 11: Partnerships & Credits
  14. Cross-Aggregate Relationships
  15. Subscription Tiers & Feature Entitlements
  16. Enum Catalog (120+ enums)
  17. Validation Rules Summary
  18. Denormalization Patterns
  19. Foreign Key Conventions
  20. Firestore Index Requirements
  21. Collection Name Gotchas

1. Multi-Tenancy Model

Every entity except global taxonomies belongs to exactly one Organization via the TenantScoped base interface:
interface TenantScoped {
  organizationId: string;  // Required on every write
  createdAt: Timestamp;
  updatedAt: Timestamp;
}
Rules:
  1. Strict Isolation — no entity can belong to more than one Organization
  2. Scoping — all Firestore queries must include organizationId
  3. Exceptionsfoundations is a shared library readable by all orgs; write access is platform-admin only
  4. Cross-Tenant References — prohibited at both Service and Firestore Security Rules layers
  5. BaseService enforcementorganizationId is validated via Zod schema before any write

2. Collection Inventory

Root Collections (Tenant-Scoped)

#CollectionCode AliasTypeScript TypeDomain
1employeesusersUserIdentity
2projectsprojectsProjectProjects
3journalsjournalsJournalEntryTime Tracking
4expensesexpensesExpenseFinance
5journalSubmissionsjournalSubmissionsJournalSubmissionTime Tracking
6notificationsnotificationsNotificationPlatform
7referralsreferralsReferralPartnerships
8invitationsinvitationsInvitationIdentity
9grantApplicationsgrantApplicationsGrantApplicationGrants
10grantPipelinegrantPipelineGrantPipelineEntryGrants
11activeGrantsactiveGrantsActiveGrantGrants
12expenseAllocationsexpenseAllocationsExpenseAllocationFinance
13auditLogsauditLogsAuditLogEntryCompliance
14securityEventssecurityEventsSecurityEventIdentity
15systemEventssystemEventsRecord<string, unknown>Platform
16deadlinesdeadlinesDeadlineProjects
17complianceSummariescomplianceSummariesComplianceSummaryCompliance
18complianceAlertscomplianceAlertsComplianceAlertCompliance

Rule Engine Collections

#CollectionCode AliasTypeScript TypeScope
19compliance_rulescomplianceRulesCompliancePolicyTenant
20rule_templatesruleTemplatesRuleTemplatePlatform
21grant_rulesgrantRulesGrantRuleTenant
22rule_violationsruleViolationsRuleViolationTenant
23rule_analyticsruleAnalyticsRulePerformanceMetricsTenant
24platform_rulesplatformRulesPlatformPolicyPlatform
25tenant_donor_configstenantDonorConfigsTenantDonorConfigTenant

Relations & CRM Collections

#CollectionCode AliasTypeScript Type
26contactscontactsContact
27interactionsinteractionsInteraction
28contactViewscontactViewsContactView
29foundationsfoundationsTaxonomyItem (Platform)
30grantorInteractionsgrantorInteractionsGrantorInteraction
31reportingDeadlinesreportingDeadlinesReportingDeadline
32grantorRuleConflictsgrantorRuleConflictsGrantorRuleConflict
33hubspotConfigshubspotConfigsHubSpotConfig
34hubspotSyncLogshubspotSyncLogsHubSpotSyncLog

Stakeholder Portal Collections

#CollectionTypeScript Type
35portalTokensPortalToken
36portalSessionsPortalSession
37portalCommentsPortalComment
38portalReportAcknowledgmentsPortalReportAcknowledgment

Credits & Gamification Collections

#CollectionTypeScript TypeScope
39missionCreditsMissionCreditPer-user wallet
40creditTransactionsCreditTransactionTenant
41creditRedemptionsCreditRedemptionTenant
42badgesBadgeTenant
43gamificationPreferencesGamificationPreferencesPer-user
44campaignsCampaignPlatform / Tenant

Impact / M&E Collections

#CollectionTypeScript TypeScope
45meIndicatorsMEIndicatorTenant + Project
46meIndicatorTargetsMEIndicatorTargetTenant + Project
47meDataPointsMEIndicatorDataPointTenant + Project
48meDashboardConfigsMEDashboardConfigTenant + Project
49meKoboConnectionsMEKoboConnectionTenant
50meKoboFormLinksMEKoboFormLinkTenant + Project
51meIndicatorSummariesMEIndicatorSummaryTenant (read-only)
52meGrantIndicatorConfigsMEGrantIndicatorConfigTenant
53meAISuggestionsAIIndicatorSuggestionTenant + Project
54meWorkflowRulesMEWorkflowRuleTenant
55meWorkflowExecutionLogsMEWorkflowExecutionLogTenant
56meSettingsMEOrgSettingsTenant (1 doc/org)

Taxonomy Collections

#CollectionTypeScript Type
57budgetCategoriesBudgetCategory
58missionPillarsMissionPillar
59donorsTaxonomyItem

Platform Management (SuperAdmin)

#CollectionTypeScript TypeScope
60imuserationSessionsImuserationSessionPlatform
61auditorAccessGrantsAuditorAccessGrantTenant
62configSnapshotsConfigurationSnapshotTenant
63auditExportJobsAuditExportJobTenant
64platformMetricsPlatformMetricsPlatform
65userGrowthMetricsUserGrowthMetricsPlatform
66retentionCohortsRetentionCohortPlatform
67organizationMetricsOrganizationMetricsPlatform
68auditorReportsAuditorReportTenant

Platform-Wide & Config

#CollectionTypeScript Type
69grantOpportunitiesGrantOpportunity
70organizationsOrganization
71configmixed

Organization Subcollections

PathTypeScript TypePurpose
organizations/{orgId}/moduleInstallations/{moduleId}ModuleInstallationExtension install state
organizations/{orgId}/config/appSettingsAppSettingsOrg-specific settings
organizations/{orgId}/apiKeys/ApiKeyScoped API keys
organizations/{orgId}/webhooks/WebhookIntegration webhooks
organizations/{orgId}/integrations/IntegrationThird-party configs
organizations/{orgId}/onboarding/OnboardingStateWizard progress

Project Subcollections

PathTypeScript TypePurpose
projects/{id}/documentChunks/DocumentChunkRAG chunks
projects/{id}/complianceRules/ProjectComplianceRuleProject-specific rules
projects/{id}/budgetForecasts/BudgetForecastAI projections
projects/{id}/budgetAlerts/BudgetAlertThreshold alerts

Pipeline Subcollections

PathTypeScript TypePurpose
grantPipeline/{id}/tasks/PipelineTaskPreparation tasks
grantPipeline/{id}/documents/PipelineDocumentApplication docs
grantPipeline/{id}/activities/PipelineActivityActivity log

3. Identity & Access

Collections: organizations, employees, invitations, sessions, apiKeys, securityEvents

Organization

The root tenant. Users belong to exactly one organization.
FieldTypeNotes
idstringFirestore document ID
namestringDisplay name
slugstringURL-safe identifier
subscriptionTierSubscriptionTierfree | starter | growth | enterprise
settingsOrganizationSettingsLocale, branding, feature flags
classificationTenantClassificationNGO type, sector, jurisdiction
missionPillarsstring[]Tags for mission-alignment scoring

TenantClassification

6-dimensional profiling system for NGO tenants. Defined in src/schemas/classification.schema.ts.
DimensionEnum Values
organizationalRolengo, charity, social_enterprise, cooperative, foundation, government_agency, academic_institution, other
primarySectoreducation, health, environment, human_rights, poverty, agriculture, technology, arts_culture, disaster_relief, water_sanitation, gender_equality, child_welfare, elderly_care, disability, housing, legal_aid, food_security, other
geographicScopelocal, regional, national, international, global
budgetTiermicro (<50k), small (50k-500k), medium (500k-5M), large (5M-50M), enterprise (>50M)
operationalModeldirect_service, grant_making, capacity_building, advocacy, research, hybrid
jurisdictionNL, UK, OTHER (discriminated union with jurisdiction-specific legal/fiscal schemas)
Jurisdiction-specific legal/fiscal schemas (discriminated union):
  • Netherlands: STICHTING, VERENIGING, COOPERATIE, BV, OTHER legal forms; ANBI, SBBI, CBF recognition flags; KvK number, RSIN
  • UK: CIO, CLG, UNINCORPORATED, CIC, OTHER legal forms; charity number, HMRC, VAT flags
  • Generic: Arbitrary jurisdiction and legal form description fields

User

Stored in the employees Firestore collection.
FieldTypeNotes
idstringFirebase Auth UID
emailstring
firstName, lastNamestring
roleSystemRoleSUPER_ADMIN | ADMIN | MANAGER | MEMBER | AUDITOR
statusUserStatusactive | invited | suspended | deactivated
staffTypeStaffType12 types (see HR section)
departmentstring
jobTitlestring
mfaEnabledboolean
referralCodestring | nullSet when user joins via referral

Invitation

FieldType
emailstring
roleSystemRole
tokenstring (signed JWT)
statuspending | accepted | expired | revoked
expiresAtTimestamp (7 days)

Session

FieldType
userIdstring
deviceInfoDeviceInfo (browser/OS fingerprint)
lastActiveAtTimestamp
expiresAtTimestamp

SecurityEvent

FieldType
userIdstring
typeSecurityEventType (login | logout | failed_login | mfa_enrolled | password_changed | ...)
ipAddressstring
successboolean
metadataRecord<string, unknown>

ApiKey

FieldType
userIdstring (owner)
namestring
keyHashstring (SHA-256)
prefixstring (first 8 chars, shown in UI)
scopesApiKeyScope[]
expiresAtTimestamp | null
revokedAtTimestamp | null

4. Grant Lifecycle

Collections: grantOpportunities, grantPipeline, grantApplications, activeGrants, grantReports

GrantOpportunity

FieldTypeNotes
titlestring
grantorstringFunder name
fundingRange{ min, max }
deadlineTimestamp
eligibilityCriteriastring[]
source'platform' | 'manual'
matchScorenumberAI-computed 0–100

GrantPipelineEntry

FieldTypeNotes
opportunityIdstringFK → grantOpportunities
stagePipelineStageprospect | preparing | submitted | under_review | won | lost
probabilitynumber0–100
requestedAmountnumber
assignedTostring[]User IDs

GrantApplication

FieldTypeNotes
pipelineIdstringFK → grantPipeline
statusApplicationStatusdraft | submitted | under_review | awarded | rejected + 4 more
narrativestringAI-assisted text
attachmentsstring[]Storage URLs

ActiveGrant

FieldTypeNotes
applicationIdstringFK → grantApplications
awardedAmountnumber
currencystringISO 4217
disbursementScheduleDisbursement[]Embedded: tranche dates + amounts
reportingRequirementsReportingRequirement[]Deadlines and report types
projectIdsstring[]FK → projects (N:M)
status'active' | 'completed' | 'suspended'

GrantReport

FieldTypeNotes
grantIdstringFK → activeGrants
period{ from, to }Reporting period
status'draft' | 'submitted' | 'approved'

5. Project Engine

Collections: projects, budgetItems, milestones, tasks, deadlines

Project

FieldTypeNotes
namestring
statusProjectStatusplanning | active | on_hold | completed | archived
phaseProjectPhaseinitiation | planning | execution | monitoring | closure
budgetnumberTotal budget
currencystring
startDate / endDateTimestamp
grantIdsstring[]FK → activeGrants (N:M)
teamMemberIdsstring[]FK → employees
managerIdstringFK → employees
missionPillarsstring[]
templateIdstring | nullIf created from template

BudgetItem

FieldTypeNotes
projectIdstringFK → projects
categoryBudgetCategoryPersonnel | Operations | Travel | Equipment | Consultancy | Overhead
allocatedAmountnumber
spentAmountnumberDenormalized
grantIdstring | nullFunding source

Milestone

FieldType
projectIdstring
titlestring
dueDateTimestamp
statuspending | in_progress | completed
completionPercentagenumber

Task

FieldType
milestoneIdstring
projectIdstring (denormalized)
assigneeIdstring
statustodo | in_progress | blocked | done
prioritylow | medium | high | urgent

Deadline

FieldType
projectIdstring
typereporting | submission | payment | milestone
dueDateTimestamp
completedboolean

6. Finance

Collections: expenses, invoices, receipts

Expense

FieldTypeNotes
amountnumber
currencystring
categoryExpenseCategory7 categories
projectIdstringFK → projects
grantIdstring | nullFK → activeGrants (primary grant)
submittedBystringFK → employees
statusExpenseStatusdraft | pending | approved | rejected | paid
allocationsExpenseAllocation[]Embedded: split across grants
receiptUrlstring | nullFirebase Storage

ExpenseAllocation (embedded)

FieldTypeConstraint
grantIdstringFK → activeGrants
amountnumber
percentagenumberSum must = 100 (95-105% tolerance)

Invoice

FieldType
projectIdstring
vendorNamestring
amountnumber
dueDateTimestamp
statusunpaid | paid | overdue

BudgetCategory Enum

Personnel · Operations · Travel · Equipment · Consultancy · Overhead

7. Time Tracking

Collections: journals (JournalEntry), journalSubmissions (JournalSubmission)

JournalEntry

Stored in the journals collection.
FieldTypeNotes
userIdstringFK → employees
projectIdstringFK → projects
datestringISO YYYY-MM-DD
hoursnumber0–24
descriptionstringActivity description
entryTypeEntryTypework | vacation | sick_leave | parental_leave | study_leave
submissionIdstring | nullFK → journalSubmissions
grantIdstring | nullDirect grant attribution
auditFlagAuditFlaghigh | medium | low
lockedbooleanLocked entries cannot be edited
leaveDetailsLeaveDetails | nullRequired when entryType is a leave type
isVolunteerTimeboolean
inKindValuenumber | nullMonetary equivalent

JournalSubmission

Monthly summary submitted for manager approval. Stored in journalSubmissions.
FieldTypeNotes
userIdstringSubmitter
monthstringYYYY-MM
statusSubmissionStatusDraft | Submitted | Approved | Rejected | Regeneration Needed
totalHoursnumberDenormalized sum
approvedBystring | null
entryIdsstring[]FKs → journals
aiGenerationMetadataAIGenerationMetadata | nullIf AI-generated

AI Journal Generation Pipeline

11-stage processing pipeline defined in journalGenerationJobSchema:
validate_input → load_platform_policy → load_history → load_project_context →
retrieve_documents → merge_activity_data → apply_compliance_rules →
draft_cover → draft_entries → self_review → finalize_artifact

TimeOffRequest

FieldType
userIdstring
typevacation | sick | personal | bereavement | parental | unpaid | other
statusdraft | pending | approved | rejected | cancelled | taken
startDate / endDatestring
totalDaysnumber
approvedBystring | null

TimeOffBalance

FieldType
userIdstring
yearnumber
timeOffTypeTimeOffType
totalAllottednumber
usedDaysnumber
pendingDaysnumber
carriedForwardDaysnumber
availableDaysnumber (computed: totalAllotted - used - pending + carriedForward)

8. Compliance & Audit

Collections: compliance_rules, complianceAlerts, auditLogs

ComplianceRule

FieldType
namestring
domainfinancial | operational | legal | ...
checkTypethreshold | deadline | document | approval
severitylow | medium | high | critical | info
thresholdnumber | null
enabledboolean

ComplianceAlert

FieldType
ruleIdstring
entityType / entityIdstring
statusnew | acknowledged | investigating | resolved | dismissed
assignedTostring | null

AuditLog

Append-only. 80+ AuditAction constants.
FieldType
actionAuditAction
userIdstring
resourceType / resourceIdstring
organizationIdstring
resultsuccess | failure | partial
metadataRecord<string, unknown> (before/after diffs)
ipAddressstring | null
timestampTimestamp

9. Relations / CRM

Collections: foundations, contacts, grantorInteractions, reportingDeadlines

Foundation

Shared library of grant-making organizations (platform-scoped, not tenant-scoped).
FieldType
namestring
typefoundation | government | corporate | bilateral
focusAreasstring[]
geographicFocusstring[]
totalGrantsValuenumber

Contact

FieldType
typefunder | partner | vendor | consultant | beneficiary | stakeholder | other
firstName / lastNamestring
emailstring
foundationIdstring | null
relationshipStatusactive | inactive | prospect | archived
segmentsstring[]
hubspotContactIdstring | null

Interaction

FieldType
contactIdstring
typemeeting | call | email | video_call | event | note
dateTimestamp
summarystring
followUpDateTimestamp | null

GrantorRelationship

FieldType
foundationIdstring
engagementScorenumber (0–100)
engagementLevellow | medium | high | champion
deadlinesGrantorDeadline[] (embedded)

10. Documents & Knowledge

Collections: documents, documentFolders

DocumentFolder

FieldTypeNotes
namestring
parentIdstring | nullSelf-referencing tree
pathstring[]Ancestor IDs (for breadcrumbs + subtree queries)

Document

FieldTypeNotes
folderIdstring | null
namestring
storageUrlstringFirebase Storage
mimeTypestring
sizeBytesnumber
statusprocessing | indexed | failedRAG indexing state
projectId / grantIdstring | nullOptional scoping

Document Brain Types

47 specialized document types in documents-brain.schema.ts:
  • 8 compliance areas, 4 sensitivity levels, 6 approval statuses
  • 10 template categories, system folder keys

RAG Pipeline

7-stage document processing:
upload → text_extraction → chunking → embedding → metadata_extraction → indexing → complete
Each document produces DocumentChunk entries with vector embeddings stored for semantic search.

11. People & HR

Collections: employees (extended User), timeOffRequests, securityEvents

StaffType Enum (12 types)

full_time · part_time · contractor · intern · volunteer · consultant · temporary · fellow · board_member · advisor · secondee · other

ContractType Enum

permanent · fixed_term · freelance · zero_hours · internship

Extended User Fields

FieldType
staffTypeStaffType
contractTypeContractType
hourlyRatenumber | null
emergencyContactEmergencyContact | null
fundingAllocationsFundingAllocation[]
calendarIntegrationCalendarConfig | null

12. Platform & Extensions

Collections: organizations/{orgId}/moduleInstallations, widgetDefinitions, widgetAssignments

ModuleInstallation

FieldType
moduleIdstring (matches manifest ID)
versionstring (semver)
statustrialing | active | inactive | suspended | expired
installedBystring
configRecord<string, unknown>

Notification

FieldType
userIdstring
type18 notification types (journal, expense, project, compliance, system, etc.)
channelemail | push | in_app | sms
statuspending | sent | delivered | failed | read
priority4 levels

13. Partnerships & Credits

Collections: partnerOrganizations, referrals, missionCredits, creditTransactions, subscriptions

PartnerOrganization

FieldType
namestring
revenueShareRatenumber (0.10–0.20)
statusactive | suspended | pending | inactive | terminated
referralCodestring (PARTNER_{PREFIX}_{RANDOM})

MissionCredit

One document per org (document ID = organizationId).
FieldType
balancenumber
lifetimeEarned / lifetimeSpentnumber

CreditTransaction

FieldType
amountnumber (positive = credit, negative = debit)
typereferral_award | subscription_discount | manual_adjustment
referenceIdstring | null

Subscription

FieldType
stripeSubscriptionIdstring
tierSubscriptionTier
statusactive | past_due | canceled | trialing | paused | suspended
billingCyclemonthly | annual
seatsnumber

Agent Credit System

Reserve → Consume → Release pattern. See credit-system-architecture.md for the full flow.
Field on OrganizationType
subscription.features.agentCreditsPerMonthnumber (monthly allocation)
usageMetrics.agentCreditsUsedThisMonthnumber (consumed)
agentCreditsReservednumber (active reservations)
agentCreditsPurchasednumber (one-time top-ups)
Available = (monthly + purchased) - used - reserved

14. Cross-Aggregate Relationships


15. Subscription Tiers & Feature Entitlements

Source: src/config/entitlements.ts

Tier Limits

LimitPotentialProfessionalUltimate
Max Users31525
Max Projects1050Unlimited
Max Storage5 GB50 GBUnlimited
API Calls/Month010,000Unlimited
AI Generations/Month50200Unlimited
Exports/Month50UnlimitedUnlimited
API Calls/Hour01,00010,000
AI Generations/Hour1050Unlimited

Agent-Specific Limits

LimitPotentialProfessionalUltimate
Agent Credits/Month1001,00010,000
Concurrent Agents1310
Steps/Run520Unlimited
Tokens/Run50,000200,000Unlimited
Runs/Month10200Unlimited
Runs/Hour320100

Feature Gates (29 features)

CategoryFeaturesMin Tier
BasicJournals, Reports, Projects, Team CollaborationPotential
AIAI Generation, AI Journal, AI Report, AI Audit Defense, AI Grant AssistantProfessional
ProfessionalAPI Access, Advanced Reports, Custom Exports, Budget Forecasting, Expense Mgmt, Grant DiscoveryProfessional
EnterpriseSSO, SAML, Audit Logs, Custom Integrations, Branding, Multi-Currency, Compliance MonitoringUltimate
Storage/RAGDocument Uploads, Advanced Storage, RAG Search, Semantic SearchVaries
AgentsBasic, Multi-Step, Autonomous, OrchestrationProfessional–Ultimate
ImpactImpact Module (M&E)Professional

16. Enum Catalog

Status Enums

EnumValuesUsed By
ExpenseStatusdraft, pending, approved, rejected, paidExpense
SubmissionStatusDraft, Submitted, Approved, Rejected, Regeneration NeededJournalSubmission
ApplicationStatusdraft, submitted, under_review, awarded, rejected + 4 moreGrantApplication
PipelineStageprospect, preparing, submitted, under_review, won, lostGrantPipelineEntry
ProjectStatusplanning, active, on_hold, completed, archivedProject
ProjectPhaseinitiation, planning, execution, monitoring, closureProject
UserStatusactive, invited, suspended, deactivatedUser
InviteStatuspending, accepted, expired, revokedInvitation
TimeOffStatusdraft, pending, approved, rejected, cancelled, takenTimeOffRequest
ModuleInstallStatustrialing, active, inactive, suspended, expiredModuleInstallation
ComplianceAlertStatusnew, acknowledged, investigating, resolved, dismissedComplianceAlert
AgentRunStatus7 statusesAgentRun
LeadStatusnew, contacted, qualified, proposal, negotiation, won, lostLead
OpportunityStageprospecting, qualification, proposal, negotiation, closed_won, closed_lostOpportunity
NotificationStatuspending, sent, delivered, failed, readNotification
ReportStatusdraft, generating, completed, failed, archivedReport
PartnerStatuspending, active, inactive, suspended, terminatedPartnerOrganization

Type/Category Enums

EnumValuesUsed By
ExpenseCategoryPersonnel, Operations, Travel, Equipment, Consultancy, Overhead + 1Expense
BudgetCategorySame 6 categoriesBudgetItem
EntryTypework, vacation, sick_leave, parental_leave, study_leaveJournalEntry
TimeOffTypevacation, sick, personal, bereavement, parental, unpaid, otherTimeOffRequest
StaffType12 types (see HR section)User
ContractTypepermanent, fixed_term, freelance, zero_hours, internshipUser
ContactTypefunder, partner, vendor, consultant, beneficiary, stakeholder, otherContact
CommunicationTypemeeting, call, email, video_call, event, noteInteraction
DocumentType8 typesDocument
ReportTypeproject, expense, journal, budget, compliance, audit, grant, customReport
DeadlineTypereporting, submission, payment, milestoneDeadline
SystemRoleSUPER_ADMIN, ADMIN, MANAGER, MEMBER, AUDITORUser
SubscriptionTierfree, starter, growth, enterpriseOrganization
NotificationType18 typesNotification

Severity & Priority Enums

EnumValues
ComplianceSeverityinfo, low, medium, high, critical
EventSeverityINFO, WARNING, ERROR, CRITICAL
TaskPrioritylow, medium, high, urgent
AuditFlaglow, medium, high
NotificationPriority4 levels

Gamification Enums

EnumValues
BadgeTierbronze, silver, gold, platinum, diamond
PointEventTypejournal_submitted, journal_approved, project_created, expense_submitted, report_generated, milestone_completed, goal_achieved, streak_maintained, profile_completed, training_completed, badge_earned
ChallengeTypeindividual, team, organization

17. Validation Rules Summary

These Zod .refine() rules enforce business constraints at the schema level:
DomainRuleConstraint
ExpenseAllocation sumsum(allocations[].percentage) must be 95–105%
ExpenseReceipt requirementCertain categories require receiptUrl
JournalHours range0–24 per entry
JournalLocked immutabilityLocked entries cannot be edited
JournalLeave detailsLeave-type entries must have leaveDetails
JournalFuture dateEntry date cannot be in the future
SubmissionSubmitted statestatus=Submitted requires submittedAt
SubmissionApproved statestatus=Approved requires reviewedBy
InvoiceDate orderingissueDatedueDate
InvoicePaid statestatus=paid requires paidAt
InvoiceArithmeticsubtotal + tax = total
SubscriptionDate orderingstartDatecurrentPeriodStart < currentPeriodEnd
ClassificationSector uniquenesssecondarySectors cannot include primarySector
ClassificationFoundation year1800 – current year
ClassificationSDG limitMax 5 SDGs
TimeOffDate orderingstartDateendDate
TimeOffApproved stateRequires approvedBy
TimeOffRejected stateRequires rejectionReason
TimeOffBalance formulaavailable = totalAllotted - used - pending + carriedForward
TimeOffOverdraft guardused + pending ≤ total + carriedForward
AccrualMethod validationAccrual method accrued requires accrualRate
ProjectDate orderingstartDateendDate
OrganizationSuspensionSuspended orgs require suspensionReason
Generation JobCompletionCompleted jobs must have artifact
TimerFuture guardstartTime cannot be in future
ReportCompletionCompleted reports require completedAt
ReportFailureFailed reports require errorMessage
GamificationPoints formulatotalPoints = availablePoints + redeemedPoints
GamificationPoints calcbasePoints * multiplier + bonusPoints (±0.1% tolerance)
Feature FlagsPartial rolloutNot 0/100 percentage only for testing status flags

18. Denormalization Patterns

Denormalized FieldLives OnSource Of TruthSync Mechanism
project.grantIds[]projectsactiveGrant.projectIds[]Co-write by grantService + projectService
activeGrant.projectIds[]activeGrantsproject.grantIds[]Co-write
expense.grantIdexpensesallocations[0].grantIdConvenience field set on write
journalSubmission.totalHoursjournalSubmissionsSum of journal entriesjournalService.submitMonth()
journalSubmission.entryIds[]journalSubmissionsEntries where submissionId == idjournalService.submitMonth()
documentFolder.path[]documentFoldersParent chain traversalComputed on write
contactSegment.memberCountcontactSegmentsContact count matching criteriaScheduled evaluation
grantorRelationship.engagementLevelgrantorRelationshipscalculateEngagementScore()Updated on score change
task.projectIdtasksmilestone.projectIdCopied from milestone on create

19. Foreign Key Conventions

Firestore has no native joins. GrantMaster uses four reference patterns:
PatternWhen UsedExample
String ID reference1:1 or N:1 across collectionsexpense.projectId → projects/{id}
String array referenceN:M across collectionsproject.grantIds → activeGrants[]
Embedded sub-document1:N when child is always read with parent, array boundedexpense.allocations[]
Firestore subcollection1:N when child list is unbounded or queried independentlyorganizations/{id}/moduleInstallations/{moduleId}
All string FK references use the target document’s Firestore document ID.

20. Firestore Index Requirements

CollectionFieldsDirectionUsed By
expensesorganizationId, status, createdAtASC, ASC, DESCExpense list views
expensesorganizationId, grantId, statusASC, ASC, ASCGrant expense reports
activeGrantsorganizationId, statusASC, ASCDashboard widgets
journalsorganizationId, userId, dateASC, ASC, DESCJournal views per user
compliance_rulesorganizationId, type, status, createdAtASC, ASC, ASC, DESCCompliance dashboard
auditLogsorganizationId, resourceType, resourceId, timestampASC, ASC, ASC, DESCEntity audit trails
documentsorganizationId, path, statusASC, ASC, ASCFolder subtree views
grantPipelineorganizationId, stage, updatedAtASC, ASC, DESCPipeline board

21. Collection Name Gotchas

Collection NameStoresUI Calls It
employeesUser documentsUsers / Team
journalsJournalEntry documentsJournals / Time Tracking
journalSubmissionsJournalSubmission documentsMonthly Submissions
compliance_rulesCompliancePolicy documentsCompliance Rules
missionCreditsMissionCredit wallet (1 per org)Credits

Maintenance

Update this document when:
  • Adding or renaming a Firestore collection
  • Introducing a new aggregate domain
  • Changing entity schemas or adding new Zod schemas
  • Modifying subscription tier limits or feature gates
  • Adding new enum values or validation rules
For architectural patterns, see: