skills/database-migration-manager/SKILL.md
Safe database migration manager for zero-downtime DDL changes and rollback plans. Activate on: database migration, schema change, DDL, rollback plan, zero-downtime migration, Prisma migrate, Drizzle kit, Flyway, column rename, table alter. NOT for: query optimization (use database-optimizer), ORM modeling (use data-pipeline-engineer), backup/restore (use devops-automator).
npx skillsauth add curiositech/windags-skills database-migration-managerInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Expert in safe, reversible database schema migrations with zero-downtime deployment strategies.
Activate on: "database migration", "schema change", "alter table", "add column", "drop column", "zero-downtime DDL", "rollback plan", "Prisma migrate", "Drizzle kit", "Flyway", "migration strategy"
NOT for: Query optimization → database-optimizer | ORM data modeling → data-pipeline-engineer | Backup/restore → devops-automator
| Domain | Technologies | |--------|-------------| | ORM Migrations | Prisma Migrate, Drizzle Kit, TypeORM, Sequelize | | SQL Migrations | Flyway, Liquibase, golang-migrate, dbmate, Atlas | | Zero-Downtime | Expand-contract, shadow columns, online DDL (pt-online-schema-change) | | Databases | PostgreSQL 17, MySQL 8.4, SQLite, CockroachDB, PlanetScale | | Safety | Rollback scripts, dry-run validation, lock timeout guards |
Phase 1 — EXPAND (deploy migration, app reads both):
├─ Add new column `full_name`
├─ Backfill: UPDATE users SET full_name = name
├─ Add trigger: sync writes to both columns
└─ Deploy app reading `full_name`, falling back to `name`
Phase 2 — MIGRATE (app writes to new only):
├─ Deploy app writing only to `full_name`
└─ Verify no reads/writes to old column (query logs)
Phase 3 — CONTRACT (remove old):
├─ Drop trigger
├─ Drop old column `name`
└─ Clean migration: one final migration file
-- migrations/20260320_001_add_email_verified.sql
-- FORWARD
BEGIN;
SET lock_timeout = '5s'; -- Fail fast if table locked
ALTER TABLE users
ADD COLUMN IF NOT EXISTS email_verified boolean
DEFAULT false NOT NULL;
CREATE INDEX CONCURRENTLY IF NOT EXISTS
idx_users_email_verified ON users(email_verified)
WHERE email_verified = true;
COMMIT;
-- ROLLBACK (in companion file or comment block)
-- BEGIN;
-- DROP INDEX CONCURRENTLY IF EXISTS idx_users_email_verified;
-- ALTER TABLE users DROP COLUMN IF EXISTS email_verified;
-- COMMIT;
Risk Level 1 (Safe): ADD COLUMN (nullable), CREATE INDEX CONCURRENTLY
Risk Level 2 (Caution): ADD COLUMN (with default), ADD NOT NULL constraint
Risk Level 3 (Danger): ALTER COLUMN TYPE, RENAME COLUMN
Risk Level 4 (Critical): DROP COLUMN, DROP TABLE
↓
Requires expand-contract pattern
ALTER TABLE acquires an ACCESS EXCLUSIVE lock. Without timeout, it queues behind long queries and blocks all subsequent queries. Always set lock_timeout.[ ] Migration has explicit rollback SQL
[ ] lock_timeout set for all DDL statements
[ ] CREATE INDEX uses CONCURRENTLY
[ ] Breaking changes use expand-contract pattern
[ ] Backfills run in batches (1000-10000 rows per batch)
[ ] Migration tested against production-volume staging data
[ ] No data loss — dropped columns backed up or archived
[ ] Migration is idempotent (IF NOT EXISTS / IF EXISTS guards)
[ ] Application code deployed before destructive phase
[ ] Monitoring dashboards checked during and after migration
[ ] Migration numbered/timestamped for ordering
[ ] Rollback tested independently on staging
tools
Building resilient distributed systems with circuit breakers, retries with full-jitter exponential backoff, retry budgets (per-request 3-attempt + per-client 10% ratio per Google SRE), deadline propagation, and the cascading-failure math (4 layers × 3 retries = 64x amplification). Grounded in Resilience4j, Microsoft Cloud Patterns, AWS Architecture Blog (Marc Brooker), and Google SRE Book.
testing
Designing HTTP cache headers that work correctly across browsers, CDNs, and shared proxies — `Cache-Control` directives per RFC 9111, `stale-while-revalidate` and `stale-if-error` per RFC 5861, the Vary header for varying responses, and surrogate keys for tag-based purging. Grounded in IETF RFCs and Cloudflare/Fastly docs.
development
Use when designing or fixing a Content Security Policy on a real site, choosing between nonce-based and hash-based CSP, adding strict-dynamic, debugging "Refused to execute inline script" errors, deploying CSP in report-only mode first, configuring report-to / report-uri, or auditing an existing policy for unsafe-inline / unsafe-eval / wildcards. Triggers: "CSP blocks legitimate inline script", strict-dynamic, nonce-{RANDOM}, sha256-{HASH}, object-src none, base-uri none, frame-ancestors, Trusted Types, X-Content-Security-Policy obsolete, report-only vs enforced. NOT for general HTTP security headers (HSTS, COOP/COEP), Trusted Types deep dive, CORS configuration, or building a WAF.
tools
Choosing and operating an HTTP API versioning strategy that doesn't break clients — Stripe's date-based pinned versions, the Deprecation/Sunset header pair (RFC 9745 + RFC 8594), URI vs header vs media-type approaches, and the version-transformer pattern. Grounded in Stripe's published architecture and IETF RFCs.