AI(Claude)で5万行のコードベースを“色で読む”可視化ツールを作った話

5万行のコードベース可視化 AI活用術

「コードベースの全体像が誰にも見えない」「シナリオテストの網羅性が暗黙知になっている」――こんな悩みをAIコーディングで解決したいと思ったことはないでしょうか。

筆者はEC受注管理SaaSの巨大コードベース(Vue 3 + AWS Lambda + EC2 + CDK バッチ、計5万行超)を単一HTML 1ファイル + JSON 1ファイルで可視化するツールを、AI(Claude)と対話的に組み上げました。

この記事では、その実装過程・データ構造・苦労した点・段階的な作り方を、実物のスクリーンショット付きで詳しく紹介します。「AIと開発する」が単なるバズワードではなく、個人開発レベルでもこれだけのものが作れるという実例として読んでもらえれば嬉しいです。

tl;dr

  • 既存コードベース(Vue 3 SPA + AWS Lambda + EC2 + CDK batch、計5万行超)をJSON 1ファイル + HTML 1ファイルで可視化するツールを作った
  • パッケージ間フロー / シーケンス図 / データモデル / シナリオテスト網羅率の4ビューを1画面に統合
  • 「カバレッジ表示」をONにすると、テストで触れられていない箇所がマップ上で暗くなる
  • 未網羅 state を選ぶとGherkinテンプレと JSONテンプレを自動生成、類似シナリオも提示
  • 既存BDD .featureファイルを取り込み、Gherkin手順をビューワー内で参照できる
  • 最終的に flows.json + flows.html(数百KB)の2ファイル構成

なぜ作ったか

対象は EC事業者向け受注管理SaaS(Genesys互換APIや AI要約等の機能を含む)。次のような課題を抱えていました。

  • コードの全体像が誰にも見えない — フロントエンドはVue 3、APIはPython Lambda 100+関数、EC2常駐のWebSocketサーバー、CDKで書かれた夜間バッチ、DynamoDB単一テーブル設計の謎のPKプレフィックス群、OpenSearch index、IoT Core MQTT topic、Valkey/Redis、CloudFront署名URL、Cognito CUSTOM_AUTH…と部品が多い
  • 既存設計書はxlsx / PlantUML主体で、内容が更新されていない箇所もある
  • シナリオテストの網羅性が暗黙知になっていて、テスト計画の穴がレビューで見つかりにくい
  • BDD .featureで書かれた自動テストもあるが、コードベース全体のどの部分をカバーしているのか俯瞰できない

「マップを眺めて暗い箇所を見つけたら、それが未テストの場所」というツールが欲しかった。

全体像(実物スクリーンショット)

これが実際に動いているツールのスクリーンショットです。EC受注管理SaaSを題材にしたサンプル版で、本記事用に再現しました。

フローマップビューワー マップビュー(デフォルト表示)
マップビュー: パッケージ縦カラム + コンポーネントカード + state pill + ベジェ矢印

画面構成は以下の通りです。

  • ヘッダー(上部): フロー数・コンポーネント数・state数・シナリオ数のサマリ。ビュー切替ボタン、カバレッジ表示ON/OFFトグル
  • 左サイドバー: フロー一覧 + 選択中フローのステップ一覧
  • メインキャンバス(中央): パッケージを縦カラムとして並べたマップ。コンポーネントカードに state pill(緑=網羅済、赤=未網羅)が並ぶ
  • 右サイドバー: 集計サマリ(Flow Step / State / Entity Op 網羅率)と未網羅TOP3
  • 凡例(右下): 緑/赤/青の意味

ファイル構成はシンプルです。

sample/flow-map/
├── flows.html      ← 単体で開けるビューワー(JS + CSS + JSON全部入り)
└── flows.json      ← データ部分(git diffレビュー用)

flows.htmlをダブルクリックで開けば、サーバー不要・CDN依存なしで全機能が動きます。

5つのビュー

1. マップ(関係先 / 全体)

パッケージを縦カラムとして並べ、コンポーネント(画面・Lambda・テーブル等)をカードで表示。選択中フローのstepをベジェ矢印 + 番号バッジで結びます。

  • マップ(関係先): 選択フローに登場するコンポーネントだけを表示する集中モード
  • マップ(全体): 全コンポーネントを薄表示 + 関連分を強調する俯瞰モード

カードにはstate pillが並び、シナリオで触れられたstateは緑、触れられていないstateは赤で表示されます。「4/7」のような橙色バッジが目に入った瞬間に「3 state分テスト計画が足りない」が分かるUIです。

2. シーケンス

