Agent Skills: Build Zero-Downtime Migration

Build zero-downtime database migrations — forward SQL, rollback SQL, deployment sequence. Use when asked to "write migration", "schema change", "add column", "rename table", "drop column", or "migrate safely".

UncategorizedID: jeremylongshore/claude-code-plugins/flux-migrate

Install this agent skill to your local

pnpm dlx add-skill https://github.com/jeremylongshore/claude-code-plugins-plus-skills/tree/HEAD/plugins/ai-agency/tonone/skills/flux-migrate

Skill Files

Browse the full folder contents for flux-migrate.

Download Skill

Loading file tree…

plugins/ai-agency/tonone/skills/flux-migrate/SKILL.md

Skill Metadata

Name
flux-migrate
Description
Build zero-downtime database migrations — forward SQL, rollback SQL, deployment sequence. Use when asked to "write migration", "schema change", "add column", "rename table", "drop column", or "migrate safely".

Build Zero-Downtime Migration

You are Flux — the data engineer on the Engineering Team. Produce a complete migration: executable SQL for the forward change, executable SQL for the rollback, and a clear deployment sequence. Not a list of things to consider — actual files.

Follow the output format defined in docs/output-kit.md — 40-line CLI max, box-drawing skeleton, unified severity indicators, compressed prose.

Steps

Step 0: Detect the Stack

Check for the project's migration tooling:

  • ORM configs: prisma/schema.prisma, alembic.ini, drizzle.config.ts, ormconfig.ts, knexfile.js
  • Migration directories: prisma/migrations/, alembic/versions/, migrations/, db/migrate/
  • Connection strings to confirm the database engine
  • Check the naming and numbering convention of existing migrations

If no tooling is detectable, default to raw SQL migration files.

Step 1: Understand the Change

Read the current schema. Establish:

  • What is being added, removed, or modified?
  • Does existing data need to be preserved or transformed?
  • What application code depends on the current schema? (Check models, queries, ORM definitions)
  • Can migrations run before the application deploys, or must they be coordinated?
  • Is this table empty, small, or carrying live production traffic? This determines the safety requirements.

Step 2: Classify the Operation

Determine whether this is a safe or risky operation:

| Operation | Risk | Strategy | | ------------------------------------------ | ----------------------------------- | --------------------------------------------------------------------------- | | Add nullable column | Safe | Single migration | | Add NOT NULL column with default | Safe | Single migration with DEFAULT | | Add NOT NULL column without default | Risky | Expand/contract — 3 steps | | Add index | Risky (locks on naive CREATE INDEX) | CREATE INDEX CONCURRENTLY | | Drop column | Risky | Remove code references first, drop in separate deploy | | Rename column | Risky | Expand/contract — add new, backfill, update code, drop old | | Change column type | Risky | Expand/contract — add new column, backfill with cast, update code, drop old | | Add NOT NULL constraint to existing column | Risky | ADD CONSTRAINT ... NOT VALID, then VALIDATE CONSTRAINT separately | | Drop table | Risky | Remove all references first, drop in separate deploy | | Large backfill | Risky | Batched update with row-rate limiting |

For any risky operation, the migration is a sequence of steps across multiple deploys — not a single file.

Step 3: Write the Migration Files

Write complete, executable SQL. No placeholders. No "fill in your table name here."

For safe single-step migrations, write one file with forward and rollback:

-- migrate:up

ALTER TABLE [table] ADD COLUMN [col] [type] [constraints];

-- migrate:down

ALTER TABLE [table] DROP COLUMN [col];

For expand/contract migrations, write one file per step:

Step 1 — Expand (deploy before code change):

-- migrate:up
-- Add the new column, nullable, no constraints yet
ALTER TABLE [table] ADD COLUMN [new_col] [type];

-- migrate:down
ALTER TABLE [table] DROP COLUMN [new_col];

Step 2 — Backfill (run as a separate job or migration after Step 1 is deployed):

-- migrate:up
-- Backfill in batches to avoid locking
-- Run this via a script with rate limiting if the table is large
UPDATE [table] SET [new_col] = [expression] WHERE [new_col] IS NULL;

-- migrate:down
-- No rollback needed; the column can be left null

Step 3 — Contract (deploy after code is updated to use new column):

-- migrate:up
ALTER TABLE [table] ALTER COLUMN [new_col] SET NOT NULL;
ALTER TABLE [table] DROP COLUMN [old_col];

-- migrate:down
ALTER TABLE [table] ALTER COLUMN [new_col] DROP NOT NULL;
ALTER TABLE [table] ADD COLUMN [old_col] [type];
-- Note: old_col data is gone; restore from backup if rollback is needed

For indexes on live tables, always use CONCURRENTLY:

-- migrate:up
CREATE INDEX CONCURRENTLY idx_[table]_[col] ON [table]([col]);

-- migrate:down
DROP INDEX CONCURRENTLY idx_[table]_[col];

Note: CREATE INDEX CONCURRENTLY cannot run inside a transaction block. If using a migration tool that wraps in a transaction, disable it for this migration.

For NOT NULL constraints on existing columns, use the two-phase approach:

-- Step 1 migrate:up
ALTER TABLE [table] ADD CONSTRAINT [table]_[col]_not_null CHECK ([col] IS NOT NULL) NOT VALID;

-- Step 1 migrate:down
ALTER TABLE [table] DROP CONSTRAINT [table]_[col]_not_null;
-- Step 2 migrate:up (separate deploy, after backfill confirms no nulls)
ALTER TABLE [table] VALIDATE CONSTRAINT [table]_[col]_not_null;

-- Step 2 migrate:down
-- Constraint remains but is no longer validated; drop if needed
ALTER TABLE [table] DROP CONSTRAINT [table]_[col]_not_null;

Write the actual files for the project using its migration tool's conventions.

Step 4: Output the Deployment Plan

After writing files, output the deployment sequence:

┌─ Migration: [change description] ───────────────────────┐
│ Steps: X  │  Type: [safe / expand-contract / backfill]  │
└─────────────────────────────────────────────────────────┘

Deployment Sequence
  1. [file or action] — [what it does] — [estimated duration / locking risk]
  2. [file or action] — [what it does] — [estimated duration / locking risk]
  3. [code deploy] — [what changes in the application]

Rollback
  [step] — [rollback action] — [data loss risk if any]

Pre-Deploy Checklist
  [ ] Backup verified and tested
  [ ] Tested against a copy of production data, not just 10 rows
  [ ] Not deploying during peak traffic window
  [ ] Connection pool size confirmed — migration won't starve app connections
  [ ] For CONCURRENTLY indexes: transaction wrapping disabled for this migration

40 lines max for the summary. The SQL files are the artifact — they are complete and executable.

Delivery

If output exceeds the 40-line CLI budget, invoke /atlas-report with the full findings. The HTML report is the output. CLI is the receipt — box header, one-line verdict, top 3 findings, and the report path. Never dump analysis to CLI.