Webアプリのフレームワーク移行計画で抜けがちな観点
まとめ
- 移行計画のレビューで効くのは、コスト試算の数字の細かさより「致命的になりうる構造リスクが設計に入っているか」
- 1つのDBを新旧2つのORMで共有する期間が一番あぶない。不変条件がアプリ層にしかないとサイレントなデータ破損になる
- CSRF・認証・ジョブ基盤の切替は、移行期間中の新旧併存でこそ事故る
- ROIは並走期間の二重コストと再診断費を入れないと前提が反転する。撤退ラインの無い移行は引き返せなくなる
レビューしてて引っかかったこと
成熟したサーバサイドフレームワークで育ったプロダクトを、モダンなJS/TSスタックへ段階移行する計画書を読む機会があった。型安全にしたい、ドメインが複雑になってきた、採用も考えたい、という動機自体は妥当だと思う。技術選定もORM・ジョブキュー・E2E・フォームバリデーションと、一通り主流から外れていない。
ただ読んでいて気になったのが、「移行する/しない」を決める材料としてコスト試算が前面に出ているわりに、移行を実際に殺しかねないリスクがほとんど書かれていないことだった。数字の精度より、ここが抜けてるほうが怖い。自分が踏んだことのあるやつも含めて、抜けがちな観点を4つ書いておく。
観点1: 1つのDBを2つのORMで叩く期間
「DBスキーマは変えない。移行期間は新旧アプリで同じDBを共有する」とよく書いてある。ラクそうに見えて、実はここが移行で一番難しい。
この手の成熟したフレームワークだと、整合性はDBじゃなくてアプリ層に乗っていることが多い。バリデーション、コミット後のコールバック、楽観ロック、カウンタキャッシュ、監査ログ系の仕組み、モデルに埋め込まれた状態遷移。このへんは全部アプリのコード側の話だ。
新しいORMから同じテーブルに書くと、これを全部すっ飛ばして書ける。金額・権利・台帳みたいに「壊れても気づかないまま伝播する」データでこれをやると、静かにデータが壊れる。気づいたときには手遅れ、というやつ。
スキーマの所有権もある。マイグレーションをORM側にも持たせると、どっちがスキーマの正なのか曖昧になる。双方のスキーマ定義がじわじわズレて、共存期間中ずっとランタイムエラーの種になる。
潰し方はそんなに複雑じゃない。
- 書き込みはどっちか片方の系統だけに寄せる(読みは両方でいい)
- 不変条件をDB制約か、両系統から呼べる共有サービス層に降ろす
- スキーマの所有権を片方に固定して、もう片方は読み取り専用のスキーマ定義にする
このどれかを入れておかないと、移行が長引くぶんだけリスクが積み上がる。
観点2: 移行期間のCSRF・認証・セッション
「SameSite=Strict なら CSRF 対策は要らない」を額面通り受け取るのは危ない。SameSite はブラウザ依存の挙動があるし、サブドメイン経由のバイパスや古いブラウザの穴もある。フレームワークの組み込みCSRF保護が一部のエンドポイント(サーバアクション相当)だけに効いて、APIルートは自前で守らないといけない、というケースもある。
認証の移行はもっと重い。認証ライブラリを乗り換えるとき、移行期間は新旧アプリでセッションやCookieを共有することになる。ここで互換性を見落とすと、ログアウト多発で済めばマシなほうで、最悪はクロス認証までいく。見落としがちなのはこのあたり。
- パスワードハッシュのフォーマット互換(コストパラメータ含む)
- 二要素認証の状態
- セッション固定対策
- アカウントロックアウトのカウンタ
外部のセキュリティ診断やペネトレを受けるプロダクトなら、ここはまず指摘される。計画段階で「新旧でセッションをどう共有するか」を1枚にしておいたほうがいい。
観点3: ジョブ基盤の切替と冪等性
ジョブ基盤を乗り換える計画はよくあるけど、「デプロイ中にジョブが走ってたら?」が小さなTODO扱いになってることが多い。本質はそこじゃなくて、キューごとに冪等性・実行保証・リトライの意味論が違うこと。
決済、本人確認、帳票生成、通知。こういう副作用のあるジョブが二重実行されると、二重送信や二重発行になる。移行期間に新旧両方のキューが動くなら、なおさら。
最低限、副作用のあるジョブには冪等キーを持たせて、「同じジョブが2回流れても結果は1回分」を移行前に保証しておきたい。
観点4: ROIの前提と撤退ライン
コスト試算そのものより、前提の置き方を疑ったほうがいい。楽観的になりがちなのはこの2つ。
ひとつは「セキュリティ診断は今後は差分のみで安く済む」。規制の厳しい外部パートナーや監査要件があると、新スタックの全面再診断を求められて一時費用が跳ねる。差分で済むかどうかは自分たちが決められない。
もうひとつは「初期投資は1年で回収」。新旧を並走させる期間は、両方のインフラ費と運用費が二重にかかる。これを入れると回収はだいぶ後ろ倒しになる。
年間削減の内訳も見ておきたい。「開発効率がN%上がる」みたいな仮定が削減額の大半を占めてるなら、それは実測じゃなくて期待値だ。確実に効く分(インフラ費やCI費の実額差)と、前提次第の期待分は分けて出したほうがいい。そのほうが意思決定として誠実だし、後でツッコまれにくい。
で、一番抜けてるのがこれ。ロールバック手順、カットオーバーの判定基準、撤退ライン、移行成功の定量基準が計画書に無い。年単位のシステム移行で撤退ラインが決まってないと、途中で詰んでも引き返せないデスマーチになる。技術というよりプロジェクト設計の話で、ここが抜けてると他がどれだけ精緻でも危うい。個人的にはこれが一番こわい。
おわりに
移行の方向性自体は、動機が妥当なら止める必要はないと思う。問題は、移行を殺しかねない「新旧併存中のデータ整合性・認証・ジョブ」と「前提が反転しうるROI・撤退ラインの不在」が設計から抜けてるとき。逆に言えば、この4つを設計で潰せていれば、移行計画としてはだいぶ地に足が付く。