api-database-drizzle-e74c2b — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited api-database-drizzle-e74c2b (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Quick Guide: Use Drizzle ORM for type-safe queries, Neon serverless Postgres for edge-compatible connections. Schema-first design with automatic TypeScript types. Use RQB v2 withdefineRelations()and object-basedwheresyntax. Relational queries with.with()avoid N+1 problems. Use transactions for atomic operations.
<critical_requirements>
All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering, import type, named constants)(You MUST set `casing: 'snake_case'` in Drizzle config to map camelCase JS to snake_case SQL)
(You MUST use `tx` parameter (NOT `db`) inside transaction callbacks to ensure atomicity)
(You MUST use `.with()` for relational queries to avoid N+1 problems - fetches all data in single SQL query)
(You MUST use `defineRelations()` for RQB v2 - the old `relations()` per-table syntax is deprecated)
</critical_requirements>
Detailed Resources:
Auto-detection: drizzle-orm, @neondatabase/serverless, neon-http, db.query, db.transaction, drizzle-kit, pgTable, defineRelations, drizzle-seed
When to use:
When NOT to use:
<patterns>
Configure Drizzle with Neon for serverless/edge compatibility. Key setup requirements:
export const db = drizzle(sql, {
schema,
casing: "snake_case", // Maps camelCase JS to snake_case SQL
});DATABASE_URL before use (throw on missing)casing: "snake_case" to prevent field name mismatchesneon() for HTTP (edge-compatible) or Pool for WebSocket (long queries)Full connection setup, WebSocket config, and Drizzle Kit config in examples/core.md.
Define tables with TypeScript types using Drizzle's schema builder:
export const companies = pgTable("companies", {
id: uuid("id").primaryKey().defaultRandom(),
name: varchar("name", { length: 255 }).notNull(),
slug: varchar("slug", { length: 255 }).unique(),
deletedAt: timestamp("deleted_at"), // Soft delete
createdAt: timestamp("created_at").defaultNow(),
});pgEnum() for constrained values instead of varcharcreatedAt/updatedAt timestampsdeletedAt for soft deletesonDelete: "cascade" on foreign keys to prevent orphaned recordsuuid().defaultRandom() or integer().generatedAlwaysAsIdentity() for primary keysFull schema examples (enums, relations, junction tables, identity columns) in examples/core.md.
.with()Fetch related data efficiently in a single SQL query using .with():
const job = await db.query.jobs.findFirst({
where: and(eq(jobs.id, jobId), isNull(jobs.deletedAt)),
with: {
company: { with: { locations: true } },
jobSkills: { with: { skill: true } },
},
});
// Result is fully typed: job.company.name, job.jobSkills[0].skill.nameisNull(deletedAt) in WHERE conditions for soft-deleted tablesFull relational query examples, N+1 anti-patterns, and dynamic filtering in examples/queries.md.
</patterns>
The following patterns are documented with full examples in examples/:
generate vs push - see migrations.mdPerformance optimization (indexes, prepared statements, pagination) is documented in reference.md.
<red_flags>
.with() to fetch in one querydefineRelations()isNull(deletedAt))Gotchas & Edge Cases:
enableRLS() deprecated in v1.0.0-beta.1 - use pgTable.withRLS() insteaddrizzle-zod is now drizzle-orm/zod (since v1 beta)For the complete list of anti-patterns and gotchas, see reference.md.
</red_flags>
<critical_reminders>
All code must follow project conventions in CLAUDE.md
(You MUST set `casing: 'snake_case'` in Drizzle config to map camelCase JS to snake_case SQL)
(You MUST use `tx` parameter (NOT `db`) inside transaction callbacks to ensure atomicity)
(You MUST use `.with()` for relational queries to avoid N+1 problems - fetches all data in single SQL query)
(You MUST use `defineRelations()` for RQB v2 - the old `relations()` per-table syntax is deprecated)
Failure to follow these rules will cause field name mismatches, break transaction atomicity, create N+1 performance issues, and use deprecated APIs.
</critical_reminders>
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.