Ensure accessibility in UI components including semantic HTML, ARIA attributes, keyboard navigation, and WCAG 2.2 AA compliance.
中文简介正在准备中。当前显示原文说明。
Rules for Drizzle ORM schema design, query patterns, migration workflows, and relational query usage. Ensures type-safe, production-ready database interactions.
中文简介正在准备中。当前显示原文说明。
安装前可以查看交给 AI 代理的指令内容。
Schema Design
integer('id').primaryKey().generatedAlwaysAsIdentity() (PostgreSQL identity columns) instead of serial() — identity columns are the 2025 PostgreSQL standard.export const timestamps = { createdAt: timestamp(...).defaultNow().notNull(), updatedAt: timestamp(...).$onUpdateFn(() => new Date()) }.varchar(name, { length: N }) with explicit max length for string columns storing bounded data (emails, codes, slugs).jsonb() not json() for JSON storage in PostgreSQL — jsonb is indexed and faster..notNull() on columns that must not be nullable.Indexing
pgTable's second argument callback: (table) => [index('name').on(table.col)].uniqueIndex() for unique constraints on single or combined columns..withSearchIndex or a GIN index via raw SQL migration.Queries
db.query.<table>.findMany({ with: { relation: true } }) (relational API) for typed nested joins.db.select().from(table).where(eq(table.col, val)) for flat queries.drizzle-orm: eq, and, or, gt, lt, like, inArray, isNull.db.transaction(async (tx) => {...}) for multi-step writes that must be atomic.with: in relational queries or explicit JOINs rather than looping queries.Migrations
drizzle-kit push (fast, no migration files) — never for production.drizzle-kit generate then drizzle-kit migrate — auditable SQL files.drizzle-kit pull before generating new migrations (brownfield projects).drizzle/ directory and commit them to version control.Relations
relations() alongside table definitions in schema.ts.one() for many-to-one references and many() for one-to-many or many-to-many.relations() definitions are separate — both required for the relational API to work.
</instructions>// Reusable timestamp columns export const timestamps = { createdAt: timestamp('created_at', { mode: 'date', withTimezone: true }).defaultNow().notNull(), updatedAt: timestamp('updated_at', { mode: 'date', withTimezone: true }) .defaultNow() .notNull() .$onUpdateFn(() => new Date()), };
export const users = pgTable('users', { id: integer('id').primaryKey().generatedAlwaysAsIdentity(), // NOT serial email: varchar('email', { length: 320 }).notNull().unique(), name: text('name').notNull(), meta: jsonb('meta'), // jsonb, not json ...timestamps, }, (table) => [ index('users_email_idx').on(table.email), ]);
export const posts = pgTable('posts', { id: integer('id').primaryKey().generatedAlwaysAsIdentity(), userId: integer('user_id').notNull().references(() => users.id), title: varchar('title', { length: 500 }).notNull(), ...timestamps, }, (table) => [ index('posts_user_id_idx').on(table.userId), ]);
// Relations (required for relational query API) export const usersRelations = relations(users, ({ many }) => ({ posts: many(posts), })); export const postsRelations = relations(posts, ({ one }) => ({ user: one(users, { fields: [posts.userId], references: [users.id] }), }));
// src/lib/db/queries.ts — typed relational query import { db } from './client'; import { eq } from 'drizzle-orm'; import { users } from './schema';
export async function getUserWithPosts(userId: number) { return db.query.users.findFirst({ where: eq(users.id, userId), with: { posts: true }, // nested join — no N+1 }); }
// Atomic transaction example
export async function transferData(fromId: number, toId: number, amount: number) {
return db.transaction(async (tx) => {
await tx.update(accounts).set({ balance: sqlbalance - ${amount} }).where(eq(accounts.id, fromId));
await tx.update(accounts).set({ balance: sqlbalance + ${amount} }).where(eq(accounts.id, toId));
});
}
</examples>
## Iron Laws
1. **ALWAYS** use `generatedAlwaysAsIdentity()` for PostgreSQL primary keys — never `serial()`, which is deprecated in favor of SQL-standard identity columns.
2. **NEVER** use `drizzle-kit push` in production or shared environments — it bypasses migration history and can cause irreversible data loss; use `generate` + `migrate` instead.
3. **ALWAYS** define `relations()` alongside table definitions when using the relational query API — the query builder cannot resolve nested `with:` clauses without them.
4. **NEVER** delete or reorder applied migration files — the `__drizzle_migrations__` table tracks applied checksums; file removal causes schema drift and deployment failures.
5. **ALWAYS** import query operators (`eq`, `and`, `or`, `gt`, `inArray`, etc.) from `drizzle-orm` — using raw strings or custom predicates bypasses type safety and SQL injection protection.
## Anti-Patterns
| Anti-Pattern | Why It Fails | Correct Approach |
| --- | --- | --- |
| Using `serial()` for primary keys | `serial` is a PostgreSQL pseudo-type implemented via sequences; deprecated since PG 10 in favor of SQL-standard identity columns | Use `integer('id').primaryKey().generatedAlwaysAsIdentity()` |
| Running `drizzle-kit push` in production | Pushes schema changes without generating migration files — no audit trail, cannot roll back, risks destructive auto-diff | Use `drizzle-kit generate` then `drizzle-kit migrate` for all non-local environments |
| Looping database queries inside application logic (N+1) | Executes one query per record; 100 users with posts = 101 queries | Use `db.query.users.findMany({ with: { posts: true } })` to fetch nested data in a single optimized query |
| Omitting `relations()` but using relational query API | Drizzle throws runtime errors when `with:` keys are not mapped via `relations()` | Define `relations()` for every table that participates in relational queries |
| Using `json()` instead of `jsonb()` for JSON columns | `json` stores raw text, cannot be indexed; `jsonb` stores binary, supports GIN indexes and faster operations | Replace `json()` with `jsonb()` for all PostgreSQL JSON columns |
## Memory Protocol (MANDATORY)
**Before starting:**
```bash
cat .claude/context/memory/learnings.md
After completing: Record any new patterns or exceptions discovered.
ASSUME INTERRUPTION: Your context may reset. If it's not in memory, it didn't happen.
还没有评价。欢迎分享你的使用感受。
无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。
还没有评论。来写第一条吧。
Ensure accessibility in UI components including semantic HTML, ARIA attributes, keyboard navigation, and WCAG 2.2 AA compliance.
中文简介正在准备中。当前显示原文说明。
Use when you want to improve response quality through meta-cognitive reasoning. Applies 15+ reasoning methods to reconsider and refine initial outputs.
中文简介正在准备中。当前显示原文说明。
N-round opposing-stance debates for trade-off analysis. Assigns pro/con roles to agents, runs structured debate rounds with quality scoring, and produces a moderator synthesis with confidence-rated recommendation. Generalizable to architecture, technology, security, and design decisions.
中文简介正在准备中。当前显示原文说明。
Force adversarial code review stance that eliminates confirmation bias — reviewer must find issues or re-analyze
中文简介正在准备中。当前显示原文说明。
Creates specialized AI agents on-demand when no existing agent matches a request. Use when the Router cannot find a suitable agent for a task. Enables self-evolution by generating persistent agents.
中文简介正在准备中。当前显示原文说明。
LLM-as-judge evaluation framework with 5-dimension rubric (accuracy, groundedness, coherence, completeness, helpfulness) for scoring AI-generated content quality with weighted composite scores and evidence citations
中文简介正在准备中。当前显示原文说明。