Guides
- Pre-commit hook: Biome runs on staged files +
pnpm typecheckruns full monorepo (turbo cached). Cold ~30s, warm near-instant. Fix before commit — it blocks. ^buildin turbo: Tests and typecheck depend on building deps first. If type errors appear after changing a package, runpnpm build.- Workspace header: Frontend sends
x-workspace-idon every tRPC request. Missing → falls back to user's default workspace. - Master workspace bypass:
scopedFilterskips workspace check for master UUID. Never use this ID for user-facing operations. - Standalone Next.js: Both apps use
output: "standalone"..next/standaloneis what deploys. ignoreBuildErrors: true: Both Next.js apps allow TS errors during build. Rely onpnpm typecheck.- Async event dispatch: Polling-based (1s interval). Events aren't immediately processed after a mutation.
- CI:
.github/workflows/ci.ymlruns typecheck + lint on every PR + push to main. Tests NOT yet in CI (need real Postgres + Temporal). Deployments manual viadeploy.sh. - Temporal activities can import directly: Activities run in regular Node (not sandboxed like workflows). Use direct + lazy
await import()for heavy deps like@react-pdf/rendererrather than HTTP calls. - Monetary writes: Use
nullto clear nullable fields,undefinedto skip (seehandleSavein product detail). - Product/Asset type enum shared:
assetTypeEnumdefined inassets.ts, imported byproducts.ts. Update in one place. - Signed tokens for tracking: Quote/invoice tracking URLs embed the redirect target inside the signed JWT — never accept redirect URLs from query params (open-redirect).
- Stripe webhook:
POST /api/webhooks/stripehandles both quote (payment_intent.*) and invoice (checkout.session.*) events. Routes bysession.metadata.invoiceId. - Automation allowlist:
ActionExecutor.UPDATABLE_FIELDSgates which entity fields automations can modify. Adding new automatable fields requires updating this allowlist.