Skip to content

RoninForge/roninforge-drizzle

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

roninforge-drizzle

Validate Plugin License: MIT GitHub release

Cursor plugin for Drizzle ORM (drizzle-orm@0.45.x stable + 1.0.0-rc.x next). Teaches schema-first design, drizzle-kit migrate vs push vs pull, the sql template tag for parameter binding, drizzle-zod validation pairing, Postgres RLS / materialised views / sequences, Testcontainers transaction-rollback tests. Catches the 20 LLM regressions that come from Prisma muscle memory and pre-2025 Drizzle training data.

The Problem

LLMs trained on early Drizzle codebases plus a lot of Prisma produce code that does not type-check or that ships SQL injection. They write:

  • Prisma include: { posts: true } inside db.query.users.findMany(...) (Drizzle uses with:)
  • Prisma select: { id: true } inside the same (Drizzle uses columns:)
  • Prisma nested where: { user: { name: "x" } } filter shape (Drizzle uses callback + exists)
  • **db.execute(\SELECT * FROM users WHERE email = '${email}'`)** (SQL injection; use sql`...${email}``)
  • drizzle-kit generate:pg in package.json scripts (deprecated; use drizzle-kit generate)
  • drizzle-kit push in production deploy scripts (writes diff with no migration history; use migrate)
  • casing: "camelCase" on the drizzle() constructor when on v1.0-rc (removed; use per-table camelCase.table())
  • from "drizzle-orm/pg-core/utils" import of pgArray when on v1.0-rc (path moved to /array)
  • pgTable("users", {...}, (t) => ({ keyName: ... })) returned-object index shape against 0.31+ (returns array now)
  • pgTable imported from drizzle-orm/postgres-js (driver, not schema namespace; use pg-core)
  • .returning() on MySQL or Cloudflare D1 inserts (Postgres-only; better-sqlite3 has it, D1 does not yet)
  • Missing await on db.select() / .insert() / .execute() chains (returns QueryBuilder, not data)
  • relations() declared in the same file as pgTable (circular import risk)
  • Composite primary key shape: primaryKey(t.a, t.b) instead of primaryKey({ columns: [t.a, t.b] })
  • pgEnum used as a TypeScript type instead of branding with $type<T>()
  • select().from(users).leftJoin(posts, ...) consumed as flat rows when default shape is nested
  • Transaction callback using outer db.X instead of the tx argument (escapes the transaction)
  • drizzle-orm < 0.45.2 still installed (CVE in sql.identifier() / sql.as() escaping)
  • select() with leftJoin on a 1:N when distinct user rows are wanted (use selectDistinct + projection, or groupBy for aggregates)
  • Hand-translating an existing database to TypeScript when drizzle-kit pull does it in one command

Why this plugin (vs the existing community Drizzle rules)

A basic Drizzle rules file already exists on cursor.directory. It is shallow: generic "use Drizzle, prefer types, write migrations" guidance with no version awareness, no anti-patterns, no fixtures. This plugin is the depth play:

  • 20 documented anti-patterns with BAD/CORRECT TS code (the existing rule has none)
  • Two version profiles - 0.45.x stable (npm latest today) and 1.0-rc next - with deltas called out inline
  • Migration skill from v0 to v1-rc with concrete sed commands and step ordering
  • Postgres-specific rules broken out (RLS, materialised views, sequences, identity columns, JSONB operators)
  • Multi-dialect awareness per rule (Postgres / MySQL / SQLite / D1 specifics flagged)
  • Reviewer agent with severity grouping (CRITICAL / ERROR / WARN / SUGGESTION)
  • Compilable test fixtures (anti-pattern + correct sample)
  • drizzle-kit command awareness as a first-class rule (generate:pg errors today; push vs migrate for prod has caused outages)

Install

Copy the rules, skills, and agents into your project's Cursor configuration:

git clone https://github.com/RoninForge/roninforge-drizzle.git
cp -r roninforge-drizzle/rules/* your-project/.cursor/rules/
cp -r roninforge-drizzle/skills/* your-project/.cursor/skills/
cp -r roninforge-drizzle/agents/* your-project/.cursor/agents/

Or vendor the whole repo as a git submodule under your-project/.cursor/plugins/. Refer to the Cursor plugin docs for the current global-install path on your Cursor version.

What's Included

Rules (5 files)

Rule Scope What it does
drizzle-core Always active Schema-first design, separated relations file, sql template tag, $inferSelect/$inferInsert, drizzle-zod pairing, transaction semantics, v1.0-rc deltas inline
drizzle-anti-patterns Always active 20 LLM regressions: Prisma include/select/nested-where, removed casing API, deprecated drizzle-kit commands, SQL injection via execute, .returning() on MySQL, missing await, push in prod, pre-0.45.2 CVE
drizzle-postgres **/*.ts RLS via pgPolicy + enableRLS / withRLS, materialised views, sequences, identity columns, JSONB operators, generated columns, driver trade-offs
drizzle-migrations drizzle.config.ts + drizzle/ + migrations drizzle-kit four commands (generate / migrate / push / pull), config shape, snapshot files, applying in CI/prod
drizzle-testing Agent-requested Testcontainers Postgres + transaction rollback, in-memory pglite, drizzle-zod runtime validators, what to mock and what not

Skills (4 commands)

Skill Command What it does
New schema /drizzle-new-schema Scaffold table with identity column, $onUpdate timestamp, indexes-as-array, $infer types, drizzle-zod validator, separate relations file
Migrate to v1 /drizzle-migrate-to-v1 0.x to 1.0-rc migration: bump pin, codemod pgArray import, codemod casing, defineRelations rewrite, regenerate snapshots
Validate /drizzle-validate Scan codebase for the 20 tracked anti-patterns, severity-tagged report
RLS /drizzle-rls Scaffold Postgres RLS: pgPolicy declarations, enableRLS / withRLS, owner / tenant / public-read patterns, request-scoped auth context, isolation tests

Agent (1 subagent)

Agent What it does
drizzle-reviewer Reviews Drizzle TS by severity: critical (security, data loss), error (won't compile or wrong runtime), warning (regressions), suggestion (style + future-proofing)

Fixtures

tests/fixtures/anti-pattern-sample/ is a Drizzle 0.34 / drizzle-kit 0.21 trash fire: serial() PKs, relations() mixed with schema, third-arg returned object (won't compile against 0.31+), casing: "camelCase", SQL injection via db.execute, Prisma-style include:, missing await, transaction escape via outer db. The package.json ships the deprecated generate:pg and push:pg scripts plus drizzle-kit push as the deploy step.

tests/fixtures/correct-sample/ is the same shape rewritten on drizzle-orm@0.45.2: defineConfig drizzle.config.ts with strict: true, identity columns, schema split per file with separate relations.ts, sql\`template tag,with:for related entities,awaiton every chain,txinside transactions,drizzle-zod` validators, singleton pool sized for serverless.

License

MIT - see LICENSE

Links

About

Cursor plugin for Drizzle ORM (0.45.x stable + 1.0.0-rc next): schema-first design, sql template tag, drizzle-zod pairing, RLS scaffold, Testcontainers tests. Catches 20 LLM regressions from Prisma leakage and removed APIs.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages