Install
$ agentstack add skill-anbturki-claude-toolkit-drizzle-schema ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Create Drizzle Schema
Scaffold a new Drizzle schema for $ARGUMENTS.
Step 1: Learn Project Patterns
- Read CLAUDE.md for database conventions
- Detect database dialect: PostgreSQL, MySQL, or SQLite
- Find existing schemas:
`` Glob("**/schema/**/*.ts") Glob("**/schemas/**/*.ts") ``
- Read 2-3 existing schemas — learn:
- ID generation (cuid2, uuid, nanoid, auto-increment)
- Timestamp patterns
- Naming convention (snake_case columns)
- Index patterns
- How relations are defined
- Multi-tenant patterns (orgId column)
Step 2: Scaffold Schema
File location: Match existing schema file locations.
PostgreSQL
import { relations } from "drizzle-orm";
import {
index,
pgTable,
text,
timestamp,
boolean,
integer,
jsonb,
} from "drizzle-orm/pg-core";
// Match project's ID generation
import { createId } from "@paralleldrive/cuid2"; // or nanoid, uuid, etc.
export const ${entities} = pgTable(
"${entities}",
{
id: text("id")
.primaryKey()
.$defaultFn(() => createId()),
name: text("name").notNull(),
// Add fields matching project conventions
createdAt: timestamp("created_at").defaultNow().notNull(),
updatedAt: timestamp("updated_at")
.defaultNow()
.$onUpdate(() => new Date())
.notNull(),
},
(table) => [
index("${entities}_created_at_idx").on(table.createdAt),
],
);
// Relations
export const ${entities}Relations = relations(${entities}, ({ one, many }) => ({
// Define relations matching project patterns
}));
MySQL
import { mysqlTable, varchar, timestamp, int } from "drizzle-orm/mysql-core";
export const ${entities} = mysqlTable("${entities}", {
id: varchar("id", { length: 36 }).primaryKey().$defaultFn(() => createId()),
name: varchar("name", { length: 255 }).notNull(),
createdAt: timestamp("created_at").defaultNow().notNull(),
updatedAt: timestamp("updated_at").defaultNow().onUpdateNow().notNull(),
});
SQLite
import { sqliteTable, text, integer } from "drizzle-orm/sqlite-core";
export const ${entities} = sqliteTable("${entities}", {
id: text("id").primaryKey().$defaultFn(() => createId()),
name: text("name").notNull(),
createdAt: integer("created_at", { mode: "timestamp" }).$defaultFn(() => new Date()),
updatedAt: integer("updated_at", { mode: "timestamp" }).$defaultFn(() => new Date()),
});
Column Type Reference
| Type | PostgreSQL | MySQL | SQLite | |------|-----------|-------|--------| | String | text("name") | varchar("name", { length: 255 }) | text("name") | | Integer | integer("count") | int("count") | integer("count") | | Boolean | boolean("active") | boolean("active") | integer("active", { mode: "boolean" }) | | Timestamp | timestamp("at") | timestamp("at") | integer("at", { mode: "timestamp" }) | | JSON | jsonb("data") | json("data") | text("data", { mode: "json" }) | | Decimal | numeric("amount", { precision: 10, scale: 2 }) | decimal("amount", { precision: 10, scale: 2 }) | real("amount") |
Foreign Key Patterns
// Required (cascade delete)
orgId: text("org_id")
.notNull()
.references(() => organizations.id, { onDelete: "cascade" }),
// Optional (set null on delete)
createdBy: text("created_by")
.references(() => users.id, { onDelete: "set null" }),
// Required (restrict delete)
parentId: text("parent_id")
.notNull()
.references(() => parents.id, { onDelete: "restrict" }),
Index Patterns
(table) => [
index("${entities}_org_id_idx").on(table.orgId),
index("${entities}_org_name_idx").on(table.orgId, table.name), // composite
unique("${entities}_org_name_unique").on(table.orgId, table.name), // unique
]
Type Inference
// Infer types from schema — never define manually
export type ${Entity} = typeof ${entities}.$inferSelect;
export type New${Entity} = typeof ${entities}.$inferInsert;
Step 3: After Creation
- Export from schemas index:
export * from "./${entity}"; - Generate migration:
``bash npx drizzle-kit generate # or bunx drizzle-kit generate ``
- Apply migration:
``bash npx drizzle-kit migrate # or project's migrate command ``
Rules
- Match existing ID generation — use the same library (cuid2, nanoid, uuid, etc.)
- Match existing timestamp pattern — same column names and defaults
- Add indexes on foreign keys — always index columns used in joins/filters
- Use type inference —
$inferSelectand$inferInsert, never manual types - snake_case columns — convention for database column names
- Generate migrations — never manually create migration files
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: anbturki
- Source: anbturki/claude-toolkit
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.