Database schema designer
Self-hosted AI coding factory — sandboxed agents deliver tickets to merged code, gated by a human in a dashboard. Local-first, cost-transparent, human-in-the-loop.
npx -y skills add tmj-90/gaffer --skill database-schema-designerAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Use when designing new database tables from requirements, reviewing a schema for normalisation or performance issues, adding multi-tenancy, planning a breaking migration, or generating TypeScript/Python types from a schema. Triggers on "design the schema", "ERD", "table relationships", "schema migration", "normalise this", or "database model".
SKILL.md
4.8 KB, ~1.0k tokens by cl100k_base, as published. Nobody here has run it
Design schemas that survive production
Normalise first. Index for query patterns. Never sacrifice data integrity for convenience.
Design process
Step 1 — Requirements → Entities
Extract nouns from the requirement. Each noun that has attributes and participates in relationships is likely an entity. Resist making everything a single wide table.
Step 2 — Relationships
Identify cardinality before choosing the table structure:
| Relationship | Implementation |
|---|---|
| 1:1 | Foreign key on the less-common side (or same table if always loaded together) |
| 1:N | Foreign key on the N side |
| M:N | Junction table with FK to both sides; add attributes to the junction if needed |
Step 3 — Normalisation
Target 3NF for transactional data:
- 1NF — atomic values; no repeating groups; primary key identifies each row.
- 2NF — no partial dependencies (non-key column depends on the whole PK, not a subset).
- 3NF — no transitive dependencies (non-key column depends only on the PK, not on another non-key column).
Denormalise deliberately for read-heavy analytics tables — document the trade-off.
Standard conventions
- Primary key:
id(UUID v7 for distributed systems; BIGSERIAL for single-node). - Timestamps:
created_at TIMESTAMPTZ DEFAULT now(),updated_at TIMESTAMPTZ DEFAULT now(). - Soft delete:
deleted_at TIMESTAMPTZnullable — add a partial indexWHERE deleted_at IS NULL. - Audit trail: separate
audit_logtable withentity_type,entity_id,action,actor_id,changed_at,before,after. - Multi-tenancy:
tenant_idon every tenant-scoped table; composite primary key or FK constraint; RLS policy.
Index strategy
- Index every foreign key (databases do not do this automatically).
- Add composite indexes for the most common
WHERE col1 = ? AND col2 = ?patterns. - Partial indexes for filtered queries (
WHERE deleted_at IS NULL,WHERE status = 'active'). - Covering indexes (
INCLUDE (col)) to avoid heap lookups on hot read paths. - Drop indexes that are never used — they slow writes.
Migration safety
| Change | Safe? | Notes |
|---|---|---|
| Add nullable column | Yes | |
| Add NOT NULL with default | Risky on large tables | Add nullable, backfill, add constraint |
| Rename column | No | Add new, backfill, drop old — across deploys |
| Drop column | No | Mark unused, deploy, then drop |
| Add index | Yes (CONCURRENT) | CREATE INDEX CONCURRENTLY — never blocking |
| Change column type | No | New column + backfill pattern |
Steps
- Read the lore + existing schema.
search_lorefor ORM conventions, migration tool (Drizzle/Prisma/Alembic), naming rules, and existing patterns. Extend; don't contradict. - Extract entities and relationships from the requirements. Draw the ERD (Mermaid is fine) before writing DDL.
- Normalise to 3NF. Document any deliberate denormalisation.
- Write migrations. Use the repo's migration tool. Each migration: one logical change, reversible (
up/down), idempotent. - Add indexes. At minimum: every FK; composite for the top query patterns identified from the ticket.
- Generate types. Derive TypeScript interfaces or Python Pydantic models from the schema — do not hand-write them separately.
- Verify. Run migrations against a real database; confirm
EXPLAIN ANALYZEon the primary query patterns shows index scans, not sequential scans. Record evidence.
Review checklist
- 3NF achieved — no partial or transitive dependencies, or denormalisation is documented.
- Every FK indexed — check
pg_indexesor equivalent. - Migrations reversible —
downmigration exists and tested. - No blocking DDL — index creation uses
CONCURRENTLY; large table alterations use the add-backfill-constraint pattern. - Timestamps on every table —
created_at,updated_at. - Types generated — not hand-written from the schema.
Rules
- Never rename a column in a single migration on a live table — three-deploy pattern only.
CREATE INDEX CONCURRENTLYalways — blocking index creation on production tables is a SEV2.- Audit trail for every table that stores user-facing data with compliance implications.
Capture lore
ORM choice, migration tool, naming conventions, UUID strategy, and RLS policy are high-value schema lore — call suggest_lore with tags: [database, schema, migrations].
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.