選択フローをUMLシーケンス図に変換。ライフライン上に番号付き矢印が引かれ、各矢印の上にGherkin手順を pill 付きで表示します。

3. データモデル

DynamoDB / OpenSearch / S3 / Valkey / IoT topicを別グループ化して全エンティティを一覧表示。各エンティティの右ペインに以下を表示します。

  • Fields表(型 / required / indexed / PIIフラグ)
  • Indexes(GSI / OpenSearch index)
  • Relations(他エンティティへの参照、N:1等)
  • Used by(このエンティティを読み書きするコンポーネント、クリックでMapに遷移)
  • 関連フロー(このエンティティを触るフロー、クリックでフロー詳細)
  • Notes(TTLや命名規則の備考)

4. シナリオ網羅

シナリオを一覧、選択時には集計カード3種(Flow Step / State / Entity Op 網羅率)、未網羅TOP3フロー、選択シナリオのGherkin手順(.feature由来)を表示します。

5. カバレッジ表示(ON / OFFトグル)

このツールの核となる機能です。右上のチェックボックスをONにすると、画面全体の見え方が変わります。

フローマップビューワー カバレッジ表示ON
カバレッジ表示ON: 未網羅の多いコンポーネントが暗くなる

具体的には:

  • 未網羅 step の矢印が灰色+点線、バッジも灰色化
  • state網羅率が低いコンポーネントは段階的に暗くなる
  • 100% → opacity 1.0(鮮明)
  • 50-99% → opacity 0.78
  • 1-49% → opacity 0.5 + saturate 0.6
  • 0% → opacity 0.3 + saturate 0.3(ほぼ消えかけ)
  • 緑/赤の枠線色で、網羅状況がカードレベルでも判別可能

「マップを眺めて暗い箇所を見つけたら、そこが未テスト」という体験がここで完成します。

state popup と Gherkin テンプレ自動生成

statesを持つコンポーネントをクリックすると、状態遷移ポップアップが開きます。

state popup 未網羅state一覧
state popup: 未網羅stateごとに3種類のアクションボタン

未網羅 state ごとに3種類のアクションがあります。

Gherkinテンプレ

押すと、その state を踏むためのテンプレを自動生成。プレビュー / ソース切替 + コピーボタン付きです。

Gherkinテンプレ自動生成
未網羅stateからGherkinテンプレを自動生成(コピー可)

ソース(コピー対象)はこんな形:

# 自動生成テンプレ — 「在庫補充バッチ」の未網羅 state 「実行中」 用
# language: ja
@draft
シナリオ: 在庫補充バッチ を「実行中」状態にする
  前提 在庫補充バッチ を表示できる前提条件を満たしている
  もし 〔実行中〕を発火させる操作を実施する  (要記入)
  ならば 在庫補充バッチ が「実行中」状態になっている

JSONテンプレ

flows.jsonscenarios[] に貼れる雛形:

{
  "id": "scn-restock-batch-running",
  "name": "在庫補充バッチ — 実行中 状態",
  "status": "drafted",
  "covers": {
    "componentStates": [
      { "componentId": "restock-batch", "stateId": "running" }
    ]
  }
}

類似シナリオ

スコア順(同コンポーネントを触る → BDD scenarios → 同パッケージ)で5件提示。クリックでGherkin stepsが展開され、書きぶりの手本になります。

データ構造(flows.json)

トップレベルは5配列のシンプルな構造です。

{
  "app": { "name": "...", "stackSummary": "...", "generatedAt": "2026-05-18" },
  "packages":    [ /* パッケージ → コンポーネント */ ],
  "flows":       [ /* フロー → ステップ */ ],
  "entities":    [ /* データエンティティ */ ],
  "scenarios":   [ /* テストシナリオ */ ],
  "bddFeatures": [ /* .feature 原典 */ ]
}

packages → components

{
  "id": "frontend",
  "name": "フロントエンド (Vue 3)",
  "components": [
    {
      "id": "checkout-page",
      "name": "決済画面",
      "type": "page",
      "subtitle": "新規/編集 兼用",
      "states": [
        { "id": "input", "label": "入力中" },
        { "id": "success", "label": "決済成功" },
        { "id": "failure", "label": "決済失敗" }
      ]
    }
  ]
}

scenarios

{
  "id": "scn-checkout-success",
  "name": "決済→注文確定 (正常系)",
  "status": "automated",
  "covers": {
    "steps": ["checkout-order"],
    "componentStates": [
      { "componentId": "checkout-page", "stateId": "success" }
    ],
    "entityOps": [
      { "entityId": "ent-order", "op": "create" }
    ]
  }
}

