db-enforcer
npx skills add https://github.com/oakoss/agent-skills --skill db-enforcer
Agent 安装分布
Skill 文档
DB Enforcer
Overview
Enforces data integrity and architectural consistency between the TypeScript application layer and the PostgreSQL persistence layer. Prevents type drift by ensuring CHECK constraints mirror TypeScript types, migrations are generated before applying changes, and Row-Level Security protects every table.
When to use: Schema design, migration planning, RLS policy authoring, Prisma model mapping, constraint auditing, zero-downtime deployments.
When NOT to use: Application-level business logic, frontend state management, non-PostgreSQL databases. For full RLS auditing, performance tuning, and compliance validation, use the database-security skill instead.
Quick Reference
| Pattern | API/Tool | Key Points |
|---|---|---|
| Type-to-DB sync | prisma migrate dev --create-only |
Generate SQL before applying changes |
| Naming alignment | @map / @@map |
snake_case in SQL, camelCase in TS |
| Primary keys | DEFAULT uuidv7() |
Sequential, globally unique, fast indexing (PG 18+) |
| Virtual columns | GENERATED ALWAYS AS (...) VIRTUAL |
Zero disk cost, computed on read (PG 18+) |
| Temporal uniqueness | EXCLUDE USING gist |
Prevent overlapping ranges natively |
| NOT VALID constraints | ADD CONSTRAINT ... NOT VALID |
Add constraints without table locks |
| TypedSQL | prisma.$queryRawTyped() |
Type-safe raw SQL via .sql files |
| Relation emulation | relationMode = "prisma" |
Integrity in FK-less environments (GA since 4.8.0) |
| Soft deletes | Prisma $extends |
Cross-cutting concern via client extensions |
| RLS standard | (select auth.uid()) = user_id |
Default own-data access policy with initPlan caching |
| Team RLS | EXISTS subquery |
Permission checks via join tables |
| Column-level security | PostgreSQL Views | Hide sensitive columns from public APIs |
Synchronization Protocol
Every schema modification MUST follow these steps:
- Type-to-DB Verification: When adding an enum or union in TS, verify the equivalent CHECK constraint in SQL
- Migration-First Generation: Generate SQL migrations using
prisma migrate dev --create-onlyBEFORE applying - Naming Alignment: Enforce snake_case in SQL and camelCase in TS via explicit
@map/@@mapdirectives - Integrity Audit: Run
prisma validateand check for missing indices on relation scalars - RLS Verification: Confirm every new table has RLS enabled with appropriate policies
- Lock Assessment: Evaluate whether migration requires
CREATE INDEX CONCURRENTLYorNOT VALIDpatterns
PostgreSQL Version Requirements
Several patterns in this skill require specific PostgreSQL versions:
| Feature | Minimum Version | Fallback |
|---|---|---|
uuidv7() |
PostgreSQL 18 | gen_random_uuid() (UUIDv4) via pgcrypto |
| Virtual columns | PostgreSQL 18 | STORED generated columns (PG 12+) |
EXCLUDE USING |
PostgreSQL 9.0 | Application-level overlap checks |
NOT VALID |
PostgreSQL 9.1 | Schedule constraint addition during downtime |
security_invoker |
PostgreSQL 15 | Use security_definer with restricted grants |
Common Mistakes
| Mistake | Correct Pattern |
|---|---|
| Running SQL changes manually without migrations | Generate numbered migrations with prisma migrate dev --create-only before applying |
| Using auto-increment or raw IDs exposed in URLs | Use UUIDv7 for globally unique, non-enumerable identifiers |
| Skipping CHECK constraints on enums or unions | Add database-level CHECK constraints that mirror TypeScript types |
| Mixing snake_case and camelCase without explicit mapping | Use @map and @@map to enforce snake_case in SQL and camelCase in TypeScript |
| Tables without Row-Level Security policies | Apply RLS policies to every table, defaulting to (select auth.uid()) = user_id |
| DROP or RENAME column in a single deployment | Use expand-and-contract: add new column, dual-write, backfill, switch reads, drop old |
| Adding NOT NULL to large tables with full lock | Add column as NULL first, backfill, then add NOT NULL with NOT VALID |
| Creating indices without CONCURRENTLY | Use CREATE INDEX CONCURRENTLY in raw SQL migrations to avoid table locks |
Using auth.uid() directly in RLS without subselect |
Wrap in (select auth.uid()) to trigger initPlan caching |
Assuming uuidv7() works on all PG versions |
Verify PostgreSQL 18+; fall back to gen_random_uuid() on older versions |
Naming Conventions
Prisma models use camelCase in TypeScript and must map to snake_case in PostgreSQL:
| Layer | Convention | Enforced By |
|---|---|---|
| TypeScript | camelCase | Prisma model field names |
| PostgreSQL | snake_case | @map / @@map |
| Enums | UPPER_SNAKE | CHECK constraints |
| Indices | snake_case | idx_table_column |
Deployment Pipeline
Migrations follow a strict pipeline order:
prisma migrate dev --create-only— generate and review SQL locallyprisma validate— verify schema consistency- Apply to staging/preview database and run integration tests
prisma migrate deploy— apply in CI/CD pipeline to production- Monitor for lock contention and query plan regressions
Relationship to Other Skills
database-security: Covers full RLS auditing, PGAudit configuration, Supabase-specific patterns, Convex auth guards, and compliance validation. Usedatabase-securityfor in-depth policy review and access simulation. Usedb-enforcerfor schema design and migration patterns that include RLS as part of the integrity workflow.
Delegation
- Audit existing schema for missing constraints or indices: Use
Exploreagent - Plan a zero-downtime migration strategy for production databases: Use
Planagent - Execute a full schema refactor with type alignment and RLS setup: Use
Taskagent - Review RLS policies for bypasses and performance issues: Use
database-securityskill