Claude Codeで挑む大規模レガシー移行:DDD適用と動作差ゼロの極意

AI・テクノロジー
STΛCKHUB ANALYSIS2026.07.19 00:00

「成功しても何も起きない」という究極のエンジニアリング

「成功しても何も起きない」――この言葉に、私はエンジニアとしての矜持と、同時に背筋が凍るようなプレッシャーを感じる。Luupのバックエンドチームが取り組んだ今回のレガシー移行プロジェクトは、まさにこの「観測可能な動作差を一切作らない」という極限の制約下で行われた。対象はユーザー特典に関わるドメインロジックであり、約38,000行の追加と約13,000行の削除、計232ファイルに及ぶ大規模なDDD(ドメイン駆動設計)Modules構造への移行である。このプロジェクトが特筆すべきは、AIエージェント「Claude Code」を単なるコード生成ツールとしてではなく、プロジェクトの「原則を維持する番人」として組み込んだ点にある。

我々エンジニアがレガシーコードと対峙する際、最も恐れるのは「意図せぬ副作用」だ。特に支払いロジックのようなクリティカルな領域では、リファクタリングのついでに行った「ちょっとした改善」が、数ヶ月後に致命的なバグとして顕在化することがある。今回のプロジェクトでは、このリスクを排除するために「mainと動作差ゼロ」を第一原則に掲げた。これは単なるスローガンではない。Firestoreの永続化形式、APIの入出力、計算結果に至るまで、外部から観測可能な挙動を一切変えないという、極めて厳格な制約である。この原則をClaude Codeのメモリに明文化し、セッションを跨いでもエージェントが同じ判断基準を維持できるようにした手法は、AIとの協業における一つのベストプラクティスと言えるだろう。

プロジェクトは7つのStacked PRに分割され、Strangler Figパターンを適用することで、段階的に新構造へ移行する戦略が取られた。特に興味深いのは、pr6で新コードがトラフィックを処理し始める際、万が一の事態に備えて即座にレガシー経路へ切り戻せるよう、永続化形式を一切変更しなかった点だ。もしここで「より良いスキーマ」への変更を強行していれば、切り戻しは不可能になっていたはずだ。技術的負債の返済において、理想的な設計を追求するあまり、ロールバックの安全性を犠牲にするという罠に陥るエンジニアは多い。しかし、彼らは「移行完了」の定義を「規約への準拠」と「動作の維持」に厳格に分離することで、この罠を回避した。これは、現場で泥臭く戦うシニアエンジニアだからこそ導き出せる、極めて現実的かつ賢明な判断である。

AIエージェントとの協業:検証と制御の技術

AIエージェントは強力な武器だが、同時に「親切心」という名のノイズを混入させるリスクを孕んでいる。今回の事例で最も示唆に富んでいるのは、Claude Codeが型を厳密にしようとして行った「undefinedからnullへの変更」が、Firestoreの永続化形式に影響を与え、動作差を生み出したというエピソードだ。これは、AIが「コードの品質」を向上させようとするあまり、「ビジネス上の要件(永続化の互換性)」を破壊した典型例である。我々エンジニアがAIを制御する際、単にコードを書かせるだけでなく、今回のように「原則を明文化してメモリに刻む」「意図的な差分をリストアップする」といった、人間側からのガバナンスが不可欠であることを物語っている。

検証手法においても、彼らは非常に泥臭く、かつ論理的なアプローチをとっている。特に「本番データの実測」による設計判断は、DDDの教科書的な理想論と現実のデータが衝突した際の素晴らしい解決策だ。DDDではEntity生成時にバリデーションを通すのが定石だが、過去のデータが現在のルールに適合する保証はない。そこで彼らは、Firestoreのcount() aggregationを活用し、不正な値を持つレコードが実在するかを低コストで調査した。結果、マスターデータ側は0件であることを確認し、ユーザー履歴側は実測が困難であることを明示した上で、検証をスキップする設計を選択した。この「測れるものは測り、測れないものはその事実を記録する」という姿勢こそ、推測でコードを書き換えて障害を誘発する若手エンジニアが最も学ぶべき教訓である。

また、プロジェクトの途中でClaude Codeのモデルが更新され、以前は見えなかった問題が検出されたという事実は、AI開発のスピード感を象徴している。長期プロジェクトにおいて、途中でモデルを乗り換え、過去の成果物を再検証するプロセスは、人間のチームでは決して得られない強力な武器となる。一方で、パフォーマンス面でのコールドスタート問題や、循環importの放置など、AIレビューをもってしても完全には排除できない課題も残されている。AIはあくまで「強力なレビュアー」であり、最終的な設計の責任を負うのは人間であるという事実は、今後も変わることはないだろう。以下の表は、今回の移行プロジェクトにおける検証体制の要点をまとめたものである。

検証手法 目的 具体的なアプローチ
特性テスト レガシー動作の固定 期限計算やシリアライズ結果をテストで固定し、リファクタリング前後で同値であることを保証
本番データ実測 設計判断の根拠 count() aggregationを用いて不正データの分布を調査し、バリデーションの要否を決定
意図的な差分リスト 変更の透明性 技術的に回避不可能な動作差をPRに明記し、レビュアーの判断を支援

レガシーと共存するDDDの未来への問い

今回のプロジェクトを通じて浮き彫りになったのは、「DDDの原則」と「レガシーシステムの現実」の間の深い溝である。彼らが採用した「create(新規作成時の厳格な検証)」と「reconstruct(永続化済みデータの寛容な復元)」というEntity生成経路の分離は、レガシーと共存するDDDの現実的な解として非常に洗練されている。しかし、これはあくまで「今のビジネスルール」と「過去の遺産」を切り分けるための対症療法に過ぎない。我々エンジニアは、いつまでこの「過去の負債」を抱えながら、新しい設計を継ぎ足し続けるべきなのだろうか。

AIの進化により、レガシーコードの解析や移行のコストは劇的に低下しつつある。ITmediaの調査でも指摘されている通り、COBOLや古いJavaの塩漬け状態をAIで打破し、数年かかる移行を数日に短縮できる時代が到来している。しかし、ツールがどれほど進化しても、システムが抱える「ビジネスロジックの複雑さ」そのものは消えない。むしろ、AIによってコードの生成速度が上がれば上がるほど、設計の整合性を保つための「人間による判断」の重要性は相対的に高まっている。今回の事例で、AIが作ったバグをAIレビューが検出するという「自作自演」の構図が見られたことは、AIが万能ではないことの証明であると同時に、検証体制の設計こそがエンジニアの新たなコアスキルになることを示唆している。

読者であるあなたに問いたい。あなたのプロジェクトにある「触り続けるコード」は、本当に今の構造のままで良いのか? そして、もし明日からAIを導入してリファクタリングを始めるとしたら、あなたは「mainと動作差ゼロ」を保証するための、どのような「原則」をエージェントに刻み込むだろうか? ツールに踊らされるのではなく、ツールを使い倒して「成功しても何も起きない」という完璧な移行を成し遂げるために、今すぐあなたのコードベースにおける「観測可能な動作」を定義し直すべきだ。AIは答えを教えてくれるが、その答えがあなたのビジネスにとって「正しい」かどうかを判断できるのは、現場の文脈を知り尽くしたあなただけなのだから。

Published at 00:00

コメント

タイトルとURLをコピーしました