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
| Alias | Resolves To | Usage |
|---|
@/* | src/* | All app-level imports |
@grantmaster/shared | packages/shared/src/index.ts | Shared types, events, contracts |
@grantmaster/shared/* | packages/shared/src/*/index.ts | Shared submodules |
@grantmaster/domain-schema | packages/domain-schema/src/index.ts | Domain schemas |
@grantmaster/domain-schema/* | packages/domain-schema/src/* | Schema submodules |
Defined in tsconfig.json and mirrored in vite.config.ts.
Import Boundaries
Rules
- Features are isolated —
src/features/[A]/ must not import from src/features/[B]/ internals. Use the barrel export (index.ts) if cross-feature access is needed.
- Core is shared —
src/core/ can be imported by any feature.
- Components are shared —
src/components/ can be imported by any feature.
- Hooks are shared —
src/hooks/ can be imported by any feature.
- Types are shared —
src/types/ can be imported by any feature.
- 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
| Dependency | Used By | Import |
|---|
| TenantContext | All features | @/contexts/TenantContext |
| AuthContext | All features | @/contexts/AuthContext |
| Firebase core | All services | @/core/firebase |
| React Query | All data hooks | @tanstack/react-query |
| EventBus | All services (emit) | @/core/eventBus |
| BaseService | All services (extend) | @/core/BaseService |
| firestoreCollections | All services (data access) | @/core/firestoreCollections |
ESLint-Enforced Boundaries
Custom rules in eslint.config.js that enforce architectural boundaries at build time:
| Rule | What It Enforces |
|---|
no-direct-firestore-import | Must use typed refs from firestoreCollections |
no-direct-onsnapshot | Must go through service layer |
prefer-typed-firestore-refs | Must use canonical typed references |
no-eventbus-in-components | EventBus only in services, never in React components |
require-firestore-limit | Every Firestore query needs explicit limit() |
no-derived-state | Prevents stale derived state patterns |
no-legacy-tailwind-palette | Enforces slate-*, emerald-*, rose-*, amber-* |
no-raw-button-with-design-system | Must use <Button> component |
no-raw-text-input-with-design-system | Must use <Input> / <Textarea> |
no-status-badge-bypass | Must 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/.