Skip to content

Drizzle — Checklist

OWNER: urszula, maxim ALSO_USED_BY: boris, floris, hugo, jasper, marco, stef, arjan LAST_VERIFIED: 2026-03-26 GE_STACK_VERSION: drizzle-orm 0.45.x


SCHEMA CHECKLIST (before merging any schema change)

  • [ ] CHECK: All column names use snake_case in the SQL string argument IF_SKIPPED: TypeScript/SQL mismatch causes silent query failures
  • [ ] CHECK: All table names are plural and snake_case IF_SKIPPED: Inconsistent naming breaks conventions across 60 agents
  • [ ] CHECK: All timestamps use { withTimezone: true } IF_SKIPPED: Timezone data silently dropped — EU compliance violation
  • [ ] CHECK: Table has createdAt and updatedAt columns IF_SKIPPED: No audit trail for record lifecycle
  • [ ] CHECK: Enums are defined in drizzle/schema/enums.ts IF_SKIPPED: Scattered enums cause import cycles and duplication
  • [ ] CHECK: JSONB columns have $type<>() annotation IF_SKIPPED: Untyped JSONB defeats TypeScript strict mode
  • [ ] CHECK: Foreign keys specify onDelete behavior IF_SKIPPED: Default is RESTRICT — may cause unexpected constraint errors
  • [ ] CHECK: Indexes have explicit names matching {table}_{column}_idx IF_SKIPPED: Auto-generated names are unstable across drizzle-kit versions
  • [ ] CHECK: New domain module is exported from drizzle/schema/index.ts IF_SKIPPED: Table invisible to the application — silent 0-result queries

QUERY CHECKLIST (before merging any query code)

  • [ ] CHECK: Upserts use onConflictDoUpdate, not select-then-insert IF_SKIPPED: Race condition under concurrent access
  • [ ] CHECK: Partial selects used for tables with 10+ columns IF_SKIPPED: Unnecessary data transfer and memory usage
  • [ ] CHECK: Multi-table mutations wrapped in db.transaction() IF_SKIPPED: Partial failures leave data inconsistent
  • [ ] CHECK: No N+1 queries (query in a loop) IF_SKIPPED: O(N) database roundtrips — kills performance
  • [ ] CHECK: Pagination uses cursor-based, not OFFSET IF_SKIPPED: OFFSET re-scans all skipped rows — O(N) cost
  • [ ] CHECK: ZodError caught with .issues not .errors IF_SKIPPED: Zod v4 breaking change — .errors is undefined

MIGRATION CHECKLIST (before applying any migration)

  • [ ] CHECK: Migration file has header comment (author, date, source) IF_SKIPPED: No traceability for schema changes
  • [ ] CHECK: Migration file renamed to be descriptive IF_SKIPPED: _journal.json and filename must match
  • [ ] CHECK: Rollback file exists for destructive changes IF_SKIPPED: No recovery path if migration causes issues
  • [ ] CHECK: New indexes use CREATE INDEX CONCURRENTLY IF_SKIPPED: Table locked for duration of index build
  • [ ] CHECK: New NOT NULL columns have defaults or use 3-step pattern IF_SKIPPED: Table rewrite locks all rows — downtime
  • [ ] CHECK: No column renames (use add-backfill-drop pattern) IF_SKIPPED: Breaks running application instances during rolling deploy
  • [ ] CHECK: Verification queries included at bottom of migration IF_SKIPPED: No way to confirm migration applied correctly
  • [ ] CHECK: Boris has reviewed the migration SQL IF_SKIPPED: Database changes without DBA review violate GE process

CONNECTION CHECKLIST (per project)

  • [ ] CHECK: Single postgres() client in lib/db/index.ts IF_SKIPPED: Multiple connection pools exhaust max_connections
  • [ ] CHECK: DATABASE_URL read from environment, never hardcoded IF_SKIPPED: Credentials in source code — security violation
  • [ ] CHECK: drizzle.config.ts dialect is postgresql IF_SKIPPED: Wrong dialect generates incompatible SQL

Cross-References

READ_ALSO: wiki/docs/stack/drizzle/index.md READ_ALSO: wiki/docs/stack/drizzle/pitfalls.md READ_ALSO: wiki/docs/stack/drizzle/migrations.md READ_ALSO: wiki/docs/stack/postgresql/checklist.md