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.

Dependency & Import Map

Import boundaries, path aliases, provider hierarchy, and ESLint-enforced rules that govern how modules interact.

Path Aliases

AliasResolves ToUsage
@/*src/*All app-level imports
@grantmaster/sharedpackages/shared/src/index.tsShared types, events, contracts
@grantmaster/shared/*packages/shared/src/*/index.tsShared submodules
@grantmaster/domain-schemapackages/domain-schema/src/index.tsDomain schemas
@grantmaster/domain-schema/*packages/domain-schema/src/*Schema submodules
Defined in tsconfig.json and mirrored in vite.config.ts.

Import Boundaries

Rules

  1. Features are isolatedsrc/features/[A]/ must not import from src/features/[B]/ internals. Use the barrel export (index.ts) if cross-feature access is needed.
  2. Core is sharedsrc/core/ can be imported by any feature.
  3. Components are sharedsrc/components/ can be imported by any feature.
  4. Hooks are sharedsrc/hooks/ can be imported by any feature.
  5. Types are sharedsrc/types/ can be imported by any feature.
  6. Services stay in features — services are private to their feature; expose via context/hooks if needed.

Dependency Direction

Features depend downward on core, shared, and components — never laterally on other features’ internals.

Provider Hierarchy

Three-tier composition: GlobalProviders → DomainProviders → FeatureProviders. Tier 1 wraps the entire app. Tier 2 wraps authenticated routes. Tier 3 wraps specific route subtrees.

Common Dependency: TenantContext

Almost every feature depends on useTenant() from @/contexts/TenantContext. This provides:
  • orgId — current organization
  • tenantClassification — org type (ngo, social-enterprise, etc.)
  • Organization settings and preferences
Gotcha: Use useTenant(), never useOrganization (deprecated).

Shared Dependencies

DependencyUsed ByImport
TenantContextAll features@/contexts/TenantContext
AuthContextAll features@/contexts/AuthContext
Firebase coreAll services@/core/firebase
React QueryAll data hooks@tanstack/react-query
EventBusAll services (emit)@/core/eventBus
BaseServiceAll services (extend)@/core/BaseService
firestoreCollectionsAll services (data access)@/core/firestoreCollections

ESLint-Enforced Boundaries

Custom rules in eslint.config.js that enforce architectural boundaries at build time:
RuleWhat It Enforces
no-direct-firestore-importMust use typed refs from firestoreCollections
no-direct-onsnapshotMust go through service layer
prefer-typed-firestore-refsMust use canonical typed references
no-eventbus-in-componentsEventBus only in services, never in React components
require-firestore-limitEvery Firestore query needs explicit limit()
no-derived-statePrevents stale derived state patterns
no-legacy-tailwind-paletteEnforces slate-*, emerald-*, rose-*, amber-*
no-raw-button-with-design-systemMust use <Button> component
no-raw-text-input-with-design-systemMust use <Input> / <Textarea>
no-status-badge-bypassMust use <StatusBadge> component

Workspace Structure

grantmaster/                  # Root (npm workspaces)
├── src/                      # Main React app
├── functions/                # Firebase Cloud Functions (separate workspace)
├── packages/
│   ├── shared/               # Shared types, events, contracts
│   └── domain-schema/        # Domain Zod schemas
├── portal/                   # External portal app
└── apps/                     # Additional apps
Cross-workspace imports use the @grantmaster/* aliases. The main app and functions share types via packages/shared/.