Tech Blog

設計を実装でぶれさせない運用 — 乖離管理表と実装差分タスク一覧で「正本」を守る

設計 ドキュメント 運用 プロジェクト管理 三点突合

この記事でわかること

  • 「設計と実装が乖離する」問題を、設計書を消すことなく管理し続ける運用方法
  • 乖離ID(DVG-XXX)と課題票ID(TASK-XX)を紐づけて追跡する書式
  • 基本設計 / 詳細設計 / API設計の 三点突合表 で矛盾を検出するゲートの作り方

対象読者

  • 設計書を作ったものの「実装が先走って設計と合わなくなる」現象に困っている方
  • 設計を都度書き直すコストと、設計をメンテしないコストの間で悩んでいる方
  • ドキュメント運用に 検証コマンドを併走させる スタイルに興味がある方

動作環境

項目内容
ドキュメント形式Markdown
リポジトリ構成e-scooter-sharing-doc を別リポジトリで管理
検証ツールripgrep(rg

シリーズ記事(開発進行中) — この記事は 街中の電動キックボードシェアリングを自作して理解する — 設計・実装・運用の記録シリーズ の一部です。プロジェクトは現在も継続中で、新しい記事や設計判断の追記が随時行われます。プロジェクト全体の動機・採用技術・画面IDなどの用語表・他記事への索引はリンク先にまとめています。

はじめに

電動キックボードシェアリングプロジェクトでは、要件定義・基本設計・詳細設計・API設計を 正本 として維持する方針でスタートしました。

ところが実装が進むにつれ、画面遷移の細かい挙動・API のエンドポイント・ステータス名などが少しずつズレ始めます。よくある対処は2つ:

  1. 設計書を都度書き直す → 設計の意図が薄まる
  2. 設計書を放置する → 設計と実装が乖離して新メンバーが混乱

このプロジェクトでは どちらでもない第3の道 を採りました。

設計本文は正本として維持しつつ、現行実装との差分は「乖離管理表」で追跡する。

destination 画面 — 乖離 DVG-001〜DVG-004 を経て「解消」状態になった実装の現れ方

地図上のピンは「設計通りに API から取得 → グレー/紺で状態区別」が成立した姿。ここに至るまでに DVG-001〜DVG-004 の4件を乖離管理表で追跡しました。


乖離管理表(DVG-XXX)

30_ユーザーアプリ/002_詳細設計/乖離管理表(S01-S13).md を作って、画面ごとの乖離をテーブルで管理します。

| 乖離ID | 画面 | 設計期待値(正本) | 現行実装の事実 | 影響 | 暫定運用 | 課題票ID | 状態 |
|---|---|---|---|---|---|---|---|
| DVG-001 | S01 | 初期化時に GET /api/v1/ports で初期ポートマスタを取得 | 初期取得を実装済み | 初回表示の遅延を解消 | なし | TASK-A4 | 解消 |
| DVG-002 | S07 | S04状態ガードで未合格時に S07 へ遷移 | S07画面/導線/API送信を実装済み | 利用開始条件の運用依存を低減 | なし | TASK-B1 | 解消 |

ルール:

  • 乖離は消さない。状態を「未着手 / 進行中 / 解消 / 設計変更合意済み」のいずれかに更新するだけ
  • 設計本文(正本)は触らない。乖離管理表でだけ事実を残す
  • 設計変更合意済み だけは、正本側を書き換えてよい

この書式の効果は、「実装が設計から離れた事実」がドキュメントとして残る こと。設計を書き直すと履歴が消えるが、乖離管理表は何が起きたかの記録になります。


実装差分タスク一覧(TASK-XX)

乖離を解消する実装作業は 30_ユーザーアプリ/002_詳細設計/実装差分タスク一覧(app-api).md に課題票として管理します。

### A-1 状態ガードの共通化
- 対象: app
- 内容: RouteGuardService.determineNextRoute() を実装し、S05->S08->S09 の遷移判定を1箇所に集約する。
- 受入条件:
  - S04の「乗車手続きへ」から共通ガードを必ず通る。
  - 判定順が設計書と一致する。
- 状態: 解消(2026-05-23 / app commit: 34f9009)

「優先度A(早期に解消)」「優先度B(次フェーズ)」「優先度C(品質向上)」で並べ替え、課題票IDを乖離IDと相互参照させる。

完了報告は 「実装」「テスト」「設計更新」の3点セット で記録するルールにしています。

内容
実装コミットID(例: 34f9009
テスト受入条件の達成証跡(テスト合格、画面確認など)
設計更新乖離管理表の状態を「解消」に変更したことの記録

三点突合表(基本設計 / 詳細設計 / API設計)

S01〜S13 の各画面について、3つの設計成果物の整合性をテーブルにします。

画面基本設計詳細設計API設計判定
S05OTP送信 / 検証sendOtp(phone), verifyOtp(phone, code)POST /auth/send-otp, /auth/verify-otpOK
S10lock-toggletoggleLock(rentalId, requested)POST /rentals/{rental_id}/lock-toggle部分一致(将来実装)

「判定」で 「OK / 部分一致 / 設計変更必要 / 実装変更必要」 のいずれかを書き、部分一致以下は乖離IDを発行して乖離管理表に登録します。

「ここで返却」非活性 — 設計の「返却枠ありポートのみ操作可」を実装で表現した例

たとえばこの「満杯ポートで『ここで返却』が非活性」は、設計時点では「設計期待値: 返却可否でボタン活性を切替」、API設計では「available_empty_slots を返す」、詳細設計では「子画面でボタン活性ロジック」と3軸で書かれていたものが、実装後に三点突合表で OK 判定された状態の姿です。

ここで重要なのは:

  • API設計は エンドポイントの文字列レベル で正本
  • 基本設計と詳細設計は 業務上の振る舞い で正本
  • 三点突合表は 3つの軸が同じ事実を指しているか を確認する場

実装側で /api/v1/foo/api/v1/bar に変えるなら、API設計の「正本」を書き換える前に、三点突合表で他2軸も同じ事実を指すように合意を取り直す。これが設計をぶれさせない仕組みの心臓部です。


検証ゲートと ripgrep

乖離管理表が増えてくると、人手で「全部解消されているか」を確認するのは現実的でなくなります。そこで検証ゲートを設置:

# Gate A: 非OLDで /api/v1 なしの主要パスが残っていないか
rg -n "`(GET|POST|PATCH|PUT|DELETE) /(auth|users|ports|scooters|rentals|payments|ekyc)" 00_共通 20_API 30_ユーザーアプリ --glob "!**/OLD/**"

# Gate B: 差分注記が必要な主要語の存在確認
rg -n "実装差分注記|未実装|将来実装" 30_ユーザーアプリ

# Gate C: 三点突合表とタスク一覧の整合確認
rg -n "S10|部分一致|将来実装" 30_ユーザーアプリ/002_詳細設計

Gate A は 古い API パスが本文に残っていないか の検出。/api/v1 プレフィックス無しのエンドポイント表記を見つけたら、設計時点の表記揺れか、移行漏れか。

Gate B は 差分注記が必要な未実装項目 の網羅性チェック。

Gate C は 「部分一致」「将来実装」などの判定が乖離管理表とタスク一覧の両方で同じ意味で使われているか を見ます。

これらを CI に組み込んでもいいですし、手動で rg を叩いて目視確認しても OK。重要なのは 「ゲートが存在する」事実 で、設計のメンテをサボると検出される仕組みになっていること。


OLD ディレクトリで履歴を残す

設計を整理し直すとき、古い設計を「削除」せず OLD/ ディレクトリに移動します。

30_ユーザーアプリ/
├─ 001_基本設計/
├─ 002_詳細設計/
│   ├─ OLD/
│   │   └─ 旧・決済フロー設計.md
│   ├─ 決済フロー設計(正本準拠).md
│   └─ 乖離管理表(S01-S13).md

Gate A の --glob "!**/OLD/**" で OLD は検出対象から除外。生きてる設計だけを検証し、歴史は手元に残す。


学び

  • 設計と実装の乖離は 「無くす」のではなく「見える形で管理する」 方が現実的
  • 乖離管理表 / 実装差分タスク一覧 / 三点突合表は 役割が違う3つの軸 で、相互参照で正本を守る
  • 検証は ripgrep ベースの軽量ゲート で十分機能する(CI 必須ではない)
  • 設計を消さない代わりに、OLD ディレクトリに退避することで歴史を残せる

設計書は「絶対に正しい教科書」ではなく、「正本として扱うことで判断の中心に置ける道具」。それを守るための運用が、このプロジェクトでは乖離管理表と三点突合表になりました。

気軽にメッセージください

技術相談・ご感想・ご質問があればメッセージをお願いします。