ZRM Docs
Guides
  • Pre-commit hook: Biome runs on staged files + pnpm typecheck runs full monorepo (turbo cached). Cold ~30s, warm near-instant. Fix before commit — it blocks.
  • ^build in turbo: Tests and typecheck depend on building deps first. If type errors appear after changing a package, run pnpm build.
  • Workspace header: Frontend sends x-workspace-id on every tRPC request. Missing → falls back to user's default workspace.
  • Master workspace bypass: scopedFilter skips workspace check for master UUID. Never use this ID for user-facing operations.
  • Standalone Next.js: Both apps use output: "standalone". .next/standalone is what deploys.
  • ignoreBuildErrors: true: Both Next.js apps allow TS errors during build. Rely on pnpm typecheck.
  • Async event dispatch: Polling-based (1s interval). Events aren't immediately processed after a mutation.
  • CI: .github/workflows/ci.yml runs typecheck + lint on every PR + push to main. Tests NOT yet in CI (need real Postgres + Temporal). Deployments manual via deploy.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/renderer rather than HTTP calls.
  • Monetary writes: Use null to clear nullable fields, undefined to skip (see handleSave in product detail).
  • Product/Asset type enum shared: assetTypeEnum defined in assets.ts, imported by products.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/stripe handles both quote (payment_intent.*) and invoice (checkout.session.*) events. Routes by session.metadata.invoiceId.
  • Automation allowlist: ActionExecutor.UPDATABLE_FIELDS gates which entity fields automations can modify. Adding new automatable fields requires updating this allowlist.