スキーマファイル(flows.schema.json、JSON Schema Draft 2020-12)で全フィールドの仕様を厳格化。id patternは ^[a-z0-9][a-z0-9._:-]*$ でkebab-case強制にしています。

実装ポイント(AIと一緒に踏んだ罠)

単一HTMLファイル化

最終形は数百KBのHTML 1つ。CSS / JS / データ全部入りです。

<script>
  // インラインで JSON を埋め込み
  const EMBEDDED_FLOWS = { /* flows.json の全データ */ };
</script>

利点:

  • ダブルクリックで開ける(CORS制約なし、httpサーバー不要)
  • Slack / メールで配布できる単体ファイル
  • オフライン完結(CDN依存なし)

全角文字の幅見積もり

ラベル背景pillの幅を「英字1文字6.2px」で計算していたら、日本語ラベル “メールアドレス・パスワードを入力して送信” が pill から完全にはみ出した――というのが最初の罠でした。

function estimateTextWidth(text, fontSizePx) {
  let w = 0;
  for (const ch of String(text || '')) {
    const code = ch.codePointAt(0) || 0;
    const isFullWidth =
      (code >= 0x3041 && code <= 0x33ff) || // ひらがな/カタカナ
      (code >= 0x4e00 && code <= 0x9fff) || // CJK Unified
      (code >= 0xff00 && code <= 0xff60);   // 全角
    w += isFullWidth ? fontSizePx * 1.05 : fontSizePx * 0.55;
  }
  return w;
}

その後 requestAnimationFramegetBBox() の実測値で再調整しています。

CSS specificity との戦い

box-shadow: inset で枠線色を変えていたら、後から書いた body.flow-active .component.in-flow { border-color: var(--accent) } の方がspecificityが高くて常に上書きされる罠。

/* 解決: 専用ハイライト用 specificity 確保 */
.component.has-uncovered-state {
  border-color: rgba(239, 71, 111, 0.55) !important;
  box-shadow: 0 0 0 1px rgba(239, 71, 111, 0.25);
}

描画順での隠れバッジ

矢印中央の番号バッジが、その上に置いたラベルpillに覆われて見えなくなるバグ。SVGは後にappendしたものが手前に来ます。

// 解決: 描画順を「path → label → badge → number」に変更

これでバッジが必ず最前面に来るようになりました。

JSDOMでの自動テスト

実ブラウザを起動せず、JSDOM環境で49項目を自動チェック。

const dom = new JSDOM(html, { runScripts: 'dangerously', pretendToBeVisual: true });
// ビュー切替 / クリック / キーボード / 検索 / popup / template生成 ... 全部自動検証

これで「リファクタリングしても回帰してない」を毎回確認できました。

【PR】

AIコーディングを副業の武器にしたいなら

買い切り型99,800円〜で実案件ベースで学べる。AI活用・Web制作・動画編集など副業直結カリキュラム。Claude Code等を使いこなして副業案件を獲得したい人に最適。

▶ デイトラのコース一覧を見る

シナリオテスト計画への活用フロー

これがツールの主目的だった部分です。

1. マップを眺める
       ↓
2. 暗いコンポーネント・薄い矢印を見つける
       ↓
3. 暗いコンポーネントをクリック → state popup が開く
       ↓
4. 未網羅 state が赤ピルで列挙される
       ↓
5. 「類似シナリオ」を押す → 既存BDDシナリオの書きぶりを参考
       ↓
6. 「Gherkinテンプレ」を押す → コピーして.feature に貼り付け
       ↓
7. 「JSONテンプレ」をflows.json scenarios[] に追加
       ↓
8. flows.html を再生成 → 先ほど暗かった state pill が緑に変わる
       ↓
   「テストが1つ増えた」ことが視覚的に確認できる

このサイクルを回すと、テスト計画レビューが「マップで赤いところを埋めていく」作業になり、レビュアー / 設計者 / テスト書く人 / 開発者が同じ画面で会話できるようになります。

段階的な構築の流れ

時系列で振り返ると、こんな流れでした。

