From house-style
Enforces PostgreSQL best practices for transaction safety (TX_ naming), read-write separation, ULID UUID PKs, JSONB typing, decimal money types, and snake_case naming when writing DB access code, schemas, or managing transactions.
npx claudepluginhub pbdeuchler/llm-plugins --plugin house-styleThis skill uses the workspace's default tool permissions.
Enforce transaction safety, type safety, and naming conventions to prevent data corruption and runtime errors.
Enforces PostgreSQL patterns for transaction safety with TX_ naming, read-write separation, ULID UUID PKs, type-safe JSONB/decimal handling, and snake_case conventions.
Designs scalable Postgres/Supabase schemas, writes reversible migrations, configures RLS policies, syncs TypeScript types, optimizes queries/indexes, and advises on data modeling.
Designs PostgreSQL schemas with best practices for data types, constraints, indexing, partitioning, RLS, and performance optimization.
Share bugs, ideas, or general feedback.
Enforce transaction safety, type safety, and naming conventions to prevent data corruption and runtime errors.
Core principles:
Methods that START transactions:
Methods that PARTICIPATE in transactions:
What DOES NOT count as "starting a transaction":
onConflictDoUpdateDefault: ULID stored as UUID
Exceptions (context-dependent):
Rule: If unsure whether data will be user-visible, use ULID.
Use exact decimal types (numeric/decimal) for monetary values:
numeric(19, 4) for general financial dataWhy: Floating-point types accumulate rounding errors. Exact decimal types prevent financial discrepancies.
ALWAYS type JSONB columns in your ORM/schema:
Record<string, unknown> if truly schemalessWhy: Prevents runtime errors from accessing undefined properties or wrong types.
Maintain separate client types at compile time:
Why: Prevents accidental writes to replica, enforces deliberate mutation choices.
All database objects use snake_case:
user_preferences, order_itemscreated_at, user_id, is_activeidx_tablename_columns (e.g., idx_users_email)fk_tablename_reftable (e.g., fk_orders_users)Application code: Map to idiomatic case (camelCase in TypeScript, etc.)
Standard mixins:
created_at, updated_at timestamps on all tablesdeleted_at for soft deletion when neededtenant_id for multi-tenant tables (project-dependent)Proactive indexing:
Default isolation (Read Committed) for most operations.
Use stricter isolation when:
SELECT ... FOR UPDATE)Always use generate + migrate workflow:
Never use auto-push workflow in production.
| Mistake | Reality | Fix |
|---|---|---|
| "This is one operation, doesn't need transaction" | Multi-step operations without transactions cause partial updates and data corruption | Wrap in transaction with TX_ prefix |
| "Single atomic operation needs TX_ prefix" | TX_ is for explicit transaction blocks, not atomic operations | No TX_ for single INSERT/UPDATE/DELETE |
| "UUID is just a string" | Type confusion causes runtime errors (wrong ID formats, failed lookups) | Use strict UUID type in language |
| "I'll type JSONB later when schema stabilizes" | Untyped JSONB leads to undefined property access and type errors | Type immediately with known fields or Record<string, unknown> |
| "Read client vs write client doesn't matter" | Using wrong client bypasses separation, allows accidental mutations | Use read-only client by default, switch deliberately |
| "I'll add indexes when we see performance issues" | Missing indexes on foreign keys cause slow queries from day one | Add indexes proactively for FKs and common filters |
| "This table won't be user-visible, use serial" | Requirements change, IDs leak in logs/URLs/errors | Use ULID by default unless certain it's internal-only |
| "Float/double is fine for money, close enough" | Rounding errors accumulate, causing financial discrepancies (0.01 differences multiply) | Use numeric/decimal types for exact arithmetic |
Transaction management:
.transaction() but no TX_ prefixTX_ prefix but accepts executor parameterType safety:
Schema:
created_at/updated_at timestampsAll of these mean: Stop and fix immediately.