Documentation Index
Fetch the complete documentation index at: https://grantmaster.dev/llms.txt
Use this file to discover all available pages before exploring further.
FAQ & Troubleshooting
Centralized guide for common issues, errors, and questions. See also: Common Gotchas for enforced rules and known pitfalls.
Local Development
Emulators won’t start / port conflicts
The Firebase Emulator Suite requires specific ports. If any are occupied, emulators will fail to bind.| Service | Port |
|---|---|
| Vite Dev Server | 3000 |
| Firebase Emulator UI | 4000 |
| Functions Emulator | 5001 |
| Firestore Emulator | 8080 |
| Auth Emulator | 9099 |
| Storage Emulator | 9199 |
npm run dev:all to start everything together, or coordinate manually with two terminals (npm run dev:start + npm run dev).
Health check: Run npm run health:emulators to verify emulator status.
CORS errors in development
- Ensure
VITE_USE_EMULATORS=trueis set in.env.localwhen running against emulators. - The Vite dev server must run on
localhost:3000(the authorized domain configured in Firebase). - If hitting production Firebase from localhost, CORS will block requests — always use emulators for local development.
Functions not responding
- Check
functions/firebase-debug.logfor execution errors. - Ensure the Functions emulator is running on port 5001.
- Rebuild functions after code changes:
cd functions && npm run build. - Verify dependencies are installed:
cd functions && npm install.
Hot reload not working
- Ensure you are running
npm run dev(Vite), not a production build. - Clear the Vite cache:
rm -rf node_modules/.viteand restart. - Large file changes (new routes, new providers) may require a full restart.
”Module not found” errors
- Run
npm installat the repo root to ensure all workspace dependencies are installed. - For functions:
cd functions && npm install.
Build & Deploy
Build fails with TypeScript errors
- Run
npx tsc --noEmitto see the full error list. - Check that shared types in
packages/shared/are up to date:npm run buildin that workspace. - ESLint custom rules (palette, component, architecture) will also fail the build — see Common Gotchas for the full list.
Deploy fails with permissions error
- Run
firebase loginto re-authenticate. - Ensure the correct project is selected:
firebase use stagingorfirebase use production. - For production deploys, the production guardrail pattern requires
--confirm-project=grantlog. Seescripts/README.mdfor details.
Staging vs production config issues
- Environment-specific configs are handled via
.env.staging/.env.production. - Build with the right command:
npm run build:stagingornpm run build:production. - Verify the active Firebase project:
firebase use.
Firebase / Firestore
”Permission denied” on Firestore reads
Common causes:- organizationId mismatch — The document’s
organizationIddoesn’t match the user’s tenant. Firestore security rules enforce tenant isolation. - Missing role or permission — The user lacks the required RBAC permission for the operation. Check
PermissionGuardand the user’s assigned roles. - Security rules not deployed — If rules were changed but not deployed, production behavior may differ from expectations.
- Check the Firestore Emulator UI (port 4000) for rule evaluation details.
- Verify the user’s custom claims:
firebase auth:exportor check in the Auth emulator. - Ensure
organizationIdis consistent across related documents.
TENANT_MISMATCH errors
This is a critical error indicating a cross-tenant data access attempt. The system will immediately terminate the session and log a high-priority event. Causes:- A user switched organizations but stale references point to the previous tenant’s data.
- A service call passes the wrong
organizationId.
- Force a full page reload to clear stale context.
- Verify that all service calls use
useTenant()(notuseOrganization, which is deprecated) to get the currentorganizationId.
Emulator data lost on restart
By default, emulator data is ephemeral. To persist data across restarts:emulators script uses --import/--export flags automatically.
Authentication
Custom claims not updating
Firebase custom claims (roles, permissions,organizationId) are embedded in the ID token and cached until the token refreshes (up to 1 hour).
Force a token refresh:
- Sign out and sign back in.
- In code, call
auth.currentUser?.getIdToken(true)to force a refresh. - After running scripts like
local:set-superadmin, restart the app or hard-refresh.
MFA issues in development
MFA is not enforced in the Auth emulator. If testing MFA flows:- The emulator auto-approves MFA challenges.
- Production MFA issues may stem from clock skew on the user’s device (TOTP) or expired phone verification codes.
Invitation link expired
- Invitation tokens have a TTL. Generate a new invitation from the Team page.
- Check that the
portalTokenscollection entry hasn’t expired.
Common Error Messages
The application uses a typed error hierarchy defined insrc/errors/AppError.ts. All errors extend AppError and carry a severity, category, and userMessage.
| Error Code | Type | Cause | Fix |
|---|---|---|---|
VALIDATION_ERROR | User | Zod schema failure or invalid input | Check input against the expected schema; inspect field-level errors in the UI |
PERMISSION_DENIED | Security | User lacks required RBAC role/permission | Verify user roles in the admin panel; check PermissionGuard wrapping |
TENANT_MISMATCH | Critical | Cross-tenant data access attempt | Verify organizationId consistency; force reload to clear stale context |
NOT_FOUND | Data | Entity doesn’t exist in the collection | Check the collection name and document ID; see collection name gotchas |
INTERNAL_ERROR | System | Unexpected backend/infrastructure failure | Check Sentry for stack trace; review functions/firebase-debug.log |
RATE_LIMIT | User | API throttling (too many requests) | Wait for the retryAfter period; reduce request frequency |
BUSINESS_LOGIC | User | Domain-specific validation failure | Read the error message for specifics (e.g., budget exceeded, deadline passed) |
Error categories in the codebase
For debugging, errors are also categorized by system area:validation, authentication, authorization, not_found, network, firestore, storage, rate_limit, business_logic, external_api, ai_service, email_service.
These categories appear in Sentry and structured logs. Filter by category to narrow down issues.
Performance
Slow Firestore queries
- Add
limit(): All Firestore queries must include an explicitlimit()— this is enforced by therequire-firestore-limitESLint rule. - Check indexes: Missing composite indexes cause full collection scans. The Firestore emulator logs index suggestions.
- Use pagination: For large result sets, use cursor-based pagination (
startAfter). - Review query patterns: Avoid
!=andnot-inoperators which bypass indexes.
Large bundle size
- All routes use
React.lazy()for code splitting — checksrc/routes/lazyComponents.tsx. - Verify chunk configuration in
vite-chunks.config.ts. - Run
npm run buildand inspect the output for unexpectedly large chunks. - Heavy libraries (PDF generation, Excel export) should only load in their respective routes.
Testing
E2E tests failing locally
- Ensure emulators are running before starting E2E tests.
- Run
npm run test:setup-usersto create required test users. - Check that shared auth state in
tests/.auth/is not stale — delete it and re-run. - Use
npm run test:e2e:debugfor step-by-step debugging.
Vitest watch mode issues
- If watch mode doesn’t pick up changes, clear the Vitest cache and restart.
- Ensure you’re running
npm run test(watch mode) ornpm run test:run(single run). - Tests use
jsdomenvironment — some Node-only APIs may not be available.
Emulator state between tests
- Tests should be idempotent. Avoid depending on state from previous tests.
- Use
npm run dev:all:freshto start with a clean emulator state before test runs. - For E2E, the
test:setup-usersscript provisions the baseline user data.
Scripts & Tooling
”Permission denied” when running scripts
”Firebase project not found”
Production guardrails blocking a script
Production-targeting scripts require explicit confirmation:SuperAdmin Troubleshooting
For platform-level diagnostics, SuperAdmins have additional tools:- EventBus (
/eventbus): Real-time stream of all domain, system, and external events. Filter bytenantIdto debug a specific tenant. - Audit Logs: Track infrastructure changes, permission grants, and tenant impersonation actions.
- System Health (
/integrations): Check connectivity status of external services (Firebase, Stripe, Postmark, etc.).