レビュー結果 - ドメインモデル分析¶
レビュー対象¶
- ファイル:
tmp/国際貨物輸送システムのケーススタディ/ドメインモデル分析.md - 比較対象:
docs/strategy/business_architecture.md、docs/requirements/requirements_definition.md - レビュー日: 2026-03-31
- レビュー方式: マルチパースペクティブ(5 エージェント並列)
総合評価¶
JIG ツールによる既存 OSS(jakartaee/cargotracker)のドメインモデル分析として DDD パターンの適用精度は高く、Booking / Routing / Tracking / Handling / Shared Domain の 5 コンテキスト分割は本プロジェクトのビジネス境界と概ね整合する。
ただし本ドキュメントはオリジナル Cargo Tracker サンプルアプリの分析結果であり、本プロジェクト固有のビジネス要件(精算・税関・通知・荷主エンティティ・例外処理)への対応が未着手である。TransportStatus の 5 値と要件定義の 9 状態の乖離、集約ルートの誤分類、循環依存など実装フェーズで深刻な問題になる設計課題も複数ある。本プロジェクトのドメインモデル設計書として使用する前に、下記「高」優先度の指摘すべてを反映したプロジェクト固有版への書き直しが必要。
改善提案(重要度順)¶
高¶
| # | 提案 | 指摘元 | 理由 |
|---|---|---|---|
| H1 | TransportStatus を 9 値に拡張し要件定義の状態遷移と整合させる |
architect / designer / tester | IN_PORT が受領済・荷降し済・引取待ちを区別できず、受け入れテストの Given-When-Then が成立しない |
| H2 | 精算コンテキスト(Billing Context)を 6 番目のコンテキストとして追加する | PM / designer / user-rep | UC10〜12(料金算出・割引・精算)と外部システム「決済機関」連携を担うモデルが完全に欠落している |
| H3 | 荷主(Shipper)・荷受人(Consignee)エンティティを Booking Context に追加する | PM / designer / user-rep / tester | 法人割引判定・通知先・引取確認の起点が存在せず、5 件以上のユーザーストーリーが実現不可能になる |
| H4 | BookingId・TrackingNumber を値オブジェクトに格下げする |
architect / designer / tester | 識別子クラスが集約ルートになると、不要なリポジトリが増生し DDD の基本制約に反する |
| H5 | HandlingActivity.isValidFor(cargo: Cargo) を ACL 経由に変更する |
architect | Handling Context が Booking Context の Cargo 型に直接依存しており、コンテキスト境界を侵食している |
| H6 | Handling Context 内の循環依存(h_agg ↔ h_vo)を解消する |
architect / designer | HandlingActivityHistory(VO)が HandlingActivity(集約ルート)を参照する構造は DDD の根本的な制約違反 |
| H7 | BookingStatus 列挙型を追加し予約業務状態を表現する |
tester / PM | RoutingStatus(3 値)は経路設定状態であり、予約の業務状態(仮受付→経路提案中→予約確定→…)を表現できない |
| H8 | 税関(Customs)連携の ACL・概念をモデルに追加する | PM / architect | 国際貨物輸送の要件として税関が外部システムに明記されているが、モデルに通関関連の概念が一切ない |
| H9 | 例外概念(ExceptionEvent / ExceptionType)を Tracking Context に追加する | designer / tester / user-rep | US14(遅延)・US15(破損・紛失)の受け入れ基準を実装できない |
| H10 | HandlingActivity.isValidFor() の荷役タイプ別検証ルールを定義する |
tester | 何を検証しているか不明のため、単体テストの期待値が決まらない |
| H11 | BookingAmount の計算ロジック・通貨情報を明示する |
PM / architect / tester | US16(料金算出)のテストが書けない。Integer 型では多通貨・割引計算を表現できない |
中¶
| # | 提案 | 指摘元 | 理由 |
|---|---|---|---|
| M1 | Shared Domain の設計方針(共有カーネル vs ACL)を統一する | architect | Location を Shared Domain に置きながら各コンテキストで独自型(TrackingLocation 等)も定義しており、方針が混在している |
| M2 | Tracking ↔ Handling の双方向依存をメッセージブローカー経由に変更する | architect | 双方向依存は独立デプロイを妨げる。Handling → イベント発行 → Tracking が subscribe する一方向に整理 |
| M3 | TrackingBookingId を値オブジェクトに変更する |
architect | 識別子の保持のみを目的としており、エンティティとしての性質(状態変化・ライフサイクル)がない |
| M4 | 通知のドメインイベント(CargoStatusChangedNotification 等)を定義する |
PM / user-rep | CargoStatusUpdated が発生した後に誰に・どのように通知されるかのフローが存在しない |
| M5 | アクターとコンテキストの対応表を追加する | designer | 7 アクター(荷主・荷受人・営業担当者・経路設計者・追跡管理者・荷役作業員・経理担当者)がどのコンテキストを使うか不明 |
| M6 | 英語用語と日本語ユビキタス言語の対応表を追加する | designer | LOAD / UNLOAD / RECEIVE / CLAIM と「積込・荷降し・受領・引取」の対応が文書化されておらず、ビジネス担当者との認識齟齬リスクがある |
| M7 | 外部システム連携の ACL を Port として定義する | architect | 外部経路システム・税関・決済機関・港湾管理システムとの統合境界がモデル上に存在しない |
| M8 | CargoItinerary の Leg 制約(最小数・順序・時刻整合性)を明示する |
tester | 境界値テストの期待値が「Leg が 1 個の直行便は有効か」から始まって決まらない |
| M9 | TrackingActivity.currentStatus() の返却型 TrackingStatus を定義する |
tester | 戻り値の型定義が存在せず、TransportStatus と別物かどうかも不明 |
| M10 | 貨物種別(CargoType: 一般 / 危険物 / 冷凍)を Cargo 集約に追加する |
PM / architect | 貨物種別は荷役制約・ルート制約・料金計算に影響するビジネスルール。未定義のままだと「危険物を一般ルートで予約」などのビジネスバグが発生しうる |
| M11 | CargoStatusUpdated のイベント依存方向を逆転させる |
architect | Tracking が Booking を呼ぶ構造(tracking → booking)は Tracking が Booking に依存することを意味し、独立デプロイを妨げる |
| M12 | TrackingActivity・TrackingEvent(Entity と VO の重複)の役割の違いを明記する |
tester | フィールド構成がほぼ同一で 2 つが存在し、テスト時にどちらを検証すべきか判断できない |
低¶
| # | 提案 | 指摘元 | 理由 |
|---|---|---|---|
| L1 | 見積(Quotation / Quote)概念を Booking Context に追加するか判断する | PM / designer | US01「輸送見積作成」は業務の起点だが、Cargo 集約(予約確定後)から設計が始まっており見積段階が漏れている |
| L2 | UNKNOWN TransportStatus の設定トリガーを明示する |
tester | いつ UNKNOWN になるかの仕様がなく、テストの Given が書けない |
| L3 | BookCargoCommand 等の入力値検証ルール(UN/LOCODE 形式・日付範囲等)を明示する |
tester | バリデーションエラーの期待値が定まらない |
| L4 | CargoItinerary の用語「Leg → 輸送区間」を日本語対応表に追加する |
designer | US06「経由港」と Leg.unloadLocation の対応が暗黙的 |
| L5 | HandlingActivityHistory(VO)の不変性の扱いを明確化する |
designer | イベント追加のたびに変化するコレクションを値オブジェクトで表現することの矛盾を解消する |
矛盾事項¶
複数エージェントで相反する指摘はなし。主要な論点として以下を記録する。
| # | 論点 | 推奨判断 |
|---|---|---|
| 1 | Shared Domain を共有カーネルにするか各コンテキストが ACL で隔離するか | Location(UN/LOCODE)は変更頻度が低いため共有カーネルとして維持し、VoyageNumber 等は各コンテキストの独自型に統一することを推奨 |
| 2 | 精算は Booking Context の拡張か、独立した Billing Context か | 業務ルールの複雑さ(割引・税務・入金管理)と外部システム(決済機関)との境界を考慮し、独立した Billing Context を推奨 |
エージェント別フィードバック詳細¶
xp-product-manager(高: 7 / 中: 3 / 低: 2)
### 評価サマリー DDD の設計パターンは適切に適用されており、コア輸送業務(予約・経路・荷役・追跡)の骨格は概ね正しく表現されている。ただし、本プロジェクトのビジネス要件で明示されている「決済」「税関」「通知」「貨物種別」「荷主エンティティ」が未モデル化であり、このままではユースケース 12 件のうち少なくとも 4 件(UC10〜12、UC09)が実現できない。 ### 良い点 - DDD パターンの正確な適用(集約・値オブジェクト・エンティティ・コマンドの正しい識別) - UN/LOCODE の採用(ビジネスアーキテクチャの「標準準拠と相互運用性」原則との整合) - `HandlingActivity` の荷役タイプが要件定義の荷役作業種別(積込・荷降し・受領・引取)と対応 - コンテキスト間ドメインイベント(`RouteRequested → RouteAssigned`)が業務フローと整合 - `BookingAmount` の存在により後の精算コンテキストへの拡張基盤がある ### 主な改善提案 - **【高】精算コンテキスト(Payment/Settlement Context)が完全に欠落** — UC10〜12 と「決済機関」外部システム連携が実現できない - **【高】TransportStatus の状態値が要件定義と不整合** — 元の Cargo Tracker サンプルの値がそのまま使われており、プロジェクト固有の状態(受領済・積込済・荷降し済・引取待ち・例外発生・対応中)が表現できない - **【高】税関(Customs)連携の概念がない** — 国際貨物輸送で通関は業務遂行の前提条件 - **【高】荷主(Shipper)エンティティが存在しない** — 法人割引判定・UC02(荷主登録)が実現できない - **【中】通知ドメインイベントが未定義** — `CargoStatusUpdated` 後に誰がどう受け取るかのフローがない - **【中】貨物種別(CargoType)の欠落** — 危険物・冷凍貨物の制約がモデルに反映されない ### スコープ外の発見 本ドキュメントは「JIG ツールによる既存 OSS サンプルアプリの分析結果」であり「本プロジェクトのドメインモデル設計書」ではないことを明確化すべき。自己評価「品質指標すべて高」は本プロジェクト要件との整合性を考慮しておらず過大評価。xp-architect(高: 6 / 中: 5 / 低: 2)
### 評価サマリー 全体として DDD の基本構造を適切に捉えており、5 つのコンテキスト分割は理にかなっている。一方で、集約ルートの誤分類・循環依存・TransportStatus の状態不整合・外部システム連携のモデル欠如という実装フェーズで深刻な問題となりうる設計課題が複数確認されており、早期に修正すべき点がある。 ### 良い点 - コンテキスト分割の方向性が妥当(業務の自然な境界に沿い、各コンテキストが単一責務) - コンテキストごとに専用の識別子型を定義(ACL の意図が感じられる) - コマンドが明示されており CQRS 設計の基盤になりえる - ドメインイベントフローが記述されており業務の流れを正確に表現 - UN/LOCODE による国際標準準拠 ### 主な改善提案 - **【高】`BookingId`・`TrackingNumber` の集約ルート誤分類** — 識別子は値オブジェクトであり、独立した集約ルートにすると不要なリポジトリが増生する - **【高】`h_agg ↔ h_vo` 循環依存の解消** — `HandlingActivityHistory`(VO)が集約ルートを参照する構造は DDD の根本的な制約違反 - **【高】TransportStatus と要件定義の状態モデルの不整合** — `IN_PORT` が 3 つの業務状態を区別できない - **【高】`HandlingActivity.isValidFor(cargo: Cargo)` によるコンテキスト境界違反** — ACL を導入して `CargoSnapshot` 値オブジェクト経由に変更すること - **【中】Shared Domain の設計方針の不一貫性** — 共有カーネルと ACL が混在 - **【中】外部システム連携の ACL が未定義** — `ExternalRoutingServicePort`・`CustomsClearancePort`・`PaymentGatewayPort`・`PortManagementPort` を Port として定義すること ### 懸念事項 - `CargoStatusUpdated` の流れが `tracking → booking` となっており依存方向が逆 - `TrackingActivity` の高頻度イベント追記での楽観的ロック競合リスク - 精算業務のドメインモデルが完全に欠落xp-interaction-designer(高: 4 / 中: 4 / 低: 2)
### 評価サマリー DDD の構造的骨格(境界付けられたコンテキスト、集約、値オブジェクト)は適切に分離されており技術品質は高い。しかし、ユーザーストーリーで定義された日本語ユビキタス言語と英語ドメイン用語の対応関係が文書化されておらず、荷主が画面で見る状態名(「積込済」「荷降し済」等)がコードの列挙値(`IN_PORT` 等)に正確に対応しているかが追跡不能な状態にある。精算コンテキスト・例外概念・アクター-コンテキスト対応の欠如も、ユーザーストーリー実現の障壁となる。 ### 良い点 - 境界付けられたコンテキストの分離が要件定義書の業務区分と概ね整合 - コマンドが各コンテキストに定義されており、ユーザーストーリーの操作との対応が取りやすい - Shared Domain(Location・VoyageNumber)が要件定義の UN/LOCODE 受け入れ基準と整合 - ドメインイベントフローが可視化されており US04〜US10 の業務フローと対応 ### TransportStatus と業務状態の対応表(整合状況) | ユーザーが見る状態 | TransportStatus | 対応 | |---|---|---| | 受領待ち | `NOT_RECEIVED` | ✅ | | 受領済 | — | ❌ 欠落 | | 積込済 | — | ❌ 欠落 | | 輸送中 | `ONBOARD_CARRIER` | ✅ | | 荷降し済 | `IN_PORT` | ⚠️ 受領済・引取待ちと区別不能 | | 引取待ち | `IN_PORT` | ⚠️ 上と同じ | | 引取済 | `CLAIMED` | ✅ | | 例外発生 | `UNKNOWN` | ⚠️ 意味が異なる | ### 主な改善提案 - **【高】TransportStatus の粒度がユーザー体験の状態と不一致** — `IN_PORT` を分割し 8〜9 値に拡張、英日対応表を追記すること - **【高】英語用語と日本語ユビキタス言語の対応表が存在しない** — ドキュメント冒頭にユビキタス言語対応表を追加すること - **【高】精算コンテキストが存在しない** — `Invoice`・`PaymentStatus`・`DiscountPolicy` を含む Billing Context を追加すること - **【高】例外概念(ExceptionEvent / ExceptionType)が存在しない** — `TrackingExceptionEvent` エンティティを Tracking Context に追加することxp-tester(高: 5 / 中: 5 / 低: 2)
### 評価サマリー DDD の構造的分離は適切でテストの独立性を確保する土台は整っている。しかし状態モデルの不整合・ビジネスルールの曖昧さ・計算ロジックの欠落が複数あり、このまま実装を進めると受け入れテストが書けない箇所が多数発生する。 ### 良い点 - 集約の境界が明確でコンテキスト隔離のユニットテストが可能 - コマンドが定義されており Given 側のテストデータ設計の起点として使える - 列挙型による状態の明示で状態遷移テストの期待値が枚挙しやすい - `isValidFor()` メソッドが定義されており妥当性検証の単体テスト設計ポイントとして明確 ### TransportStatus 対応表(テスト観点) | 要件定義の状態 | TransportStatus | テスト可否 | |---|---|---| | 受領待ち | `NOT_RECEIVED` | ✅ | | 受領済 | — | ❌ 定義なし | | 積込済 | — | ❌ 定義なし | | 輸送中 | `ONBOARD_CARRIER` | ✅ | | 荷降し済 | `IN_PORT` | ⚠️ 曖昧 | | 引取待ち | `IN_PORT` | ⚠️ 区別不能 | | 引取済 | `CLAIMED` | ✅ | | 例外発生 | `UNKNOWN`(推測) | ⚠️ 根拠なし | | 対応中 | — | ❌ 定義なし | ### 主な改善提案 - **【高】`TransportStatus` 5 値 vs 要件定義 9 状態の乖離** — 対応表とともに状態を拡張すること - **【高】`RoutingStatus` 3 値では予約業務状態を表現できない** — `BookingStatus` 列挙型の追加が必要 - **【高】`BookingAmount` の計算ロジックが未定義** — US16 のテストの Given-When-Then が成立しない - **【高】`isValidFor()` の検証ルールが未定義** — 荷役タイプ別のデシジョンテーブルを定義すること - **【中】`CargoItinerary` の Leg 制約が曖昧** — 最小数・順序制約・時刻整合性を明示することxp-user-representative(高: 5 / 中: 2 / 低: 1)
### 評価サマリー 予約・経路設計・追跡・荷役の中核業務フローは概ねモデル化されており、DDD 的な構造としては整理されている。ただし、「通知」「精算・Invoice」「荷受人」「キャンセル・ルート変更」という日常業務で頻繁に使う概念が根本的に欠落しており、現状では実際の輸送業務を支えるシステムとして不十分。 ### 良い点 - 荷役タイプ(RECEIVE / LOAD / UNLOAD / CLAIM)が現場作業員の業務(受領・積込・荷降し・引取)と完全に一致 - TransportStatus の状態遷移が現場の感覚と概ね合っている(`UNKNOWN` も現場で必要) - `RoutingStatus.MISROUTED` は追跡管理者の誤配送検知に有用 - `CargoItinerary` の Leg 分割は多港経由の実務に合っている ### 主な改善提案 - **【高】Notification(通知)コンテキストまたは概念が完全に欠落** — 荷受人の最大のニーズ「貨物到着通知」が実現できない - **【高】精算・Invoice のドメイン概念が存在しない** — 請求書発行・精算の業務フローを支える概念がない - **【高】荷主(Shipper)・荷受人(Consignee)のエンティティが存在しない** — 顧客の特定ができず通知先・請求先が不明 - **【高】キャンセル・ルート緊急変更のコマンドが存在しない** — 台風・港湾ストライキ等の例外は国際輸送では日常茶飯事 - **【高】業務フロー「予約→引取→精算」が完結していない** — 精算クローズまでの後半が丸ごと設計対象外 ### 懸念事項 - アーキテクチャ品質評価「表現力: 高」は過大評価。荷主・荷受人・通知・精算という主要なビジネス概念が欠けた状態での評価は実態に合わない改善アクションの推奨順序¶
フェーズ 1(ドメインモデル設計書作成前に必須)¶
本ドキュメントを「参照事例分析」から「本プロジェクトのドメインモデル設計書」へ格上げするための最低限の作業:
- TransportStatus を 9 値に拡張し、要件定義の状態遷移と 1:1 で対応させる(H1)
BookingStatus列挙型を追加し予約の業務状態を表現する(H7)- 荷主(Shipper)・荷受人(Consignee)を Booking Context に追加する(H3)
BookingId・TrackingNumberを値オブジェクトに格下げする(H4)- 循環依存(
HandlingActivityHistory)を解消する(H6) - ユビキタス言語対応表を追加する(M6)
フェーズ 2(設計ドキュメント完成に向けて)¶
- 精算コンテキスト(Billing Context)を追加する(H2)
- 例外概念(ExceptionEvent / ExceptionType)を追加する(H9)
- 外部システム連携の ACL(4 種の Port)を定義する(M7)
- 通知ドメインイベントのフローを追加する(M4)
- アクターとコンテキストの対応表を追加する(M5)
フェーズ 3(品質向上)¶
isValidFor()の検証ルール(デシジョンテーブル)を定義する(H10)BookingAmountの計算ロジック・通貨情報を明示する(H11)- 貨物種別(CargoType)を
Cargo集約に追加する(M10) - Leg の整合性制約を明示する(M8)