Phase やったこと 成果物
1 コードベース調査(api/ frontend/ backend/ batch/) 構造把握
2 flows.json 初版作成 データ層
3 アップロードされたサンプルviewerをベースにHTML化 基本表示
4 ラベルホバー表示 / 左下サイドバー分割 / scrollToStep UX改善
5 番号バッジドラッグで矢印曲げ + localStorage永続化 カスタマイズ
6 DynamoDB / OpenSearch / S3 等を全エンティティとして抽出 データモデル
7 データモデルタブ追加(関連コンポーネント逆引き) データビュー
8 既存テスト仕様参照シナリオ + states定義 シナリオ層
9 シナリオ網羅タブ + カバレッジ計算 + 未網羅一覧 カバレッジ可視化
10 カバレッジオーバーレイ(暗さ表現) 視覚的網羅判定
11 state popup + Gherkin / JSONテンプレ自動生成 テスト計画支援
12 .feature 取込 → BDD scenarios 自動登録 BDD連携
13 左下3タブ化(ステップ / サマリ / コンテキスト) 情報密度向上
14 edit-page に states + 兼用副題追加 認識性改善
15 Gherkinテンプレに プレビュー / ソース切替 コピペ体験

別プロジェクトで再利用するには

flows.schema.json を汎用仕様にしてあるので、別プロジェクトでも次の手順で同等のものが作れます。

  1. flows.htmlflows.schema.jsonをコピー
  2. プロジェクトの構造に沿ってflows.jsonを作成
  3. flows.htmlEMBEDDED_FLOWS = {...} を新JSONで置換
  4. ダブルクリックで動作確認

最小限は app / packages / flows の3つ。データモデル可視化したいなら entities 、シナリオ網羅したいなら scenarios、BDD連動するなら bddFeatures + [BDD] scenarios を追加するだけです。

デメリット・注意点

正直にデメリットも書いておきます。

  • flows.json を手で編集してもHTMLには反映されない: HTML側にインラインで埋め込んでいるため、再生成が必要。CIで自動再生成するパイプラインがないと運用負荷が高い
  • 現状の網羅判定は「flows.json の宣言を信じている」だけ: 実際のテスト実行とは連動していない。Playwright実行結果との連携は別途必要
  • JavaScriptフレームワーク不使用: 素のDOM操作なので、機能追加でコードが膨らみやすい。チームで保守する場合はReact/Vue等への移植も検討
  • BDDシナリオのcovers.componentStatesは手書きが必要: 自動マッピング辞書を別途用意しないと、BDD取込だけでは網羅率が上がらない

これらをこなせる開発体力がチームにあるか、最初に確認してから着手するのが安全です。

よくある質問

Q1. これを作るのにどれくらい時間がかかった?

筆者の場合、AI(Claude)と対話的に進めて約2週間(うち実作業時間は20〜30時間程度)。試行錯誤を含めた数字なので、設計を固めて作れば10〜15時間で類似のものが作れると思います。

Q2. PlantUMLやMermaidじゃダメ?

PlantUML / Mermaidは「単一のフロー図」を描くのには優れていますが、複数のフロー・データモデル・テストカバレッジを1画面で横断的に見せる用途には弱いです。逆に言えば、ドキュメントとして1枚絵で済む用途ならPlantUML/Mermaidが手早いです。

Q3. AIにここまで作らせていいの?保守できる?

AIに「全部書かせて自分は読まない」だと保守不能になります。私の場合は機能ごとに動作確認しながら一緒に作っていくスタイルで、コードの構造は理解した状態を保ちました。設計判断は人間、実装の重労働をAIに任せるバランス感が大事です。

Q4. 商用プロジェクトでも使える?

サンプルはMITライセンス相当の汎用構造です。社内ツールとして展開するのは問題ありません。ただし、flows.jsonにデプロイ前のシステム設計情報が含まれるため、リポジトリ管理・配布範囲には注意してください。

まとめ

「コードベースを色で読む」体験は、想像以上に気持ち良いものでした。書いたコード行数からするとHTML 1ファイルだけですが、その中に5ビュー + 3タブ + 6種類のホバー/クリック動作 + Gherkinテンプレ生成 + BDD連携 + JSON Schema厳格化が全部入っています。

  • 既存ドキュメント(xlsx / PlantUML)は「正解だが古い」ことがある
  • コード自体は「最新だが読みづらい」
  • BDD .feature「実行可能だがコード全体との接続が見えない」

これら3つの隙間に「マップ上で色が変わる」という新しい言語を1つ足すと、関係者全員が同じ画面を見て会話できるようになります。

レビュアーは “緑が増えたね” と褒め、設計者は “この赤を埋めるシナリオが必要” と発見し、テスト書く人は “Gherkinテンプレからコピペで始められる” と楽できる――そんな効果を実感しました。

AIコーディングは、こうした「ニッチだけど刺さるツール」を個人レベルで作れる時代を本当に開いたと思います。「あれば便利だけど工数が見合わない」と諦めていた社内ツールを、今こそAIと一緒に作ってみてください。

関連記事

出典

コメント