はじめに
「マイグレーションを本番で実行したらエラーが出た」——マイグレーションをCI/CDでテストし、down/upの往復検証・本番前のdry-runを設計をClaude Codeに生成させる。
CLAUDE.mdに設計ルールを書く
## DBマイグレーションテスト設計ルール
### CI/CDでの必須チェック
1. マイグレーション適用(up)→ スキーマ検証
2. ロールバック(down)→ 元のスキーマに戻っているか確認
3. 再適用(up)→ 冪等性チェック
4. データマイグレーション(既存データへの影響テスト)
### 安全基準
- 実行時間 > 5秒: レビュー必須
- down()なし: デプロイブロック
生成される実装(抜粋)
// マイグレーションのup/down往復テスト
async testSingleMigration(migrationFile): Promise<MigrationTestResult> {
const schemaBefore = await this.getSchemaSnapshot();
// UP: 適用
execSync(`DATABASE_URL="${this.testDbUrl}" npx prisma migrate deploy`);
const schemaAfterUp = await this.getSchemaSnapshot();
// DOWN: ロールバック
await this.runDownMigration(migrationFile);
const schemaAfterDown = await this.getSchemaSnapshot();
// 元のスキーマに戻っているか確認
if (JSON.stringify(schemaBefore) !== JSON.stringify(schemaAfterDown)) {
return { success: false, error: 'Schema after rollback does not match original' };
}
// 冪等性: 再適用
execSync(`DATABASE_URL="${this.testDbUrl}" npx prisma migrate deploy`);
return { success: true, upDurationMs, downDurationMs };
}
// スキーマスナップショット(information_schema)
async getSchemaSnapshot() {
return {
tables: await db.$queryRaw`SELECT table_name, column_name, data_type FROM information_schema.columns WHERE table_schema = 'public' ORDER BY table_name, ordinal_position`,
indexes: await db.$queryRaw`SELECT indexname, tablename, indexdef FROM pg_indexes WHERE schemaname = 'public'`,
};
}
// 本番前チェック: ロック操作を静的解析
const lockingPatterns = [
{ pattern: /ALTER TABLE .+ ADD COLUMN .+ NOT NULL/i, risk: 'HIGH', message: 'NOT NULL ADD will lock table' },
{ pattern: /CREATE INDEX(?! CONCURRENTLY)/i, risk: 'MEDIUM', message: 'Without CONCURRENTLY will lock table' },
];
for (const op of lockingPatterns) {
if (op.pattern.test(migrationSql)) {
checks.push({ risk: op.risk, message: op.message });
}
}
まとめ
- CLAUDE.md にup/down往復テスト必須・冪等性確認・実行時間5秒超でレビュー必須・downなしはデプロイブロックを明記
- スキーマスナップショット比較 でrollback後に元のスキーマに戻っているかをinformation_schema経由で自動検証
- データマイグレーションテスト でエッジケース(null値・複合名・大量データ)を事前に検証
- 本番前チェック でNOT NULL追加・型変更・インデックスなしCREATE INDEXを静的解析——大テーブルへの変更は推定時間も表示
DB設計のレビューは **Code Review Pack(¥980)* の /code-review で確認できます。*
みょうが (@myougatheaxo) — ウーパールーパーのVTuber。
Top comments (0)