Skip to content
Docs

Command palette

Jump to a page or view, or find a todo by name.

Changelog

Review checklist

Review or self-review a change against the repository's rules, with the command or test that checks each item.

Markdown

Use this list before opening a pull request and when reviewing one. Skip the sections the change does not touch. Each item names what checks it: [type], [lint], [test], [build], [deploy] or [convention]. A [convention] item is checked only by a reviewer, so read it carefully.

Always

  • pnpm check-types, pnpm lint, FORMAT_BASE_REF=origin/main pnpm format:check and pnpm test pass. [type] [lint] [test]
  • Database behavior is tested against the disposable cluster: node scripts/test-local-postgres.mjs exec pnpm test:integration. TEST_DATABASE_URL never points at a shared or hosted database. [test]
  • A user-visible change has a changelog entry, and a changed flow updates its guide in the same change. [convention]
  • Commits are logical Conventional Commits, and file moves are not mixed with behavior changes. [convention]

Backend feature shape

  • The feature lives in packages/api/src/features/<feature>/ with role names (contract, procedures, service, errors, jobs, http) as described in ADR-0011. [test] boundary test
  • The contract file starts with the LEAF MODULE header and imports only leaves. [test] scripts/leaf-modules.test.mjs
  • Nothing new imports another feature's internals, a *.procedures file or a *.jobs file, and platform/ imports no feature. [lint] .oxlintrc.json · [test] scripts/feature-boundaries.test.mjs
  • No import cycle was introduced. [test] scripts/import-cycles.test.mjs
  • A migrated feature's *.service.ts, *.rules.ts, *.policy.ts and *.procedures.ts are listed in the D2 and D8 overrides of .oxlintrc.json. [lint]

Tenant isolation

  • Procedures use context.db, which runs as app_tenant. The organizationId filter is still present. [test] rls.isolation.test.ts
  • A new table uses pgTable.withRLS with tenantPolicy(...), gets its GRANT in packages/db/scripts/rls-baseline.mjs and ships with a generated, reviewed migration. drizzle-kit push is never used. [test] rls-catalog.test.ts
  • A new cross-tenant path uses asSystem(db, reason, fn) with a new SystemReason, and node scripts/check-system-call-sites.mjs --write ran in the same change. [lint]
  • withTenant holds no network I/O. [convention]
  • An operation limited to some Org roles chains requireOrgRole(...) after orgProcedure; no service compares role strings. [test] require-org-role.test.ts · [convention]
  • A tenancy change ran pnpm --filter @template-cloudflare/db test:rls-matrix, and node scripts/rls-preview-proof.mjs <previewUrl> passed against the preview before a production deploy. [test] [deploy]

Client/server boundary

  • A client imports only leaves, contracts or import type. No barrel was added to a server-capable module (ADR-0002). [lint]
  • A new cross-package import added a deliberate exports entry, and the package page names it. The web app imports no routers/*.schema alias. [test] packages/api/src/exports.test.ts, docs package-exports test
  • pnpm --filter web build passes, including assert-client-bundle-clean.mjs. [build]
  • apps/mobile changed only if the change is meant for the native app. [convention]

Errors and Effect

  • A domain failure is a Schema.TaggedError in <feature>.errors.ts, and the feature mapper handles it. A service imports no @orpc/*. [type] [lint]
  • A new client-visible code is in APP_ERRORS, ERROR_MESSAGE_KEYS and every locale (en, de, fr). [type] [test] locale tests
  • A procedure body calls runProcedure once. No Layer, ManagedRuntime or I/O runtime exists at module scope (ADR-0010, ADR-0005). [convention]
  • Only idempotent reads are retried. A webhook POST or an email send is never retried in-round. [convention]

Configuration and logging

  • A new environment variable is declared in packages/env and documented in the environments guide. It is read through the schema, not process.env. [lint] node/no-process-env
  • Expected failures (4xx) are not logged as errors. Unexpected failures carry the request ID. Logs contain no credentials, prompts or private payloads. [convention]

Runtime, bundle and decisions

  • A runtime, deadline or heavy-dependency change has a dated report in docs/measurements/ with exact commands and limits. [convention]
  • A change to an established boundary reads the relevant ADR first. A new boundary decision gets an ADR with a status line, and the ADR index is updated. [convention]
  • Dependency changes follow the two-day release quarantine and exact pins. [test] tooling tests

Read Enforcement for the full list of rules and how each is checked.

Edit on GitHubDocumentation is in English.