Prod db surgical
Skill webdevtodayjason/dev-kit/plugins/dev-kit/skills/prod-db-surgical
Portable Claude Code dev workflow — skills, commands, agents, security hooks, and a CLAUDE.md template. One-install onboarding; ships zero credentials.
npx -y skills add webdevtodayjason/dev-kit --skill prod-db-surgicalAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 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
Hard rules for working with a production database. Triggers when the user says "production database", "prod database", "prod DB", "live database", or when any database-modifying command (`prisma db push`, `prisma migrate`, `ALTER`, `DROP`, `UPDATE`, `DELETE`, `CREATE INDEX`, etc.) is being considered against a `DATABASE_URL` that resolves to production. Encodes the hard lesson that a stale-branch `prisma db push --accept-data-loss` can silently drop a column with live data. This skill prevents that pattern from recurring by mandating surgical, single-statement, idempotent SQL with explicit per-operation confirmation for anything destructive.
SKILL.md
9.3 KB, ~2.1k tokens by cl100k_base, as published. Nobody here has run it
Production Database — Surgical Operations Only
A production database is one row, one query, one column-change away from unrecoverable damage. Stale branches, smart-looking flags, and "this is additive, safe" assumptions are how that damage happens. This skill exists to slow down JUST enough to never repeat that kind of incident.
Core principle
Every prod-DB modification is one explicit SQL statement, reviewed before it
runs. Not "a Prisma push that figures it out." Not "the schema is already
correct, just sync it." A single ALTER / INSERT / UPDATE / DELETE,
written down, shown to the user, executed as that exact statement.
The hard rules
1. Never run these against prod without explicit per-operation approval
| Forbidden by default | Why |
|---|---|
prisma db push | Reconciles ENTIRE local schema against the DB. If the local schema is stale or branched from an older base, every diff is silently applied. The project's package.json scripts often have --accept-data-loss baked in, which makes destructive drops happen without prompting. |
prisma migrate dev | Generates and applies migrations. Touches the DB even in "dev" mode if DATABASE_URL points at prod. |
prisma migrate deploy | Applies pending migrations. Acceptable ONLY when the migration was generated against a known-clean dev DB and reviewed. |
--accept-data-loss flag | Never. If destruction is required, run the destructive SQL surgically as a separate step. |
DROP TABLE, DROP COLUMN, ALTER ... DROP, TRUNCATE | Each requires explicit user confirmation in chat for that exact statement. |
UPDATE / DELETE without WHERE | Reject categorically. Even "I want to clear all X" goes via a per-row review. |
UPDATE / DELETE with WHERE matching > 1 row | Confirm row count first via a SELECT COUNT(*) with the same WHERE; show the user. |
2. Branch-base check before ANY prod-DB-touching command
Before running anything against prod:
- Check the current local schema is what the user thinks it is:
git rev-parse HEAD git log --oneline origin/main..HEAD git log --oneline HEAD..origin/main - If the local branch is missing commits from
origin/main, STOP. The local schema is stale. Adb pushfrom a stale branch will roll the prod schema BACKWARD, dropping columns/tables that recent merges added. - Surface the staleness to the user. Recommend rebasing first, OR using the surgical alternative below (which doesn't depend on local schema).
3. Prefer surgical raw SQL over schema diff
For single-column / single-index / single-row changes, write the exact SQL and execute it directly. Do NOT use prisma db push or prisma migrate.
Use prisma db execute --stdin --url $DATABASE_URL (built into the project, reads SQL from stdin):
echo 'ALTER TABLE "Document" ADD COLUMN IF NOT EXISTS "renderedHtml" TEXT;' \
| npx prisma db execute --stdin --url "$DATABASE_URL"
This:
- Touches ONLY the named table/column
- Has no schema-diff side effects
- Doesn't need
--accept-data-loss - Is idempotent if you use
IF NOT EXISTS/IF EXISTS
If psql is installed locally that also works; the prisma db execute --stdin path works without any external CLI.
4. Idempotency clauses are mandatory
Every DDL statement gets:
CREATE TABLE IF NOT EXISTSCREATE INDEX IF NOT EXISTSALTER TABLE ... ADD COLUMN IF NOT EXISTSDROP TABLE IF EXISTS(when authorized)DROP INDEX IF EXISTS
So the same SQL is safe to re-run if the first execution hung or partially failed.
5. Verify the change took effect
After ANY prod-DB write, run a verification query that depends on the modified surface. Don't trust "Script executed successfully" — that just means the connection worked.
For a column add, query the column:
npx tsx -e "
import { PrismaClient } from '@prisma/client';
const p = new PrismaClient();
p.document.findFirst({ select: { id: true, renderedHtml: true } })
.then(r => console.log('✅', r))
.catch(e => { console.error('❌', e.message); process.exit(1); })
.finally(() => p.\$disconnect());
"
For an index add, run an EXPLAIN on a query that should use it. For a row update, re-SELECT the row and confirm the new value.
6. Backup check before destructive operations
Before any operation that COULD lose data (DROP, ALTER COLUMN with type change, UPDATE/DELETE matching > 0 rows, schema rollback):
- Confirm the provider's automated backups cover this DB and are recent
- Railway: dashboard → service → Backups (paid tier has automated; free tier may not)
- Supabase: dashboard → Database → Backups
- Self-hosted: check the cron / script writing to S3/disk
- Surface the latest backup timestamp to the user
- Get explicit per-operation approval
If the backup check is unclear, halt and surface the gap. Do NOT proceed with the assumption that backups exist.
7. Single statement per execution
Don't bundle "add column AND drop table AND modify enum" into one stdin payload. One statement per command. Each verified independently. Easier to roll back, easier to debug if one fails mid-batch.
8. Document every prod-DB change
After execution, write to a durable runbook (whichever this project uses):
ORCHESTRATION.mdfor active orchestrator sessionsops/runbooks/prod-db-changes.mdif the project has one- A new entry in
lib/changelog.tsif the change is user-visible
Each entry: timestamp, what changed, the exact SQL run, who authorized, the verify result. So six months from now, when someone asks "when did this column appear", it's answerable.
Decision tree when asked to do a prod-DB operation
Is this against prod (DATABASE_URL points at production)?
├── No → normal dev rules apply, this skill doesn't bind
└── Yes
├── Is the request a `prisma db push` or `prisma migrate`?
│ └── REFUSE by default. Counter-propose the surgical equivalent.
│ Only proceed with explicit user override after surfacing the risk.
│
├── Is it surgical raw SQL (single ALTER/INSERT/UPDATE/SELECT)?
│ ├── Read-only (SELECT, EXPLAIN, \d): execute freely
│ ├── Additive (ADD COLUMN, CREATE INDEX, INSERT new row): write
│ │ the SQL with IF NOT EXISTS, show to user, execute on go-ahead
│ └── Destructive (DROP, UPDATE, DELETE, ALTER ... DROP):
│ 1. Run the equivalent SELECT to show what's about to be touched
│ 2. Show the user the SQL + the affected row count + the backup
│ status
│ 3. Wait for explicit per-operation chat confirmation
│ 4. Execute. Verify. Document.
│
└── Is the local working tree clean and on a known commit relative to
origin/main?
├── Yes → proceed
└── No → surface the staleness; the user must confirm the
mismatch is intentional before any DB write
Anti-patterns to call out by name
When the user (or another agent) suggests these, refuse and counter-propose:
- "It's just a schema sync, prisma db push is fine" → No. Use raw SQL.
- "The change is additive, no risk" → Verify by writing the exact SQL. Don't trust the framing.
- "Use --accept-data-loss, the table is empty" → Drop the table
surgically:
DROP TABLE IF EXISTS "Foo";after confirming row count. Don't conflate "accept-data-loss" with "no data to lose". - "It worked locally, push to prod" → Local DB and prod DB diverge in ways your local tests don't cover (rows, indexes, extensions, perms). Always surgical.
- "I'll create a migration to handle it" → Migrations are for versioned schema evolution with code review. For one-shot fixes, surgical SQL is faster and clearer.
What this skill never does
- Run prod-DB operations autonomously without per-operation user approval
- Trust
--accept-data-lossto mean "no real data" - Assume a branch is up to date; always check
- Skip the verify step
- Skip documentation
Trigger phrases (what gets you here)
- "production database", "prod database", "prod DB"
- "live database"
- The user pointing at a
DATABASE_URLenv value clearly tied to prod - Any
prisma db push/prisma migrate/ALTER/DROP/UPDATE/DELETEcommand being considered for execution against an unknown DB — verify it's not prod before proceeding; if prod, this skill applies
When this skill activates, the next response to the user states:
Operating under prod-DB-surgical rules. Single-statement, idempotent SQL. Explicit per-operation approval for anything destructive. Show SQL before execute. Verify after. Document on completion.
…then proceed within those rules.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.
Gives 0 of the 12 instructions most databases sql skills give in ~2.1k tokens
Counted across 589 of the 662 authors here whose files we hold, read 2026-08-07
- Use parameterized queriesin 37 of 589, across 34 files
- Use timestamptz for timestampsin 30 of 589, across 14 files
- Index foreign keysin 29 of 589, across 18 files
- Create indexes concurrentlyin 29 of 589, across 24 files
- Use numeric type for moneyin 25 of 589, across 8 files
- Use cursor pagination instead of offsetin 24 of 589, across 17 files
- Select only required columnsin 24 of 589, across 20 files
- Add indexes manually on foreign key columnsin 22 of 589, across 12 files
- Normalize to third normal formin 19 of 589, across 10 files
- Configure connection poolingin 19 of 589, across 17 files
- Put equality columns before range columns in indexesin 18 of 589, across 10 files
- Read individual rule files for detailed explanationsin 18 of 589, across 4 files
Said here and by no other author read
- execute single explicit SQL statements only
- prefer raw SQL over schema diff tools
- make all DDL statements idempotent
- execute one statement per command
- check branch state against main before proceeding
- surface branch staleness before executing database writes
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.