src/orchestrator/plugins/drizzle/SKILL.md
Drizzle ORM schema definition, type-safe queries, relational queries, CRUD operations, transactions, migrations with drizzle-kit, and database setup for PostgreSQL, MySQL, and SQLite. Use when defining database schemas, writing queries or joins, managing migrations, setting up a new Drizzle project, or working with drizzle-kit.
npx skillsauth add monkilabs/opencastle drizzle-ormInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Read the matching reference before writing code for any of these topics:
| Topic | Reference |
|-------|-----------|
| Schema definition & column types | references/schema-patterns.md |
| Queries, joins, & CRUD operations | references/query-patterns.md |
| Migrations & drizzle-kit | references/migrations.md |
Schema
schema.ts files using pgTable / mysqlTable / sqliteTable from the correct dialect package$inferSelect and $inferInsert for TypeScript types — never duplicate type definitions manuallyreferences(() => table.column) — omitting this creates an unconstrained column{ schema } to drizzle() when initializing the client to enable relational queriesRelations
relations() from drizzle-orm alongside the table definitiondb.query relational API — the SQL-like API does not use themQueries
db.select().from()) for complex joins and aggregationsdb.query.table.findMany({ with: { ... } })) for nested data fetchingeq, and, or, gt, like, isNull etc. from drizzle-orm for where clausesreturning() to get the inserted, updated, or deleted rows backMigrations
drizzle-kit for all migrations: npx drizzle-kit generate then npx drizzle-kit migratedrizzle.config.ts — connections string must be set before running commandsnpx drizzle-kit push in development only; always use migrate for productionTransactions
db.transaction(async (tx) => { ... })tx (the transaction argument) instead of db for all queries inside the callbackPerformance
db.select({ col: table.col }) for partial selects — avoids loading unused columns.prepare() for repeated queries (prepared statements)import { pgTable, text, integer, timestamp, boolean } from 'drizzle-orm/pg-core';
import { relations } from 'drizzle-orm';
export const users = pgTable('users', {
id: text('id').primaryKey(),
email: text('email').notNull().unique(),
name: text('name').notNull(),
createdAt: timestamp('created_at').defaultNow().notNull(),
});
export const posts = pgTable('posts', {
id: text('id').primaryKey(),
title: text('title').notNull(),
authorId: text('author_id').notNull().references(() => users.id, { onDelete: 'cascade' }),
published: boolean('published').default(false).notNull(),
});
export const usersRelations = relations(users, ({ many }) => ({
posts: many(posts),
}));
export const postsRelations = relations(posts, ({ one }) => ({
author: one(users, { fields: [posts.authorId], references: [users.id] }),
}));
// Type inference — no manual duplication
export type User = typeof users.$inferSelect;
export type NewUser = typeof users.$inferInsert;
import { db } from './db';
import { eq } from 'drizzle-orm';
import { users, posts } from './schema';
// SQL-like: select with join
const results = await db
.select({ user: users, postCount: count(posts.id) })
.from(users)
.leftJoin(posts, eq(posts.authorId, users.id))
.groupBy(users.id);
// Relational: nested fetch
const usersWithPosts = await db.query.users.findMany({
where: eq(users.id, userId),
with: { posts: { where: eq(posts.published, true) } },
});
// Insert with returning
const [newUser] = await db.insert(users).values({ id, email, name }).returning();
references/schema-patterns.md — Table definitions, column types, constraints, indexes, relations, type inferencereferences/query-patterns.md — Select, joins, where clauses, relational API, CRUD, transactions, prepared statementsreferences/migrations.md — drizzle.config.ts, generate/migrate/push commands, migration workflownpm install drizzle-orm + dialect driver (postgres / @libsql/client / better-sqlite3)npm install -D drizzle-kitsrc/db/schema.ts using the correct dialect table builderdrizzle.config.ts with database URL and schema path — verify the config before running commandsnpx drizzle-kit generate — inspect the SQL output before applyingnpx drizzle-kit migrate
npx drizzle-kit push for dev environmentsconst db = drizzle(pool, { schema }) and run a test query to confirm connectivitydevelopment
Defines 10 sequential validation gates: secret scanning, lint/test/build checks, blast radius analysis, dependency auditing, browser testing, cache management, regression checks, smoke tests. Use when running pre-deploy validation or CI checks, CI/CD pipelines, deployment pipeline validation, pre-merge checks, continuous integration, or pull request validation.
development
Generates test plans, writes unit/integration/E2E test files, identifies coverage gaps, flags common testing anti-patterns. Use when writing tests, creating test suites, planning test strategies, mocking dependencies, measuring code coverage, or test planning.
development
Provides model routing rules, validates delegation prerequisites, supplies cost tracking templates, defines dead-letter queue formats for Team Lead orchestration. Load when assigning tasks to agents, choosing model tiers, starting delegation session, running multi-agent workflow, delegating work, choosing which model to use, or assigning tasks.
testing
Saves, restores session state including task progress, file changes, delegation history. Use when saving progress, resuming interrupted work, picking up where you left off, or checkpointing current work.