データベースとマイグレーション
PostgreSQL の運用先を選び、実行中のアプリを壊さず Drizzle の変更をリリースします。
スターターのコミット
2a1a04aで検証済みです。
このページを終えると、各環境で使う DB、スキーマ変更をレビュー可能な SQL にする方法、アプリのリリースとは分けて適用する方法が分かります。
スターターは複数の DB アダプターを用意せず、PostgreSQL と Drizzle を採用しています。ローカルでは pnpm setup で Docker 上の PostgreSQL を使えます。本番では、互換性のあるマネージド PostgreSQL または自社運用の PostgreSQL を選び、DATABASE_URL を設定します。src/db/schema.ts がスキーマの正本で、src/db/migrations/ にコミットされた SQL がデプロイ履歴です。db() を呼べるのは src/models/** だけです。
ローカル手順
pnpm setup は開発用とテスト用の DB を分けて作ります。テスト DB の名前には test が必要で、安全機構はそれ以外の DB の全行削除を拒否します。
スキーマ変更後:
pnpm db:generate
pnpm db:lint
pnpm db:migrate
pnpm test:db:setup
pnpm test:db生成された SQL と meta/_journal.json をコードと一緒にコミットし、デプロイ済みのマイグレーションは編集しません。
本番手順
アプリのデプロイ時にマイグレーションは自動実行されません。DB とアプリを別々に監視し、再試行し、リリースできるようにする既定の安全策です。
pnpm db:check:prod
pnpm db:migrate:prod
pnpm db:integrity本番用の実行処理は、非対話で PostgreSQL のアドバイザリーロックを取得し、チェックサムを検証します。先にバックアップを取り、スキーマとアプリを別々にリリースしても新旧コードの両方が動く、追加してから削除する段階的な変更にします。
データ規約
- 数値
idは内部用、公開 API はuuidを使います。 - 金額は最小通貨単位の整数と通貨コードで保存します。
- テナントに属する行は
org_uuidを持ち、すべてのモデルクエリで組織を限定します。 - 冪等性キーと取引番号は、DB の一意制約で守ります。
- Account erase が不可逆 pseudonym を使うため identity relation は論理的です。Task-ledger、job、output file の重要関係は foreign key で保護され、削除順は lifecycle service が担います。
- 予約では PostgreSQL の排他制約も使い、仮押さえ・確定済みの時間枠が重複するのを防ぎます。
本番前に決めること
- マイグレーションを CI のリリースジョブと運用担当者のどちらが実行するか決めます。各 Web インスタンスからは実行しません。
- データの価値に見合うバックアップ・復元方針を決めます。マイグレーションロックはバックアップの代わりではありません。
- Relation 変更前後に
db:integrityを実行します。Migration linter は破壊的 drop、危険な rename、無制限 rewrite、blocking unique index を説明なしでは拒否します。 - 無停止を目指す場合は、追加してから削除する段階的な変更を優先します。破壊的な一段階の名前変更は簡単ですが、スキーマとコードのリリースを結合し、ロールバックを危険にします。
pnpm db:check:prod が予想どおりの未適用一覧を示し、バックアップが最新で、ステージング環境の複製で検証済みであり、展開中に旧・新両方のアプリ版が動くなら、本番マイグレーションの準備は完了です。
本番データの契約を変える前に、スターターの docs/database.md と DEPLOYMENT.md を読んでください。コードの置き場所はアーキテクチャとエラー契約、認証用 ID と公開 ID の区別は顧客認証で確認できます。