コンテンツにスキップ

設計ドキュメント横断のフォローアップ台帳

本ファイルへの新規のフォローアップ項目の追加は禁止する。更新・削除のみ可能。 新規にフォローアップが必要な場合は、.claude/rules/followups.md の手順に従って書くこと。

設計ドキュメントを修正すると、そのドキュメント単独では閉じない未決事項が出る。OASへの反映、 他ドメインとの合意、外部仕様の出典不一致、書いた規則を支える実体の欠落である。これらを各 ドキュメントの申し送り節に散らすと、どこに書いたかが分からなくなり追随漏れになる。

行き先を本ファイルに固定する。 .claude/rules/design-docs.md が指すフォローアップの宛先は 本台帳であり、同ルールの paths が対象とするドキュメント(飛行計画・GeoSpatial・Elevation・Asset)の どれを修正した場合でも、追加先はここである。

書くこと
種別下記4種のいずれか
項目何が未決なのか。判断が分かれる論点は選択肢も書く。値(桁数・値域・出典ごとの数値)は書かず、由来のドキュメントを正とする(台帳が値を持つと同じ数値が3箇所になる)。判定の根拠が由来のドキュメントに書かれていない場合(実装やツールの挙動を実測して判定した場合など)は、その根拠をファイル名とシンボル名(クラス名・メソッド名・定数名・SQL制約名など)でこの列に書く。行番号は書かない(他PRのマージで容易にずれ、追随漏れの温床になる。grepで見つからないシンボル参照が必要なら、その旨と根拠を書く)
由来気づいた箇所。ドキュメントはファイル名と節名(行番号は改版で動くため節名を優先する)。リポジトリ外の資料は資料名と該当箇所(項番・別紙のID など)
対応状況未対応 / Issue #N / PR #N / 決定済み。決定した内容を由来のドキュメントへ反映してから決定済みにする

この台帳は残作業のリストである。 行に触れたときは、その時点で残っている作業だけが読み取れる状態にする。

  • 残作業が無くなった行は削除する。決定済みのまま置いたままにしない。決定そのものを記録として 残す必要があるなら、由来のドキュメント側に書いてから台帳の行を消す
  • 一部だけ解決したなら、残った作業だけに書き換える。終わった記述を残さない
  • コード・数値・応答コードを書くときは意味を添える(04ではなく04(受付完了)

種別は次の4つとする。

種別意味
OAS反映社内OASへの反映が必要
他ドメイン合意他チームとの合意が必要
出典不一致外部仕様(DIPSなど)が出典間で食い違っており、どちらが正かの確認が必要
実体未作成概念語や規則を書いたが、それを支える実体(カラム・式・制約・API項目)がまだない
種別項目由来対応状況
出典不一致飛行速度の範囲がガイドライン本文と別紙2で一致しない。上限は緩めない方針で運用しているが、どちらが正かは未確認でDIPSへの照会事項。両方の出典と値は由来の★印の記述にあるflight-plan-field-mapping.mdの「DIPS側の入力チェックとAPI制約の対応」(★印の記述)未対応
実体未作成Polygonの構成点数の上限が生成コードで強制されない。入れ子配列(LinearRing)に対する宣言はopenapi-generatorがBean Validationに出力しないため、ドメイン層のガードが必要。宣言の実体はdocs/openapi/frontend/flight-planning.yamlGeoJsonPolygonのLinearRingのminItems/maxItemsで、生成物は.gitignore対象のため./gradlew openApiSyncToSrc後のGeoJsonPolygon.javaで再現する。上限値は由来を参照。なお数え方は開いた頂点列(終点=始点との重複を含めない)で、ドメイン(src/main/java/com/intent_exchange/utm/domain/model/FlightPlanArea.javaPolygon)とDBは閉環で保持するため、判定時は終点の重複を除く(openVertices)必要があるflight-plan-field-mapping.mdの「DIPS側の入力チェックとAPI制約の対応」(flyRouteのPolygon構成点の行)未対応
他ドメイン合意模擬DIPSの日時のタイムゾーンがUTCと確定したが、飛行計画ドメインのOASは「DIPSへの通報時はJSTに変換する」「許可・承認期間はJSTの暦日で判定する」と記述しており食い違う。10月デモの通報先は模擬DIPSであるため、OASの記述および暦日判定のロジックがそのままでは成立しない。本番DIPS2.0はJSTのままで模擬DIPSとは別仕様であるため、どちらを前提に記述するかを含めて飛行計画ドメインと決める。とくにpermitDate/startDate/finishDateyyyy/MM/ddでタイムゾーンを持たないため、どの暦日と突き合わせるかの決定が必要PR #143での模擬DIPS実装。食い違いの相手はdocs/openapi/frontend/flight-planning.yamlFlightPeriod.startTimeFlightPermitApplicationInfo。模擬DIPS側の根拠はdocs/issues/issue-143-dips-base/open-questions.mdのD-11未対応
他ドメイン合意機体種別の値域がAssetチームの持つ実データと食い違っている。フロントエンドが持つ機体データの機体種別に、本設計のASSET_UAS_ATTRS.airframe_typeの値域に存在しない値がある。forDemoのシード(db/seed/local/asset_sample_data.sql冒頭コメントのairframeType='AIRPLANE'読み替えの記述)は既存の値へ読み替えて投入しているが、読み替えはシードのコメントに閉じており恒久的な合意ではない。どちらの名称を正とするかをAssetチームと決める。なおasset.yamlはスタブのため値域の宣言自体がなく(AircraftスキーマにTODOコメントのみでenum/maxLengthの宣言がない)、食い違いの相手はOASではなくリポジトリ外のフロント実データであるflight-plan-er.mdの「図3 カラム補足」(ASSET_UAS_ATTRS.airframe_type未対応
実体未作成AGL/WGS84換算用の地表標高データ(ELEVATION)のデータソースを決定した(GSJ統合DEM+ジオイド高JPGEO2024、utm-backend内蔵コンポーネント)が、正の記録先であるutm-design-docs/docs/data-model/data-model.mdへの反映とADR化は別リポジトリ側の対応が必要で未着手。utm-backend側の実装(domain.port.AltitudeConverterinfrastructure.elevation)と設計書(elevation-service-design.md)は反映済みgeospatial-api-design.mdの5.1節「ELEVATION(地表標高データ)の実体」、elevation-service-design.md2章「背景・決定事項」未対応
実体未作成機能要求5.1.3.3が定める「国土地理院DEM10B精度の最低保障・バイリニア補間」を、PR #157のElevation実装が満たしていない。東京23区は10m相当だが23区外は1kmメッシュのDEMにフォールバックし、DEMのサンプリングも最近傍である(ジオイド高側は双線形補間)。充足には全国10mメッシュ化とDEM側の双線形補間の両方が必要で、いずれも未着手。現状の値は安全判断に使えない(誤差が過小評価側に偏る)ことを設計書9章に記録済みgeospatial-api-design.mdの「地表標高データ(DEM)の参照手段はドメイン間で共有する」、elevation-service-design.md9章「既知の制限・今後の課題」未対応
他ドメイン合意forDemoでは機体・操縦者のAsset APIを提供せず、フロントエンドが機体7件・操縦者7件の固定ID(db/seed/local/asset_sample_data.sqlでシード投入)を直接保持する運用とすることを、関係各位と合意済み(Teamsで別途連絡)。この決定自体の一次情報(合意日・議事録等)はリポジトリ外にあり本リポジトリには存在しないため、変更が必要になった場合は関係者へ再確認すること。あわせてflight-plan-er.mdの「OAS・他ドメインへ反映が必要な項目」表(asset.yamlの行)は「Assetチームと項目を突き合わせる」として引き続きAPI提供を前提にした書き方のままであり、本決定と矛盾するため次にその節へ触れる際に確認することEnvSetup_ManualSteps_forDemo.mddb/seed/local/asset_sample_data.sql冒頭コメント未対応
OAS反映aircraftNamesの解決規則がOASの例と設計・実装で食い違っている。設計(flight-plan-field-mapping.md4-2節・flight-plan-er.md図3補足)と実装(FlightPlanMapper.xmlfindAircraftNames)はASSET.model単独(例: Matrice 350 RTK)で解決するが、OASのPilotAssignment.aircraftNamesの例はmanufacturer + ' ' + modelの連結(DJI Matrice 350 RTK)になっている。どちらを正とするか(model単独ならOASの例を修正、連結が正なら連結規則を設計側にも明文化)を決める必要があるflight-planning.yamlPilotAssignment.aircraftNamesの例(複数箇所)とflight-plan-field-mapping.mdの「機体名」の行(ASSET.model未対応
実体未作成PILOT.name/ASSET.modelはDIPS通報時にそれぞれpilotInfo[].contactPilot.name(120文字以内、ID100)・flightPlanInfo.aircraftInfo[].model(100文字以内、ID126)としてそのまま送信されるが、両カラムはVARCHAR(255)db/schema/asset.sql)でこれより緩い。forDemoは機体・操縦者のCRUD APIを提供せず値は固定シードのみ(いずれも100文字未満)のため実害はないが、CRUD実装時はカラムの桁数制約をDIPSの上限に合わせて狭める必要があるflight-plan-field-mapping.mdの「DIPS側の入力チェックとAPI制約の対応」(PilotAssignment.pilotName/aircraftNamesの行)未対応
実体未作成WGS84基準の形状(*_geometry_wgs84列)とAMSL/WGS84のスカラー(min/max_altitude_m_amslmin/max_altitude_m_wgs84)をFLIGHT_PLAN_AREA側(PR-02登録・PR-03更新)で充填する処理がなかった。列はPR #137、DEM・ジオイド高の取得経路(domain.port.AltitudeConverter)はPR #157で実装済みだったが、それを呼び出す充填処理が未実装だった。遅延充填(NULL保存後に後から補完)は採用せず、elevation.enabled=trueの環境では登録・更新時に1頂点でも変換できない場合は登録・更新自体を拒否し、elevation.enabled=false(既定値)ではNULLのまま保存する方針で実装した。DIPS_FLIGHT_PLAN側(PR-12収集)も解消済み。 RefreshNearbyFlightPlansUseCaseが自組織側と同じ変換処理を呼び出すが、周辺収集は多数の他Operator計画を一括で取り込むバッチ処理であるため方針は異なり、1件が標高データのカバー範囲外でもその計画のWGS84/AMSL列だけを除外し、収集全体は失敗させないこの充填はelevation.enabled=trueかつDEM・ジオイドファイル配置済みの環境でのみ機能する(既定のfalseではNULLのまま)。デモ環境でこれを有効化する手順は未整備で、Issue #245(現状はローカル実行手順の整備が範囲)を拡張して整理する予定。空域制限ドメインは同じ構造の実体化列(geometry_wgs84 / top_bottom_3d_geometry_wgs84)を持つ判断へ変えたairspace-er.mdの「WGS84基準の形状も実体化列で持つ」)。ただし空域制限側は10月デモの事前投入で直接値をロードする前提であり、本項目のような登録・更新時の変換(AltitudeConverter呼び出し)は行わない。飛行計画側の充填処理と空域制限側の事前投入は別の経路のため、双方の非対称は列の有無ではなく値を埋める手段(アプリの変換処理か、投入時の直接ロードか)にあるflight-plan-er.mdの「高度は換算値をカラムに保持する」PR #250で対応(#157がマージされるまでマージ不可)。DIPS_FLIGHT_PLAN側はPR #276で対応。デモ環境での有効化はIssue #245で対応予定
実体未作成top_bottom_3d_geometry(および対になる_wgs84列)にPostGIS型として書かれていた2D前提の型を支える実体がなく、実体は3次元(MultiPolygonZ)だった。ST_Force3Dで組み立てた値が2Dの型修飾子では登録できないことを実測で確認し、DDLはST_NDims = 3必須へ変更済み(根拠はdb/schema/flight_planning.sqlck_flight_plan_area_top_bottom_3d_geometryck_dips_flight_plan_top_bottom_3d_geometry)。由来のドキュメント側の記述はPR #137で3次元である旨を補記したflight-plan-er.mdの「図1 カラム補足」(top_bottom_3d_geometryの行)決定済み
実体未作成飛行計画側(FLIGHT_PLAN_AREADIPS_FLIGHT_PLAN)のgeometryに、USING GIST ((geometry::geography))の式インデックスを張っていない。空域制限との競合判定(PR-11)が発行するST_DWithinでは、飛行計画側は対象リビジョンの1行に絞り込んだうえで空域制限側を探索するため飛行計画側の索引は使われず、リビジョンごとに行が増える同テーブルには使われない索引の更新コストだけが乗る(DIPS_FLIGHT_PLANはそもそも競合判定の対象ではない)。これらの列に対してST_DWithinを発行する実装が他に現れたときに再検討する。 索引の追加・削除はpsqldefの宣言的同期で可逆なため、実測で必要と分かってから張れるflight-plan-er.mdの「空間インデックス」の記述未対応
実体未作成geometry列のSRID・種別・3次元を型修飾子の代わりにCHECK制約で保証するという規則に対し、それを1箇所で支える実体(共通のCHECK用関数またはDOMAIN型)がない。flight_plan_areadips_flight_planが同じ内容の制約をテーブルごとに複製しており(db/schema/flight_planning.sqlck_flight_plan_area_*ck_dips_flight_plan_*。後者のコメントも「FLIGHT_PLAN_AREAと同じく」と写しであることを認めている)、3つ目のジオメトリを持つテーブルが増えると再び複製される。共通化にはdb/schema/*.sqlCREATE TABLEのみを書く規約(例外は循環FKのALTERのみ)の改定が要り、psqldefが関数・DOMAINの定義を差分計算できるかも未検証のため、PR #137では見送った。3つ目のテーブルを追加する際に、規約改定とpsqldefでの検証をあわせて判断する。その3つ目(airspace_restriction.airspace_restriction)が空域制限ドメインの設計で現れたが、括り出しは再び見送り、制約を複製する判断を採ったairspace-er.mdのD4)。以後、この制約を複製するテーブルは3つになるdb/README.mdの「psqldefが解釈できない記法」とPR #137のレビュー(@nes-miyasaka の8点目)未対応
実体未作成飛行計画一覧の検索条件・並び順を支えるインデックスがない。FlightPlanMapper.xmlsearchdeleted_at IS NULLで絞って登録日時の昇順で返すが、flight_planに張っている索引はorganization_idcreated_bycurrent_revision_idの単独列のみ(db/schema/flight_planning.sql)で、この条件と並び順には使われず件数が増えると全件走査になる。ページング自体は由来のOASが「デモではページング・ソートを提供対象外」と明記した決定済みの事項であり、方式が決まるまで対象列・条件式を確定できないため、PR #137では索引を追加していない。UseCase層の実装・運用開始時に、確定した検索条件に合わせて張るflight-planning.yamllistFlightPlansの「デモ向け補足」とPR #137のレビュー(@nes-miyasaka のパフォーマンス指摘3点目)未対応
実体未作成ASSET_UAS_DIPS_ATTRS.dips_aircraft_type(DIPS機体種別コード)はairframe_typeから機械的に導出する運用だが、airframe_type=VTOLに対応するDIPSコードが無い(DIPSの6コードにVTOL相当が存在しない。db/schema/asset.sqlの列コメント参照)。VTOL機体をDIPS通報する際に何を設定するかが未決のまま、DBのCHECK制約(ck_asset_uas_dips_attrs_type)は値域を16に限定しているflight-plan-er.mdの「図3 カラム補足」(ASSET_UAS_DIPS_ATTRS.dips_aircraft_type)。判定根拠はdb/schema/asset.sqlの列コメント(DIPSの6コードの列挙)未対応
実体未作成altitude_agl_mの導出に使う地表標高(DEM)の参照手段自体はPR #157で実装済み(domain.port.AltitudeConverter。楕円体高→AGLのellipsoidalHeightToAglMetersを含む4方向の変換を提供)。要件5.1.3.3が求める国土地理院DEM10B精度・バイリニア補間を満たすかは別の未決事項(本台帳の「PR #157のElevation実装が満たしていない」の行)で扱う。列と充填の契機(10月デモはutm-backendが読み出し時にNULLなら充填、TO-BEは受信時)はtelemetry-er.mdで決めた。飛行計画側(*_geometry_wgs84列等)はelevation.enabled=trueの環境で登録・更新時にNOT NULLを保証し遅延充填を行わない方針をPR #250で既に決定済みであり(本台帳の「WGS84基準の形状へ換算値を充填する処理がアプリ側にない」の行、およびflight-plan-er.md参照)、テレメトリの「読み出し時にNULLなら充填」とは逆方向である。両者の差は書き込みの契機の違い(飛行計画は登録・更新を持つが、テレメトリは追記のみの受信ストリームで事後に基準を変える契機がない)にあり、どちらかが他方の先例になるものではないtelemetry-er.mdの「対地高度は受信時に充填する」決定済み
実体未作成observed_atに要求する0.1秒精度を、既存のSQSの受信I/Fが満たしていない。要件5.1.1.2はタイムスタンプをUTC基準で最低0.1秒の精度で表現することを求め、GeoSpatialもミリ秒まで返す仕様だが、既存のSQSの受信I/Fはエポック秒のdouble(long)へキャストしてから1000倍しており秒未満が切り捨てられる(telemetry-service-protosrc/main/java/com/intent_exchange/telemetry/Telemetry.javatoTimestamp()。キャストが乗算より先に結合するため)。カラムをtimestamp(3)以上で定義しても、この受信I/Fを直さない限り値は秒単位のままになる。TELEMETRY(aircraft_id, observed_at)一意制約(重複配信の排除)と噛み合うため、10月デモまでに直す。 切り捨てられたままだと、同一秒に届いた2件目以降が正常な観測でも重複として落ちる。デモのテレメトリはBroadcast Remote ID受信機から流れ、流量制御がかかっているか未確認で同一秒に2件以上届きうる(PR #265 のレビュー)。受信するJSONのtimestampはエポック秒の小数(例1705916942.4)で0.1秒の分解能を持つため、キャストの順序を直せば復元できる。当初は「10月デモでは対処しない」としていたが、上記により撤回したtelemetry-er.mdの「図1 カラム補足」(TELEMETRY.observed_atの行)未対応
他ドメイン合意テレメトリが準拠するASTM F3411のバージョンと、採用する項目の範囲が未確定。既存のSQSの受信I/Fはclassification_typeに加えてcategory_eu/class_euというEU固有の分類を受け取るが、国内運用でこれらを使うかが決まっていない。10月デモは現行のまま列を残す判断だが、使わないなら列ごと落とせる一方、GUTMA/ASTMデモでの相互接続では要る可能性があるためデモの相手方と突き合わせて決めるtelemetry-er.mdの「図1 テレメトリドメイン(10月デモ向け)」(TELEMETRY.category_euclass_eu未対応
他ドメイン合意テレメトリの保持期間とライフサイクルが未定。概念モデル側がTODO: データ更新頻度・ライフサイクルのまま実体を持たない(utm-design-docs/docs/data-model/data-model.md)。テレメトリの送信間隔は機体側の実装で現状1秒である(ADR-007も収集フローの想定として同水準に触れるが、決定ではない)。保持期間・ダウンサンプリングの方針が決まらないとTELEMETRYのパーティション粒度を確定できない。航空局報告のための保存期間要求とあわせて決めるtelemetry-er.mdの「本ドキュメントの範囲」未対応
他ドメイン合意テレメトリの保存先として時系列DBを採用するかが未決。ADR-007は収集・保存フローを「ドローン→MQTTブローカー等→時系列DB」と描き、ブローカー選定・時系列DB選定・appへのイベント伝達方式を別途設計が必要な残課題としている。10月デモはPostgreSQL(Aurora)で進めることを決定済み。デモ以降はクラスメソッドによる設計案があり、Auroraに持ちつつストレージ容量(=料金)と性能に難が出ればS3へ退避しAthenaでクエリする想定である(古いデータは参照頻度が劇的に下がるため、レイテンシの悪化を許容する判断)。AthenaはAWS寄りの選択で、S3からDuckDBで読む案も成立しうる。初期は不要で、データ蓄積が始まる時点で判断する(PR #265 のレビュー)。認定の要件はテレメトリの頻度を定めていないため、保存間隔はコスト試算の変数として扱う。保持期間の決定(本台帳の別行)と同時に判断するtelemetry-er.mdの「本ドキュメントの範囲」未対応
実体未作成テレメトリ品質(受信間隔・ジッタ・欠損率・推定誤差)を可視化するための実体がない。要件9.1.2.3がこれらの表示と、一定時間の未受信を「不明」として明示することを求めるが、TELEMETRYobserved_at/received_atを持つだけで、算出をクエリで都度行うのか集計列・集計テーブルを持つのかが未決。判定の閾値(要件9.1.2.3.2・9.1.3.3.2)も確定していない。10月デモでは可視化自体を対象外とするtelemetry-er.mdの「図1 カラム補足」(TELEMETRY.received_atの行)未対応
他ドメイン合意テレメトリとConformance Monitoring(CONFLICT_DETECTION)の連携が未設計。概念モデルの飛行計画ドメインはCONFLICT_DETECTIONに逸脱・侵入の検出種別を持つが、検出の入力となるテレメトリ側からの参照が定義されていない。10月デモではConformance Monitoringが対象外のため着手しない。移植元のUSSには既存の検討結果がある(ix-reamo/ussdesign/reamo/dd/md/飛行実績登録_動態管理シーケンス.md。バッチ周期・最大欠落時間・Contingent判定までの時間を含む)ので、着手時の入力にするtelemetry-er.mdの「本ドキュメントの範囲」未対応
他ドメイン合意テレメトリと運航調整ドメインの関係が未整理。概念モデルの運航調整ドメインがTODO: 運航調整(稲垣さん、野中さん)の検討内容をImportするのまま実体を持たない(utm-design-docs/docs/data-model/data-model.md)。運航調整の相手に動態を見せる範囲(FLIGHT_PLAN_ACCESS_GRANTがテレメトリの可視範囲まで及ぶのか)が決まっていないため、TELEMETRYの参照制御をRLSの組織スコープだけで足りるとしてよいかが確定しない。10月デモではConformance Monitoringと同じく対象外とするtelemetry-er.mdの「図1 カラム補足」(*.organization_idの行)未対応
他ドメイン合意TELEMETRY.aircraft_id(GeoSpatialのuasEntityIdに対応)に他Operator機に対して何を入れるかが未決。GeoSpatialのsearchFlyingDronePositionsは他Operator機も返しuasEntityIdを必須とするが、自UTMのASSETに存在しない機体にはアセットIDを振れない。自組織機についてはASSET.idと一致させることを本PRで決定済み。10月デモは他社UTMの機体も自組織のASSETとして登録する回避策を採るため(telemetry-er.mdの「他社UTMの機体はASSETとしてだけ登録する」)、デモ期間中は表面化しない。恒久的に他Operator機を扱う段階でGeoSpatialと決める。同じ論点で既にIssue #135が起票されている(flight-plan-field-mapping.mduasEntityIdの記述)telemetry-er.mdの「他社UTMの機体はASSETとしてだけ登録する」Issue #135
実体未作成IAMドメイン(ORGANIZATIONUSER)の実体がutm-backendに無く、operator_nameの複写元としているUSER.display_nameを解決できない。db/schema/iamスキーマもユーザー表も無く、ASSET.organization_idregistered_byはFK制約を持たない参照だけの列である(db/schema/asset.sqlのコメント)。認証自体が10月デモのスコープ外で、実行中のユーザー・組織も定数である(docs/policy/flight-planning/forDemo/AuthenticationSpecification_Flightplanning_forDemo.md)。他社機だけでなく自組織の機体でも解決できないため、10月デモはTELEMETRY_DISPLAY_DEFAULTから機体ごとに埋める方式を採る。IAMドメインの導入時に結合へ戻す。あわせて、geospatial.yamloperatorNameの例が会社名(サンプルドローン株式会社)である一方、本設計の複写元は個人の表示名(USER.display_name)で、画面に出すのが運航者(組織)か担当者(個人)かが確定していないtelemetry-er.mdの「表示用の値は機体ごとの既定値で埋める」未対応
実体未作成uas_nicknameASSET.nicknameの複写列)を埋める取り込み側の実装がまだ無い。utm-backend側の列・OAS・読み出し経路はPR #296で用意したが、複写を行うのは別リポジトリのtelemetry-service-proto PR #7で、それがデモ環境へ反映されるまでは全行NULLになる。そのためtelemetryに相関のCHECK(aircraft_id IS NULLuas_nickname IS NULL)を、current_telemetryNOT NULL(主キーのaircraft_idがある以上、機体を解決できた行しか存在しない。バックフィル要)を今は置いていない(根拠はdb/schema/telemetry.sqluas_nicknameの列コメント)。あわせて、reported_uas_idが持つ空文字チェック(ck_telemetry_reported_uas_idck_current_telemetry_reported_uas_id)に相当する制約もuas_nicknameには無く、複写元のasset.asset.nickname側にも無いため、空文字が入ると「未設定」と区別できない。取り込み側の反映後に、これら3点をまとめて入れるtelemetry-er.mdの「図1 カラム補足」(TELEMETRY.uas_nicknameの行)telemetry-service-proto PR #7
実体未作成TELEMETRY_DEAD_LETTERの監視が設計されていない。却下が増えていることに気づく仕組みが無く、「機体が送信しているのに表示されない」を後から追える状態にはなっても、起きていること自体には気づけない。SQSのDLQと同じ性質のため、監視・通知の要否は運用設計とあわせて決める(PR #265 のレビュー)telemetry-er.mdの「却下の記録は旧USSから引き継ぐ」未対応
他ドメイン合意DEM・ジオイドのデータをS3へ置き、COG(Cloud Optimized GeoTIFF)で参照する構成へ移行する。現在はGeoTIFF・ISGのファイルを配置して読む方式で、全国を一律の高解像度で用意できないため東京23区のみ10m・それ以外は全国1kmに絞っている(elevation-service-design.mdの「6.2 対象範囲・解像度」)。COGなら必要なタイルだけ読むため全国10mへ広げられる。**移行はutm-backendとテレメトリ取り込みのLambdaを同時に行う。**片方だけがS3を参照すると同じ地点で異なる対地高度が出るためである。GeoToolsのrange readerモジュールが使えるかの確認から始めるtelemetry-er.mdの「対地高度は受信時に充填する」未対応
実体未作成高度変換の実装がutm-backendとテレメトリ取り込みのLambdaに重複する。Lambdaは変換を同梱して受信時に対地高度を導出するため(同上)、infrastructure/elevation配下の実装を写すことになる。値がずれても気づきにくい箇所のため、共有ライブラリへ畳む。10月デモでは重複したまま進めるtelemetry-er.mdの「対地高度は受信時に充填する」未対応
実体未作成高度変換の初期化に約3.9秒かかる(elevation-service-design.mdの「4.7 初期化コスト」)。Lambdaでは実行環境ごとに一度かかるため、スケールアウト時に効く。10月デモの規模(3機体・1Hz・30分)では実質1回で、SQSトリガのためメッセージも失われないが、消したい場合はSnapStartが本命である。java25ランタイムでの対応可否を確認するtelemetry-er.mdの「対地高度は受信時に充填する」未対応
OAS反映TELEMETRY.flight_plan_idCURRENT_TELEMETRY.flight_plan_idはNullableだが、docs/openapi/frontend/geospatial.yamlTelemetryTrackPropertiesTelemetryPositionPropertiesflightPlanIdoperatorIdoperatorNamestatusをいずれもrequiredとしている。operator_id等はFLIGHT_PLANからの複写のため、flight_plan_idがNULLの行ではTELEMETRY_DISPLAY_DEFAULTに既定値がある機体を除いて値を作れない。flightPlanId自体はどの機体でも埋められないtelemetry-er.mdの「図1 カラム補足」(TELEMETRY.flight_plan_idの行)未対応
実体未作成reported_uas_idaircraft_idの解決(現行の4カラムOR検索)が前提とする識別子のうち、uasUtmIduasSpecificSessionIdに相当する列が新データモデルのASSET側に実在しない(asset.serial_numberasset_uas_dips_attrs.registration_symbolの2列のみ)telemetry-er.mdの「TO-BEから外している点」(UAS_REMOTE_IDの行)未対応
実体未作成FlyingDronePositionsSearchRequest.currentTime(指定時刻時点の位置)に対応する検索経路がない。CURRENT_TELEMETRYは機体ごとの最新1件しか保たないため、過去の時点はTELEMETRY(履歴)からobserved_atが指定時刻以前の直近値を機体ごとに1件引く必要があり、カレントを引く現在のSQLでは原理的に答えられない。PR #289のリポジトリ層はCurrentTelemetrySearchCriteriaに本項目を持たせず、statusまでの対応にとどめた。10月デモで指定時刻の遡及が要るかを確認してから、履歴を引く別のPortを足すか本項目をOASから落とすかを決めるgeospatial-api-design.mdの「飛行中ドローンの位置情報一覧」未対応
実体未作成altitude_agl_mのNaN・無限をDB制約で弾けていない。CHECKで表現したいが、psqldefがdouble precision列への数値リテラル比較を復元できず(PostgreSQLは('...'::numeric)::double precisionとして保持する)、同期のたびに制約のDROP/ADDが出ることをPR #288で実測した。NOT IN・等値・大小比較・d * 0 = 0のいずれの書き方でも再現し、同一テーブルのck_*_positionまで巻き添えで再作成される。蓄積量の大きいテーブルで毎回の再検証は避けたいため制約を置いていない。当面は読み出し側(TelemetryObservationの不変条件)が弾き、PR #289RepositoryExceptionへ詰め替える。psqldefの更新か、書き込み側(telemetry-service-proto)での入力チェックで担保する方法を検討するtelemetry-er.mdの「対地高度は受信時に充填する」未対応
OAS反映directionの型がER図(int、値域0-359)とgeospatial.yamlnumber/doubleminimum:0/maximum:360)で一致しないtelemetry-er.mdの「図1 テレメトリドメイン(10月デモ向け)」(TELEMETRY.direction未対応
他ドメイン合意テレメトリドメインの設計を上位の概念モデルへ反映していない。utm-design-docsdocs/data-model/data-model.mdの「Telemetry (動態監視) ドメイン」はTODO: IX側で検討するのままで、実体はtelemetry-er.mdにある。当面はutm-backend側を正として運用し、概念モデルへの反映は別途行う(conventions.mdのNOTEも、データモデルの規約自体の本来の置き場所をutm-design-docsとしている)telemetry-er.mdの「本ドキュメントの範囲」未対応
他ドメイン合意TelemetryTrackPropertiesTelemetryPositionPropertiesという型名が、飛行軌跡(事後に見る蓄積情報)を表すモデル名として違和感があるという指摘。ログ・レコードなど蓄積された情報を管理するとわかる名前への変更を検討してほしいとのこと。10月デモの対象外とし、命名見直しは別途検討するPR #265のレビュー(t-kuriのインラインコメント、docs/geospatial/design/geospatial-api-design.mdの5.3節見出し)未対応
他ドメイン合意同名だが意味が異なるuasIdが複数箇所にある(FlightPlanAreaProperties.uasIdはアセットID=UUID、テレメトリのuasIdはRemote ID由来の文字列で別物)。ASTM定義のAPIでやり取りする部分はやむを得ないが、UTMのコントロール下にある部分は命名を見直したいという指摘([MAJOR]、10月デモ以降で対応)。プロパティのリネームを伴う破壊的変更のため、対応時期・移行方法をあわせて検討するPR #265のレビュー(t-kuriのインラインコメント、docs/geospatial/design/geospatial-api-design.mdTelemetryTrackProperties.uasIdのdescription)未対応
実体未作成Polygonの幾何的な妥当性検証(ST_IsValid相当)が、APIの書き込み経路(本登録・更新)にしかない。OASのGeoJsonPolygonのdescriptionが定める「自己交差する多角形は422」「GeoJSONの構造だけでは表現できないためバックエンドのドメイン層で行う」に対し、PR #138ではPostGISへ委ねる方針を採り、本登録時にGeometryValidatorsrc/main/java/com/intent_exchange/utm/domain/port/GeometryValidator.java、実装はPostgisGeometryValidator)へ問い合わせて422を返すようにした(座標値の比較で判定できるぶん——相異なる頂点が3点以上——はFlightPlanArea.Polygonの不変条件が担う)。飛行計画更新(updateFlightPlan)の追加時に、この検証をFlightPlanContentValidatorへ集約して更新経路も同じ検証を通すようにした(BusinessLogicSpecifications.md5.1節手順2-1-6)。残っているのは、これを全書き込み経路で保証する仕組みである。DDLのgeometry列のCHECKはSRID・GeometryType・次元数のみを見ており(db/schema/flight_planning.sqlck_flight_plan_area_geometry_sridほか)ST_IsValidのCHECK制約が無いため、DIPS収集(dips_flight_plan)や将来のバッチ経由では不正なジオメトリを保存できてしまう。CHECK制約を追加する場合、違反はDataAccessExceptionRepositoryExceptionとなり500になる(GlobalExceptionHandler.handleRepository)ため、422を返す上記の事前問い合わせと役割が重ならないことを前提に、最後の砦として入れるかを判断するflight-planning.yamlGeoJsonPolygonのdescriptionとPR #138のレビュー(@nes-miyasaka の指摘一部対応済み(API層はPR #138の本登録経路、および飛行計画更新(updateFlightPlan)の追加で更新経路も対応済み。DB制約による保証は未対応)
OAS反映飛行計画名称(name)の空白のみの入力をOASの制約で弾けない。minLength/maxLengthは半角スペースだけの文字列を通すため、実際に弾いているのはFlightPlanDraftFlightPlanRevisionのコンパクトコンストラクタのisBlank()チェック(src/main/java/com/intent_exchange/utm/domain/model/FlightPlanDraft.javaFlightPlanRevision.javaのコンパクトコンストラクタ)で、GlobalExceptionHandler.handleIllegalArgumentIllegalArgumentExceptionを400にマップするため、この機能の他の内容バリデーション失敗が422を返すのに対しここだけ400になる。仮登録(createFlightPlan)・本登録(registerFlightPlan)・更新(updateFlightPlan)のいずれも同じ不変条件で400になり、経路間の差はない(更新はUpdateFlightPlanUseCase.resolveNameが指定値をそのまま通し、判定を不変条件へ委ねている)。OASにpatternを追加すれば(implementation-guide.mdの「検証の配置」が空白のみの拒否に挙げている書き方)422へ揃えられるが、従来通っていた入力が通らなくなる破壊的変更になる。加えて現在のフロントエンドはGUI内で半角スペースの入力を拒否しており(フロントエンドの実装はリポジトリ外のため本リポジトリに根拠はない)、バックエンドでも400として拒否されることから、PR #138時点では対応を見送る。破壊的変更を宣言できるバージョン境界でpattern追加とステータスコードの統一をあわせて再検討するflight-planning.yamlFlightPlanCreateRequestname(同じ制約を持つFlightPlanUpdateRequest.nameFlightPlanFields.nameも同様)とPR #138のレビュー(@nes-miyasaka の指摘未対応
実体未作成DRAFTからのキャンセルを削除と同等に扱う(status=DRAFTのままdeleted_atを設定する)決定が、冪等キーの横断機構に前提を置いているが、その機構がまだない。由来の節は「再送で返す最初の実行結果はADR-020の横断機構が保存・再生し、FLIGHT_PLAN行の再読取に依存しない」ことを前提としているが、保存先・保存内容はIssue #132で未決である。横断機構が応答本体を保存せず対象行を読み直して応答を組む方式になる場合、論理削除済みの行も読める取得経路を別に用意しないとcancelFlightPlanの再送が404になる(DRAFT対象の応答はstatus=CANCELLEDを返す契約だが、DBのstatusDRAFTのままで読み直しても再現できない点にも注意)。判定根拠はsrc/main/resources/mapper/FlightPlanMapper.xmlfindByIdsearchdeleted_at IS NULLで絞っていること(PR #138時点)flight-plan-er.mdの「一時保存は専用テーブルで表す」(DRAFTからのキャンセルは削除と同等に扱う)Issue #132
実体未作成AssetRepository/PilotRepositoryは1件ずつfindByIdIncludingDeleted等を呼ぶ設計のため、飛行計画一覧のようなN件のマスタ解決が必要なユースケースを実装するとN+1になる(計画50件・各2操縦者・各3機体で1回のGETが250クエリ)。またregisterAsset/AssetUasAttrs/AssetUasDipsAttrsの3つを束ねる一方、読み取りは呼び出し側が3回呼び出して自ら組み立てる非対称な設計になっている。findAllByIdsIncludingDeletedのような一括取得メソッド、またはUAS専用の集約ルート導入で解消できるが、forDemoでは本Repositoryの消費者が存在せず実害が無いため、CRUD・飛行計画からの本格的な参照を実装するタイミングで見直すAssetRepository.javaのjavadoc。判定根拠はPR #164のレビュー(t-kuri、2026-09-03)未対応
出典不一致収集した飛行計画の識別名称を、模擬DIPSの04応答から常には得られない。DIPS_FLIGHT_PLAN.identification_nameはDIPS2.0ガイドラインの項番4(identificationName)を想定してNOT NULLとしているが、模擬DIPSの04応答の飛行計画名称(name)は「自アカウントの飛行計画のみ出力」の区分で、他USSの計画では欠落する(tests/mocks/mock-dips/flightplan-spec.mdの04レスポンス表)。収集は他USSの計画が主対象で欠落は正常系のため、実装(CollectedFlightPlanFactory)はDIPS側の飛行計画IDで代替している(項目が空文字で返る場合もPortはOptionalの値ありとして扱うため、空白のみの値は欠落と同じ扱いにしている)。本番DIPS2.0で項番4が全ユーザー向けに返るのかを確認し、返らないなら代替値の妥当性(画面表示の要否を含む)を決める必要があるflight-plan-er.mdの「図2 カラム補足」(DIPS_FLIGHT_PLAN.identification_name未対応
実体未作成raw_payloadが「DIPS応答の当該計画分の原文」になっていない。DipsApiClientは応答本文を持ち回らず型付きモデル(DipsFlightPlanSummary)だけを返すため、収集側(CollectedFlightPlanFactory)は項目名と入れ子をDIPS側に合わせて再構成した値を格納している。由来の節が挙げる「DIPS側の項目追加を吸収する」用途はこの形では満たせない(DTOに宣言のない項目は変換時に捨てられる)。満たすにはPortまたはアダプターで生JSONを保持する経路が必要で、その際も自アカウント限定項目(個人情報)の除去は維持するflight-plan-er.mdの「raw_payloadjsonb)に応答原文を保持する理由」未対応
OAS反映飛行開始予定日時の範囲チェックをcreateFlightPlan(飛行計画仮登録)でも行うかが、OASと業務ロジック仕様・実装で食い違っている。OASのFlightPeriod.startTimeのdescriptionは「UTM側もcreateFlightPlanupdateFlightPlanregisterFlightPlanのいずれでも検証する」としているが、仮登録は入力途中の内容をそのまま保存する設計のため内容検証を一切行わず(由来の手順1、実装はsrc/main/java/com/intent_exchange/utm/usecase/CreateFlightPlanUseCase.java)、範囲チェックは本登録(registerFlightPlan)とACCEPTED以降の更新(updateFlightPlan)でのみ通る(実体はsrc/main/java/com/intent_exchange/utm/usecase/FlightPlanContentAssembler.javarequireStartAtWithinAllowedRange)。仮登録でも検証する(DRAFTは入力途中の内容を保存できるという設計方針と衝突する)か、OASのdescriptionを実態に合わせて直すかを決める必要がある。flight-planning.yamlFlightPeriod.startTimeのdescriptionとBusinessLogicSpecifications.mdの「UC-PLAN-01 飛行計画を作成する」1(飛行計画仮登録)未対応
OAS反映pilotInfo[].aircraftIdsに重複した機体IDを指定でき、違反が他の内容検証と異なり500になる。OASのPilotAssignmentInput.aircraftIdsminItemsのみでuniqueItemsを宣言しておらず、ドメイン(src/main/java/com/intent_exchange/utm/domain/model/PilotAssignment.javaのコンパクトコンストラクタ)・本登録時の入力項目チェック(src/main/java/com/intent_exchange/utm/usecase/FlightPlanContentAssembler.javaparsePilotAssignments)のいずれも重複を弾かないため、書き込み時にFLIGHT_PLAN_PILOT_ASSIGNMENTのUK(由来の行。実体はdb/schema/flight_planning.sqluq_flight_plan_pilot_assignment)へ抵触する。1要素内の重複だけでなく、同じpilotIdの要素を複数並べて機体を重複させた場合も同じ制約に抵触する。抵触はDataAccessExceptionRepositoryExceptionFlightPlanRepositoryImpl.insertRevision)→500(src/main/java/com/intent_exchange/utm/handler/GlobalExceptionHandler.javahandleRepository)となり、他の内容検証がすべて422を返すのと食い違う。選択肢は(a)OASにuniqueItemsを宣言する(生成コードがSetへ写して黙って重複を落とすか、Bean Validationとして422になるかは要確認。生成物は.gitignore対象のため./gradlew openApiSyncToSrc後のPilotAssignmentInput.javaで再現する)、(b)入力項目チェックで重複を検出して422にする、(c)重複を許容し保存前に一意化する、のいずれか。飛行計画更新(updateFlightPlan)も同じ検証・書き込み経路を通るため、登録・更新の両方に効く箇所で決める必要があるflight-plan-er.mdの「図1 カラム補足」(FLIGHT_PLAN_PILOT_ASSIGNMENTの(UK)の行)とflight-planning.yamlPilotAssignmentInput.aircraftIdsPR #221のレビューで検出未対応
実体未作成飛行計画削除のIdempotency-Key再送契約(同一キーの再送に最初の実行結果を204で返す)を支える機構がない。削除がforDemoの実装対象に入った(ArchitecturePolicy_Flightplanning_forDemo.md冒頭「対象範囲」)一方、キーの保存先・保存内容はIssue #132で未決である。削除は論理削除済みの行をfindByIddeleted_at IS NULLで絞る。src/main/resources/mapper/FlightPlanMapper.xml)で読めないため、横断機構が応答を再生せず対象行を読み直す方式になると再送が204ではなく404になる。同じ懸念をcancelFlightPlanについて記した本台帳の行(DRAFTからのキャンセル)と根は同一だが、こちらは対象APIの実装に直接かかる。機構が入るまでの間、削除の再送が404を返しうることをどう扱うかも含めて決めるBusinessLogicSpecifications.mdの「UC-PLAN-04 飛行計画を削除する」1-4・1-5Issue #132
実体未作成飛行終了予定日時が飛行開始予定日時より後であることを支えるDB制約がない。flight_plan_revisionの両カラム(planned_start_atplanned_end_at)はNOT NULLのみで両者の相関を強制するCHECK制約を持たず(db/schema/flight_planning.sqlflight_plan_revisionテーブル定義)、flight_plan_draft側は一時保存で未入力を許すため同じ2カラムがNullableである。現在の確認はドメイン層(FlightPlanRevisionのコンパクトコンストラクタ)と本登録時の入力項目チェックのみで、直接投入された行は制約をすり抜けるBusinessLogicSpecifications.mdの「UC-PLAN-01 飛行計画を作成する」2-1-2未対応
実体未作成dips_report_detailjsonb)に集約した項目のうちotherInformationinsuranceInformationは、構造・値域を検証する実体がどの層にもない。同じ列に集約する他の項目(plannedMaxTimeflightSpeedriskMitigationflightPermitApplicationInfo)は本登録・ACCEPTED以降の更新時の入力検証が必須・型・値域・項目間の整合性を見るが(実体はsrc/main/java/com/intent_exchange/utm/usecase/FlightPlanContentAssembler.javaassembleForRegistration)、この2項目は素通しで、jsonb列に付くDB制約もNOT NULLのみである。その結果、APIの型・コードの値域・OASのrequiredに適合しない値が入ると、詳細取得は当該オブジェクトを項目ごと未設定として返す。読み出し側の扱いはPR #221で決定済みsrc/main/java/com/intent_exchange/utm/handler/response/FlightPlanResponseMapper.javaconvertDipsDetail。1項目の不適合で応答全体を失敗させず、飛行計画IDと項目名をWARNログへ残す。required違反も同じ扱いとしてOASに適合しない応答を返さない)。未決なのは書き込み時の担保で、選択肢は(a)Handler境界で生成DTOへの変換とBean Validationを通してから保存する(docs/implementation-guide.md「検証の配置」に沿う形。型付きDTOを捨ててJSONを持ち回る設計そのものの見直しと同じ論点)、(b)この2項目もカラム化する、のいずれか。読み出し側で落ちた事実は応答からは区別できず(未入力と同じ形で返る)ログにしか残らないため、書き込み時に不適合を弾くまではデータの取り違えが起こりうるflight-plan-er.mdの「DIPS通報固有の属性は飛行計画本体から分離する」(dips_report_detailjsonb)に集約する項目の範囲)。判定根拠はPR #221のレビューで検出未対応
OAS反映他Operator向けのareaType/dataTypeの値域に、DIPSから収集した計画では取りえないROUTEOPERATIONAL_INTENTが含まれたままである。FlightPlanAreaPropertiesallOfOtherFlightPlanAreaPropertiesを継承しているため、親側で値域を狭めると自組織向けからも失われ、allOfは交差のため子側で広げ直すこともできない(statusの必須を外したPR #219が当たったのと同じ構造上の制約)。PR #228では返却されない旨をdescriptionへ明記するにとどめ、bufferMのように親から子へ移せるプロパティのみ実際に取り下げた。値域そのものを分けるにはスキーマの継承関係の見直し(共通の基底を切り出して兄弟にする等)が必要で、影響が自組織向けの契約と生成コードにも及ぶため見送っているgeospatial-api-design.mdの6.2節「飛行計画領域(他Operator)検索」未対応
実体未作成plan_geometry_wgs84operational_intent_geometry_wgs84に3次元を要求するCHECK制約がない。対になるtop_bottom_3d_geometry_wgs84ST_NDims = 3を課しているが(db/schema/flight_planning.sqlck_flight_plan_area_top_bottom_3d_geometry_wgs84)、前2列の制約はSRIDのみである。GeoSpatialの飛行計画領域検索はaltitudeReference=WGS84のFeatureのZ値をこの列から読むため、換算値の充填処理が2次元のジオメトリを書くと、GeoJsonGeometryCodecが高度の欠落を検知して例外にする(充填処理はPR #250・PR #276で実装済みになったため、この経路は潜在的なものではなくなった。読み出し側が*_wgs84列を3次元前提でST_Force3Dを挟まずに返すことはsrc/main/resources/mapper/FlightPlanAreaSearchMapper.xmlの冒頭コメントが明示している)。影響は該当する1計画に限られるFlightPlanAreaRepositoryImpl.toViewが当該行をログに残して結果から除外し、他の計画は返す方針を採っているため。検索全体が失敗するわけではない)。充填処理の実装時に、書き込み側で3次元を保証するCHECK制約を足すflight-plan-er.mdの「高度は換算値をカラムに保持する」未対応
実体未作成DIPS通報状態(report_status)の現在値の導出が2箇所にあり、参照するスコープが異なる。FlightPlanAreaSearchMapper.xmlflight_plan_id単位(DDLのFLIGHT_PLAN_STATE_EVENT冒頭が定める導出定義に合わせたもの、設計文書もこの単位で書く)、FlightPlanMapper.xmlfindLatestReportStatusAfterflight_plan_revision_id単位で絞ってから最大seqを採る。flight_plan_state_event.flight_plan_revision_idは仮登録時などNULLを取りうるため、最大seqのイベントがNULLリビジョンだと同じ計画のreportStatusが飛行計画領域検索と飛行計画詳細取得で違う値になりうる。導出単位が違うと、通報後に飛行計画を更新して新リビジョンができた場合の現在値も両者で異なりうる。どちらを正とするか(実装に合わせて文書を直すか、文書に合わせてSQLを直すか)を決めたうえで、導出を1箇所(共通のsqlフラグメントか導出列)へ寄せる。あわせてflight-plan-field-mapping.mdの「管理・状態系フィールド」(reportStatusの行)は「最新イベントの値」とだけ書き導出単位に触れていないため、単位を決めたうえで併せて補記する必要があるflight-plan-er.mdの「図1 カラム補足」(FLIGHT_PLAN.statusの導出キャッシュの記述)とdb/schema/flight_planning.sqlFLIGHT_PLAN_STATE_EVENTの「現在値の導出」コメント(同じ段落のstatusの導出と並べて書かれており、リビジョンでの絞り込みに言及していない)未対応
実体未作成海上ではAGLの基準面が「海面」ではなく「海底」になる。GSJの標高タイルセットは海陸シームレスで、aglToAmslMetersAltitudeConverterImpl)は地表標高(水深のある地点では海底の深さ)にAGLを足したものをそのままAMSLとして返すため、実際の対水面高度より過小に算出される(安全側ではない方向)。海上でAMSL・WGS84楕円体高を安全判断(離着水・水上での低高度飛行等)に使う要件が具体化した時点で対応する。解法自体はレビューで確認済み(海上と分かっている地点は地表標高を0とみなせばAMSL = AGLWGS84楕円体高 = AGL + ジオイド高になる)で、ボトルネックは対象地点が海上かどうかの判定手段が無いこと(現状のDEMは水深が既知でも「海である」ことを明示的には区別できない)elevation-service-design.md9章「既知の制限・今後の課題」未対応
出典不一致地表標高データ(GSJ統合DEM)の出典・利用条件が未確認。GSJ(産業技術総合研究所 地質調査総合センター)の統合DEM(mixed)シームレスタイルは、「国土地理院の標高タイル(基盤地図情報数値標高モデル)」・「ASTER GDEM」・「GEBCO Grid」等を統合した合成データセットであり(https://tiles.gsj.jp/tiles/elev/tiles.html「統合DEM (Mixed)」の出典表)、単一の出典ではない。GSJ自体の利用条件に加え、構成データセットごとに利用条件が異なりうる(国土地理院分は「国土地理院コンテンツ利用規約」が適用されると同ページに記載)。測量法第29条・第30条に基づく国土地理院長への承認申請が必要となる要件(ジオイド・モデルを組み込んだソフトウェア開発、不特定多数への提供)に本PRの用途が該当するため、申請issue #258を起票済み。承認が得られるまで、Git LFS等でデータをリポジトリ・コンテナイメージへ内蔵する判断(レビュー提案。全国10mメッシュ化時はGB級になりコンテナイメージ肥大化の問題も別途生じる)は見送るelevation-service-design.md2章「背景・決定事項」、docker/elevation-data-prep/README.mdIssue #258Issue #258
実体未作成模擬DIPSが必須とする通報者(reporter.contactReporter。氏名・国・都道府県・住所・電話番号・メールアドレス)を保持するマスタがUTM側に無い。asset.pilotは操縦者であって通報者ではなく、FLIGHT_PLAN_DIPS_ATTRS.contact_emailはメールアドレスしか持たない。10月デモはIX-UTM共通のクライアント証明書で通報しDIPS上の通報者が全Operatorで同一になるため、設定値の固定値として持たせることにした。α版以降にOperator個別の認証へ戻す際は、通報者をOperatorごとに解決する仕組みが要るflight-plan-field-mapping.mdの「通報者(reporter)は設定値で送る」(11-5節)決定済み
実体未作成模擬DIPSが必須とするpilotInfo[].privateLicense(技能認証保有状況)に対応するカラムがasset.pilotに無い。同テーブルが持つのはfirst_class/second_class(技能証明の一等・二等)だけで、これらとは別軸の項目である。10月デモは固定値を送ることにしたflight-plan-field-mapping.mdの「模擬DIPSにのみ存在する項目」(11-2節)決定済み
出典不一致飛行計画通報時の重複の扱いが出典間で食い違う。模擬DIPSのAPI一覧は「重複と判定された場合は登録失敗」とするが、実機の実行結果ではHTTP 200で登録が成功し、重複相手が通知されている。仕様変更なのか一覧の記載が古いのかが未確認で、模擬DIPSへの照会事項。両方の出典と値は由来の文書にある「ReAMo 模擬DIPSインタフェース仕様」05 飛行計画通報API。写しはflightplan-spec.mdの「未確定事項」未対応
出典不一致模擬DIPSの日時項目にタイムゾーンの記載が仕様書上は無く、JSTと推測して照会事項としていたが、先方への確認によりUTCと判明した(本番DIPS2.0のJSTとは異なる)。startTime等の解釈はこの確定値に従う「ReAMo 模擬DIPSインタフェース仕様」05 飛行計画通報API。確認結果はflightplan-spec.mdの「未確定事項」(タイムゾーンの行)決定済み
出典不一致ロック競合(lock_timeout超過)で返すProblem Detailのtypeが、方針文書と実装・OASで食い違っている。方針文書は/problems/version-conflictとするが、この値は実装のProblemTypesに定数が無く(grep -rn "version-conflict"が方針文書1件のみ)、実装はProblemTypes.BUSINESS_RULE_VIOLATIONを返し(src/main/java/com/intent_exchange/utm/handler/GlobalExceptionHandler.javahandleFlightPlanConflict)、OASの409も/problems/business-rule-violationを例に持つ(docs/openapi/problem.yamlLockConflict)。方針文書側を実装・OASへ合わせるのが妥当だが、方針文書は本台帳のpaths外の所有物であるため別途反映が要るArchitecturePolicy_Flightplanning_forDemo.mdの「20.1 ロック対象・範囲」(lock_timeout超過の記述)未対応
OAS反映422で返す/problems/business-rule-violationが、OASの422応答の例に無い。reportFlightPlanreportRequired=falseのとき422・/problems/business-rule-violationを返すとdescriptionで宣言している一方、"422"が指す共通応答(problem.yamlValidationError)のexamples/problems/invalid-input/problems/idempotency-key-conflictの2つだけで、このtypeの例が無い。クライアントが422のtypeを判別する手掛かりが例から得られないため、ValidationErrorに例を足すか、reportFlightPlan側に専用の422応答を持たせるかを決める。解消済み。 reportRequiredは通報が必須かどうかを表すフラグであって通報の可否を決めないため、reportFlightPlanreportRequired=falseを業務ルール違反として弾く仕様自体を取り下げた(PR #225のレビュー指摘)。同APIの422はIdempotency-Keyの再利用(/problems/idempotency-key-conflictValidationErrorに例がある)だけになり、例の欠落は残らないflight-planning.yamlreportFlightPlandescription"422"応答、およびproblem.yamlValidationError決定済み
出典不一致模擬DIPS連携の接続情報にフォールバック値がある。ArchitecturePolicy_Flightplanning_forDemo.md8節が「外部サービスのホスト名・エンドポイントに既定値を組み込まない。明示的な設定を必須にする」と定めるのに対し、src/main/resources/application.yamldips.api.uss-idは既定値を持つ。環境ごとの設定漏れが起動時に検出されず、意図しない値で通報しうる。どちらを正とするか(方針を緩めるか、既定値を外すか)を決める必要がある。dips.api.hostの既定値はPR #143で削除し「空の既定値+使用箇所での検証」に改めた(docs/issues/issue-143-dips-base/open-questions.md E-18)。MQTT側(dips.mqtt)は下記他ドメイン合意の行で扱うArchitecturePolicy_Flightplanning_forDemo.mdの「設定ファイル方針(飛行計画固有)」(8節)未対応
他ドメイン合意MQTTブローカーの接続先に実ホスト名の既定値が入っている。src/main/resources/application.yamldips.mqtt.hostterraform/modules/coordination/app/compose.ymlDIPS_MQTT_HOSTがいずれも実ホスト名をフォールバック値に持つため、設定漏れに気づかないまま他社が運用する検証環境へ接続を試みうる。REST側(dips.api.host)はPR #143で「空の既定値+使用箇所での検証」に改めた(open-questions.md E-18)ので、MQTT側も同じ形にするのが筋だが、重複通知受信(MQTT)は運航調整機能(issue #108)の持ち物であり、既定値を外すには有効化時の設定投入とTerraform側の追随、および空ホストを起動時に弾くガード(DipsMqttPropertiesは現状ssl://:8883を組み立ててしまい、失敗が非同期の接続時まで遅れる)が要る。文書側の実ホスト名はPR #225で${DIPS_MQTT_HOST}へ置換済み。設定・コードの変更は運航調整側と合意して行うPR #225のレビュー(@nshingo の指摘)とdocs/issues/issue-143-dips-base/open-questions.mdのE-18未対応
実体未作成area_type=ROUTEの通報で、自己交差する経路のバッファ結果がMULTIPOLYGONになった場合の挙動が未確認。通報へ送る外周リングはST_ExteriorRingで取り出すが、同関数は仕様上POLYGON以外でNULLを返すため、結果がMULTIPOLYGONだとリングが空になり、データがあるのに「形状が読めない」データ不整合(500)として扱われうる。ST_Bufferのパラメータ(join=mitre)で実際にMULTIPOLYGONが生じるかはPostGISの実挙動次第で未実測であり、まず8の字状の経路で実測したうえで、テストを追加するか設計上許容するかを決めるflight-plan-er.mdの「通報前の形状の取り出し」とdocs/issues/issue-225-dips-notify/detailed-design.md8-1節。指摘はPR #225のテスト十分性レビューのGEO-1未対応
出典不一致DIPS連携の異常系(502/503/504)をどの層のテストで担保するかが方針文書間で食い違っている。ArchitecturePolicy_Flightplanning_forDemo.md17節は「異常系はPortの実装(DipsApiClientImpl)に対するテストで賄う」とする一方、TestPolicy_Flightplanning_forDemo.mdのUnitテスト(Handler層)の観点は「HTTPステータスの反映」を挙げており、エンドポイント経由での確認が要るとも読める。現状はハンドラーメソッドの直接呼び出し(GlobalExceptionHandlerTest)までで、@RestControllerAdviceの結線は通っていない。どちらを正とするかを決めないと、テストの欠落なのか意図した省略なのかが判断できない。方針文書は本台帳のpaths外の所有物であるため別途反映が要るArchitecturePolicy_Flightplanning_forDemo.mdの「17. 外部サービス連携」とTestPolicy_Flightplanning_forDemo.mdの「2. Unitテスト」Handler層。指摘はPR #225のテスト十分性レビューのIF-1(a)未対応
出典不一致飛行する高度(flightSpec.altitude / DIPSのflightAltitude)の値域が出典間で食い違う。DIPS APIガイドラインと模擬DIPSインタフェース仕様で上限が異なり、実装は狭い方を採るため(src/main/java/com/intent_exchange/utm/domain/model/DipsFlightAltitudeMeters.java)、OASの値域では登録できる高度の飛行計画が通報時にIllegalStateExceptionとなる(src/main/java/com/intent_exchange/utm/usecase/DipsFlightPlanReportFactory.javainRange)。どちらが正かはDIPSへの照会事項。両方の出典と値は由来の★印の記述にあるflight-plan-field-mapping.mdの「DIPS側の入力チェックとAPI制約の対応」(★飛行する高度の範囲も出典間で食い違っている)未対応
実体未作成概念モデル(utm-design-docs/docs/data-model/data-model.mdの「空域制限ドメイン」)のgeometry_typeの列挙値にMULTIPOLYGONがない。OAS(geospatial.yamlAirspaceGeometryType)とGeoSpatialのAPI設計は3値で、本設計も3値を採る。上位の概念モデル側の追加が要る(geospatial-api-design.mdの5.2節が「別リポジトリdata-model.md側の対応が必要」と既に指摘している)airspace-er.mdの「図1 カラム補足」(AIRSPACE_RESTRICTION.geometry_typeの行)未対応
実体未作成概念モデルのAIRSPACE_RESTRICTIONが持つ高度の列が2列(min_altitude_m / max_altitude_m)で、基準(AGL/AMSL/WGS84)の区別も単位・基準の宣言も持たない。本設計は基準ごとに分けた6列とaltitude_unitaltitude_referenceを持ち、いずれもNULL可(高度の概念がない種別・高度を提供しないソースがある)とするため、概念モデル側の追随が要るairspace-er.mdの「高度は床面と天面を格納する」未対応
実体未作成収集時の無変更判定(no-op判定)に使うハッシュのアルゴリズムと格納型が未定。差分を検知できれば足り、暗号学的ハッシュ関数は要件ではない(衝突を意図的に作る攻撃者を想定しない)。JDK標準のSHA系で数・計算量が問題ないならそれでよく、そうでなければ軽量なハッシュ関数(commons-codecの実装やFNVなど)を選ぶ。格納型はアルゴリズムの出力幅に従って決める(32bitならintegerで足りる)。算出対象のカラムとgeometryの正規化規則(頂点順序・精度の揺れを吸収するか)もあわせて決める必要があり、決まらないと同じ内容でも異なる値になり判定が働かない。該当列は最小モデルに持たないため、収集を実装する時点で決めるairspace-er.mdの「スコープ」(取得元レスポンスの原文・無変更判定のハッシュを採用しない行)未対応
他ドメイン合意「数量の単位を列名に書くか専用カラムへ外出しするか」のバックエンド共通規則がない。conventions.mdの命名規約に単位の項目自体がなく、現状は高度だけが専用カラム(altitude_unit)で、水平距離(radius_m / buffer_m / circle_radius_m。単位を名前に持つ列はこの3つのみ)は列名に単位を持つ。「将来の単位変更に備える」というaltitude_unitの根拠は水平距離にも等しく当てはまるため、この根拠では両者を区別できない。実際に区別できるのはGeoJSONの座標配列(RFC 7946のPosition)に要素名がなくZ値の単位を宣言する場所が他にないという理由だけである。これはドメイン単位で決めるべきことではなく、3つ目のドメインで再び揺れるため、共通規則として決める必要があるairspace-er.mdの「高度カラムだけが単位を列名から外す」未対応
OAS反映高度値のカラム名から単位を外出しした結果、DBのカラム名とOASのプロパティ名が食い違う。空域制限ドメインも飛行計画と同じ命名(max_altitude_agl)を採ったため、OASのAirspaceRestrictionProperties.maxAltitudeMAgl等との食い違いが同じ形で生じている。飛行計画側についてPR #211が登録した同種の項目と一体で決める(OAS側を揃えるかは破壊的変更で、GeoSpatialの応答は未提供のため提供開始前に決める前提)airspace-er.mdの「図1 カラム補足」(高度カラムの命名の記述)未対応
実体未作成空域制限のnamedescriptioninfo_urlの桁数がDIPS側の上限に追随しているか未確認。本設計はnameVARCHAR(255)、他2列をTEXTとしたが、根拠はOAS(geospatial.yamlAirspaceRestrictionPropertiesmaxLengthの宣言を持たない)のみで、DIPS FPRガイドラインの飛行禁止エリア情報取得APIにおける各項目の桁数を確認していない。PILOT.nameASSET.modelで同種の緩さが既に問題になっているため、DIPSの上限を確認して狭めるかを決めるairspace-er.mdの「図1 カラム補足」(name / description / info_urlの行)未対応
実体未作成空港周辺の制限表面のうち円錐表面・転移表面のような曲面を、頂点ごとのZ値を持つPolygonMultiPolygonで十分に近似できるかが未検証。頂点ごとのZ値は平面ファセットの集合であり、曲面は多数のファセットへ分割するしかない。分割数の決め方(許容誤差)と、geometryの構成点数の上限に収まるかを、実データの仕様が固まってから判断する。この曲面近似の論点自体は由来の節にまだ書かれておらず、頂点ごとのZ値で天面の変化を表す設計方針からの派生として本台帳で気づいた事項であるairspace-er.mdの「上面・下面は3次元のgeometryで持つ」(制限表面で頂点ごとにZ値が異なる旨の記述)未対応
他ドメイン合意空域制限のAPIが床面(floor)を返すかが未決。AirspaceRestrictionFeatureは「geometryは天面を表し、床面は返却しないためクライアント側で地表面に沿わせて表示する」と定めており、飛行計画のdataType=TOP_BOTTOM_3Dに相当するFeatureを持たない。一方でDB側はAIRSPACE_RESTRICTION.top_bottom_3d_geometryに上下面を持つ(傾斜した制限表面を表すために必要)。APIも上下面を返す形へ寄せるかはGeoSpatialの応答契約の変更になるため、実データの仕様が固まってから決めるairspace-er.mdの「上面・下面は3次元のgeometryで持つ」未対応
実体未作成空域制限のgeometry列が空のジオメトリを許す。DDLのCHECK制約は種別(POLYGONまたはMULTIPOLYGON)とSRIDだけを見るため、面を持たないPOLYGON EMPTYが格納でき、CHECKも通る(PostGIS 18-3.6で実測。GeometryTypePOLYGONST_SRIDは4326を返す)。一方アプリ側はリングを持たない形状を表現できず、読み出しが失敗する(src/main/java/com/intent_exchange/utm/infrastructure/persistence/postgres/WktCodec.java:135で拒否し、src/test/java/com/intent_exchange/utm/infrastructure/persistence/postgres/WktCodecTest.java:164が固定している)。空を許さないCHECK制約(ST_IsEmptyが偽であること)を足すかを決める必要がある。同じ論点は飛行計画ドメインのgeometry列にもあるairspace-er.mdの「geometryの次元は縛らない」未対応
実体未作成人口集中地区(DID)を空域制限との競合判定の対象に含める方針は決まったが、それを支える行がまだ無い。10月デモの間はck_airspace_restriction_no_didがDIDの行を禁じており、AIRSPACE_RESTRICTIONにDIDが存在しないため、BusinessLogicSpecifications.mdの競合判定はこの種別を検出できない。配信のためのデータと判定のためのデータは役割が別であり、静的PMTilesで配信していることは判定の対象から外す理由にならないPR #262のレビュー)。デモ以降に本制約を落とし、DIDの行を投入する経路(GSI提供のデータセットの取り込み)を用意する必要がある。同じ性質の分類(レッドゾーン・イエローゾーン)は既に行を持つため、判定側の実装変更は不要であるairspace-er.mdのD2未対応(10月デモ以降)
実体未作成statusACTIVEDISAPPEARED)を遷移させる主体がいない。取得元の取得結果から消失したことを検知するのは収集処理であり、本設計は収集を実装しないため、投入後にDISAPPEAREDへ移る経路がない。あわせてsource_kind=MANUALの行における「消失」の定義(誰がどの条件で消失とみなすか)も未定である。収集の実装時に、遷移の契機とMANUAL行の扱いをあわせて決めるairspace-er.mdの「図1 カラム補足」(statusの行)未対応
実体未作成AMSL・WGS84の換算値スカラー4列、およびgeometry_wgs84top_bottom_3d_geometry_wgs84(決定事項D3-2)を、収集(external_idキーのUPSERT等)の実装時に自動で充填する処理がない。地表標高(DEM)・ジオイド高の取得経路も未決のため、収集を実装するまではアプリ側で埋める手段がなく、事前投入(db/seed/)で直接値をロードする経路にのみ依存する。充填処理を実装する際に、スカラーと形状をあわせて判断する。飛行計画ドメインでは同じ構造が不具合報告として表面化した。 列も換算経路も実装済みだったが呼び出し側が欠けていたため_wgs84列がNULLのままになり、issue #271が「OASの記述と違ってaltitudeReference=WGS84のFeatureが返らない」として報告した(PR #276で解消)。空域制限は事前投入が唯一の充填手段であるため、投入データがこの6列を埋めない限り検索APIはWGS84のFeatureを返さず、検索APIを提供するPR #260(PR-04)以降に同じ形の報告が起こりうるairspace-er.mdの「高度は床面と天面を格納する」未対応
実体未作成source_kind=MANUALの行を再投入する際の同一性判定が投入手順に依存している。external_idがNULLのためON CONFLICT (external_id)では突き合わせられず、既存のidを引き継いで更新する必要がある。db/seed/の規約は冪等性のためDELETE→INSERTを求めており(db/README.md)、そのまま適用するとidが振り直されてflight_planning.conflict_detectionからの参照が切れる。アプリケーションはidの安定性を保証せず投入する側が担保する方針のため、投入手順の側で規約との整合を取る必要があるairspace-er.mdの「idの安定性は投入する側が担保する」未対応
他ドメイン合意issue #248のデモ向け追加データ(機体2件・操縦者2件)をdb/seed/local/asset_sample_data.sqlへ投入したが、添付データの機体ID2件が不正なUUID、操縦者ID2件が既存の評価用データ(山田太郎・鈴木花子)のIDと衝突していたため、新規UUIDv4を採番し直して登録した。既存の固定ID運用(本台帳の「forDemoでは機体・操縦者のAsset APIを提供せず」の行)と同様、フロントエンドが機体・操縦者IDを直接保持するため、採番し直したIDをフロントエンドチームへ共有し、合意を得る必要があるasset_sample_data.sqlの「追加分(issue #248)」節Issue #248
実体未作成GlobalExceptionHandler.handleIllegalArgumentIllegalArgumentExceptionを400へ変換する共通ハンドラ)にlog.errorが無く、クライアント起因以外(実装のバグでスローされた場合)でもサーバ側のログに残らない。GeoSpatialの飛行計画領域検索PRのレビューで指摘されたが、本ハンドラは飛行計画・GeoSpatialに限らない全ドメイン共通のクラスであり本PRの変更範囲外のため、別PRでログ方針(他のhandle*メソッドとの一貫性を含む)を検討するGlobalExceptionHandler.javahandleIllegalArgument。PR #226のレビュー(@nshingoのsilent-failure監査S-3)未対応
実体未作成周辺計画収集の保存が1件ずつのUPSERT+INSERTで、DB往復が収集件数×2回になる。DipsFlightPlanRepositoryは1行単位のメソッド(upsertCollectedFlightPlaninsertNearbyLink)しか持たず、RefreshNearbyFlightPlansUseCase.storeがそれを収集件数ぶんループするため、書き込みトランザクションがdips_flight_planの行ロックを保持する時間が件数に比例して延びる。複数行VALUES ... ON CONFLICT ... RETURNINGでまとめれば往復は2回に収まるが、RETURNINGは入力順を保証しないため、返ったdips_flight_plan_idをキーにリンクの相手を突き合わせる実装が要る。forDemoはDIPS側の返却上限で打ち切りが起きない規模を前提とする(BusinessLogicSpecifications.mdの4.4節)ため実害は小さく、一括取得・一括書き込みのメソッドをPortへ足す規模になることからPR #229では見送った。上限値は由来を参照flight-plan-er.mdの「取得漏れ(DIPS側の返却上限)はデータモデルに持たない」。判定根拠はPR #229のレビュー(@nshingo、2026-09-11)未対応
実体未作成空間インデックスが実際に使われることを確認できていない。空域制限との競合判定が発行するST_DWithingeometry::geographyの式インデックス)・ST_IntersectsgeometryのGiSTインデックス)について、述語を索引の効く形(CASE式に包まずUNION ALLで枝を分け、索引が張られた式をそのまま参照する)で書き、その形はAirspaceRestrictionMapperBoundSqlTestが固定している。ただしプランナは述語の形だけでなく行数と統計にもとづくコストで索引を選ぶため、形が正しいことは索引が使われることを意味しない。確認するにはテストデータを本番相当の規模にしたうえで実行計画を見る必要があり、現在のテスト(統合テストは数件、BoundSqlテストはDB接続なし)はその規模を作っていない。索引そのものはPR-11で追加済み(本表の式インデックスの行)airspace-er.mdの「検索条件に合わせて索引を張る」。判定根拠はsrc/test/java/com/intent_exchange/utm/infrastructure/persistence/postgres/mapper/AirspaceRestrictionMapperBoundSqlTest.javaのクラスJavadoc未対応
実体未作成DBのenum型とJavaのenumの値域が一致していることを検査していない。両者を揃えることはコーディング規約でしか縛られておらず、食い違いはビルドでも型検査でも分からない。現れるのは実行時で、DB→JavaはEnum.valueOfの失敗(収集元起因のデータ不整合ではなく実装バグのため、空域制限との競合判定では詰め替えずそのまま伝播させる)、Java→DBは#{...}::<enum型>のキャスト失敗になる。どちらもその値を通る経路を踏んだときにだけ起きるため、テストデータに含まれない値のズレは本番まで残りうる。現時点でDDLは39のenum型を定義し、うち34組がドメインのenumと値域が一致する(coordinationの5型はDB側がPascalCaseでEnumDbNamesが変換する。残る5型は単位や未実装の収集処理向けでJava側に対応を持たない)が、この対応関係はコードのどこにも宣言されていない。検査の作り方は2案ある。(a) db/schema/*.sqlをパースしてJavaのenumと突き合わせる単体テスト。DB不要で常に回るが、見るのはDDLのテキストであって適用済みDBではない。(b) pg_enumを読む統合テスト(Testcontainers。共通のTestcontainersConfigurationdb/schema/をそのまま適用する)。適用済みスキーマを見られるがコンテナ起動を伴う。いずれも「どのJava enumがどのDB型に対応するか」の対応表を人が保つ必要がある。飛行計画に限らない全ドメイン横断の変更のためPR #262では見送ったairspace-er.mdの「制限分類の列挙値は1つに統一する」。判定根拠はPR #262のレビュー(@nshingo、2026-09-15)未対応
実体未作成飛行計画削除の手順1-2が定めるDIPS取り下げ(reportStatus=REPORTEDの場合に論理削除へ先立って行う)を実行する手段がない。模擬DIPSに飛行計画の削除APIが無いため取り下げ用のPort・UseCaseを持たず、通報済みの飛行計画を削除するとDIPS側の登録が残る。飛行計画通報(reportFlightPlan)の実装によりREPORTEDが到達可能になり、由来の4.6節が「発生しない」としていた前提は成立しない。削除可否の判定軸は手順1-1のとおりstatusのみであり、REPORTEDでも削除できること自体は仕様どおりである(手順1-5の409もACTIVATEDENDEDとロック競合に限る)。取り下げが可能になったとき(模擬DIPSへの削除API追加、または本番DIPSへの接続)に手順1-2とその失敗時の扱い(1-2-4は飛行計画自体を削除せず削除失敗を返すと定める)をUseCaseへ実装する必要があるが、statusの判定漏れが網羅switchのコンパイルエラーで防がれるのと違い、取り下げの欠落を知らせる仕組みはコードに無い(判定箇所はDeleteFlightPlanUseCasedoDeleteメソッドの網羅switch)。テストでも守れない。 UseCaseがロックして読むのはFlightPlan(ヘッダ)だけで、reportStatusFLIGHT_PLAN_REVISION側が持つ導出値のため(FlightPlanRevisionreportStatus成分。FlightPlanには同名の成分が無い)、現在のコード形では通報済みかどうかを参照する経路そのものが無く、「通報済みなら取り下げを先行させる」という仕様を検証するテストを書けない。取り下げを実装する際は、UseCaseが現在リビジョンを読む形へ変えることとあわせて決める。そのため同ファイルにTODO(DIPS取り下げ)を置いて本台帳と相互参照させている。REPORTING中の削除も同じ窓に入る。 ReportFlightPlanUseCaseはADR-022により外部呼び出しのあいだ行ロックを手放すため(executeメソッド)、REPORTINGのまま本ユースケースがロックを取得でき、論理削除が成立する。確定側のガード(requireStillReportingメソッド)が論理削除を弾くためデータ不整合には至らないが、DIPS側に登録が残る一方で受付番号(DIPS側の登録を指せる唯一の識別子)がUTM側に残らないため、取り下げが可能になってもREPORTING中に削除された計画だけは対象を指せない(REPORTEDで削除した場合はDIPS_REPORT.dips_receipt_noが残るのと対照的である)。通報を開始した事実自体はTx1でコミット済みのREPORT_STARTが残るため、抽出自体はできる。この経路では警告ログも出ない。 ガードが投げるのはFlightPlanNotFoundExceptionである一方、acquireForConfirmationrecordFailureのcatchはFlightPlanInvalidTransitionExceptionだけを対象とするため、acceptedButNotRecordedfailureNotRecordedのいずれも記録されず、タイムアウト等の元の例外もFlightPlanNotFoundExceptionに置き換わって失われる。REPORTINGを削除可否の判定に加えて409で弾く案は採らない。 504(成否不明)ではreportStatusREPORTINGのまま保持する設計であり滞留からの復帰手段が無いため(ADR-022の残課題)、弾くと一度504を受けた飛行計画が恒久的に削除できなくなる。残る論点は「確定側が論理削除済みを検出したときに受付番号を記録して終えるか、警告ログに留めるか」であり、ReportFlightPlanUseCase側の積み残し(detailed-design.mdの積み残し#8)として別PRで決めるBusinessLogicSpecifications.mdの「飛行計画削除におけるDIPS取り下げの非対応」(4.6節)・「UC-PLAN-04 飛行計画を削除する」1-1・1-2未対応
実体未作成周辺飛行計画リンク(FLIGHT_PLAN_DIPS_NEARBY_LINK)を開放する処理が、飛行計画更新にも削除にもない。由来は更新で飛行領域・飛行予定時刻が変わればリンクを削除し、変わらなければflight_plan_revision_idを新リビジョンへ張り替えると定め(「UC-PLAN-01-10 飛行計画付近の他の飛行計画を収集する」1-1)、削除では連動して物理削除すると定める(「UC-PLAN-04 飛行計画を削除する」1-3)が、UpdateFlightPlanUseCaseDeleteFlightPlanUseCaseはどちらもDipsFlightPlanRepositoryを参照していない(両クラスのprivate finalフィールド一覧)。Portも張り替え用のメソッドを持たず、リンク操作はinsertNearbyLink(追加)・findNearbyLinksByFlightPlanId(取得)・飛行計画単位の全削除の3つだけである(DipsFlightPlanRepository)。周辺データ更新(UC-PLAN-01-10)の実装によりACCEPTEDACTIVATEDの飛行計画はリンクを持つため、更新すると旧リビジョンを指したままのリンクが残り、削除しても残る。由来のER図が置く「保持するのは最新リビジョンの収集結果のみ」がこの間は成立しない。現時点で表に出る誤りはない。 リンクを読む本番経路が無く(findNearbyLinksByFlightPlanIdの呼び出しはテストのみ)、GeoSpatialの他Operator計画検索はDIPS_FLIGHT_PLANを直接読むためリンクの有無で結果が変わらず(OtherFlightPlanAreaSearchMapper.xmlsearch)、次の周辺データ更新が飛行計画単位でリンクを全削除してから入れ直すため状態も揃う。ただしリンクを読む機能が入った時点で誤りが表に出る。ENDEDCANCELLED遷移時の削除(同1-1)も該当APIが未実装のため同じ欠落に含まれる。実装時は張り替え用のPortメソッドの追加と、更新の変更判定(値そのものの比較)をあわせて決めるBusinessLogicSpecifications.mdの「UC-PLAN-01-10 飛行計画付近の他の飛行計画を収集する」1-1・「UC-PLAN-04 飛行計画を削除する」1-3、flight-plan-er.mdの「保持するのは最新リビジョンの収集結果のみ」未対応
実体未作成由来のADRが求める状態遷移の共通ヘルパーが無く、「ロック付き取得 → 論理削除の除外 → 404」の同じ8行が6箇所に重複している(src/main/java/com/intent_exchange/utm/usecase/RegisterFlightPlanUseCasedoRegisterUpdateFlightPlanUseCaseexecuteReportFlightPlanUseCasebeginReporting(通報Tx1)・同requireStillReporting(確定前の再取得ガード)・RefreshNearbyFlightPlansUseCaserequireStillCollectable(保存前の再取得ガード)・DeleteFlightPlanUseCasedoDelete。例外メッセージまで一致する)。集約できるのは取得だけである。 由来のADRは「取得 → 検証 → 保存」の集約を求めるが、検証は状態の許可リスト・網羅switch・リビジョン同一性・通報状態とばらばらで、保存も「何も書かない」から「リビジョンを進める」まで開きがあるため、束ねるとテンプレートメソッドやコールバックで呼び出し側が抽象と戦う形になる。ADRが挙げる「ロックの取り忘れ」の防止は、ヘルパーの抽出だけでは達成されない。 トランザクション外からの呼び出しはfindByIdForUpdate自体がRepositoryExceptionで弾くため既に塞がっており(FlightPlanRepositoryfindByIdForUpdateのJavadocが定める契約)、残るのは状態遷移ユースケースがロックなしのfindByIdを使う誤りだけで、これを防ぐにはArchUnitルールが要る(ヘルパーの抽出とは分けて検討する)。置き場所はusecaseパッケージの協力オブジェクト(DipsFlightPlanReportSourceLoaderFlightPlanContentValidatorと同じ置き方)とし、Portに取得と404を兼ねるメソッドを足す案は「論理削除済みでも返し、判定は呼び出し元」というfindByIdForUpdateの現在の契約を崩すため採らない。名前にはロックを残す(中立な名前にするとロックの存在が呼び出し側から見えなくなり、ADRの目的に反する)。再取得ガードの2箇所はリビジョン同一性の確認まで共通のため第2のヘルパーの候補になるが、例外メッセージが用途ごとに異なるため抽出の可否は実装時に判断する。着手は関係PR(飛行計画削除・飛行計画通報・周辺計画収集)がマージされた後とする。5ファイルに触るため並行するとコンフリクトするutm-design-docs docs/adr/ADR-019-pessimistic-lock-state-transition.mdの「方針」節(「状態遷移の共通処理(取得 → 検証 → 保存)はヘルパーに集約し、ロックの取り忘れを防ぐ」)。判定根拠はPR #223のレビュー(@nshingo、2026-09-14。同レビューは5箇所としているが、RefreshNearbyFlightPlansUseCaseを含めた実測は6箇所)未対応
実体未作成由来の規約が禁じるHTTPステータスコードの記述が、ドメイン層のPort(src/main/java/com/intent_exchange/utm/domain/port/)のJavadocに残っている。PR #223がsoftDeleteのJavadocに追加した「存在しないIDに対する404」も含め、本ブランチでは直さず別PRで扱う(同PRで一度直したが、既存分と扱いを揃えるため取り消した)。記述は2種類あり、直し方が違う。 自システムの応答コードを挙げるもの(代表例: DipsApiClientの「3種はGlobalExceptionHandlerが502/503/504へ対応付ける」。PortがHandler層のクラス名と応答コードの対応表を持つ形であり、層をまたぐ度合いが大きい。ほかにFlightPlanRepositoryにも残る)は、情報を失わずに言い換えられる。一方、外部システムが返すコードを挙げるもの(代表例: OpponentUtmClientの「対向UTMが406を返した場合はExternalUtmNotAcceptableException」、DipsApiClientの「200以外のHTTPステータス」)は、「どの外部応答がどの例外に化けるか」という呼び出し側が例外を扱うために要る対応関係を表しており、消すだけでは情報が失われる。移すならdomain.exception側など受け皿を決める必要がある。ステータスコード以外にHTTPメソッドとパスの記述もある(代表例: OpponentUtmClientの「調整開始通知(POST /uss/v1/coordination/initiations)」)。該当は外部通信のPortに偏り、内部の永続化PortではFlightPlanRepositoryに残るのみである。運航調整ドメインのPortも含むため、着手時はまず範囲(飛行計画のPortに限るか全体か)を決める。本欄は代表例だけを挙げる。 全件は着手時にdomain/port/配下を検索して洗い直す(箇所を列挙すると実装のたびに台帳側の追随が要るため)。なお種別は本台帳の4種のいずれにも厳密には当たらないが、レビュー由来で別PRへ回した実装課題として既存行の扱いに倣う.claude/rules/java/main.mdの「ドメイン層の独立性」(「Javadoc・コメントにHTTPステータスコードなど技術層の詳細を書かない」)。指摘はPR #223のレビュー(@nshingo、2026-09-14)未対応
OAS反映他Operator計画検索(OtherFlightPlanAreaFeatureCollection)は、altitudeReference=WGS84のFeatureが標高データのカバー範囲外で欠落しても、クライアント側にそれを検知する信号がない。truncatedtotalCount > limitのみで判定し、excludedCount/degraded()は行そのものを落とした場合(InconsistentRowException)専用(FlightPlanAreaSearchResult#truncatedのjavadocも「クライアントへ伝える手段は現時点でOASに無い」と認めている)。「取りこぼしより過検出を許容する」という安全側の方針(4.4節)とは逆方向(存在する計画を地図に出さない)の欠落であるため、影響は無視できない。信号を追加するにはOAS変更(新規プロパティまたは既存フラグの意味拡張)を伴うため別Issueで検討するgeospatial.yamlOtherFlightPlanAreaFeatureのdescription。PR #276のレビュー(@t-kuriによるAIレビュー代行、C-2)未対応
他ドメイン合意空域制限の手動登録・更新(source_kind=MANUAL)を契機とした、飛行計画との競合再判定の起動機構がない。DIPSからの定期収集は取得時に再チェックが走る想定だが、手動登録・更新の経路には対応する起動契機が無い。収集・手動登録の書き込み経路自体が本設計の対象外(AirspaceRestrictionRepositoryは読み取り専用)のため現時点では決められず、書き込み経路を実装する際にflight_planning.conflict_detection側とあわせて起動契機を決める必要があるAirspaceRestrictionRepository.java。指摘はPR #236のレビュー(@t-kuri、2026-09-16)未対応
OAS反映geospatial.yamlAirspaceRestrictionFeatureが、同一restrictionIdに対し常に2件を返す書き方になっていた。天面がZ値を持たない行は基準の区別がつかず1件でしか返せず、取得元がWGS84基準の値を持たない行もWGS84のFeatureを作れない。あわせて同descriptionはWGS84のZ値を「頂点ごとに算出した楕円体高」と応答時算出の前提で説明しており、実体化列から読む現在の方式とも食い違っていた。「1件または2件」+各件が返る条件へ是正済みPR #260、info.version 0.11.0)。同種の是正は他Operator計画検索でもPR #276が行っているBusinessLogicSpecifications.mdの5.3「空域制限検索」(1-3-5・1-3-6)PR #260で対応
OAS反映geospatial.yamlPositionが要素数を3固定で宣言し、2要素を許していなかった。空域制限には高度の概念がない分類(レッドゾーン等)と取得元が高度を提供しない行があり、2次元の座標を返す経路が実在する。minItems: 2maxItems: 3へ緩め、RFC 7946のpositionに合わせたPR #260、info.version 0.11.0。checkOasBreakingChangesは破壊的変更なし)。Positionは飛行計画領域検索とテレメトリの形状も参照するため、2要素を返すのは空域制限検索だけである旨をdescriptionに明記した。生成コードは入れ子配列のminItemsをBean Validationへ出力しないため、2要素を弾いていたのはPointGeometryのみで、他の経路は実行時には落ちていなかった(同じ性質の既知例が本台帳のPolygon構成点数の行にある)BusinessLogicSpecifications.mdの5.3「空域制限検索」(1-3-6)。判定根拠はdocs/issues/issue-260-airspace-gis/detailed-design.mdの12-1節PR #260で対応
実体未作成geometry_type=MULTIPOLYGONの行でtop_bottom_3d_geometryの並びが未定義。同列は上面・下面をcoordinates[0]/coordinates[1]の2枚として定義しているが、これは天面が1枚の面である行を前提としており、分離したN個の領域に対する並べ方(2N枚にするのか、上面N枚・下面N枚に分けるのか)が決まっていない。GeoSpatialの検索応答はproperties.geometryTypegeometry.typeの1対1対応をOASで約束しているため、先頭1枚を天面として取るとMULTIPOLYGONの行で型が崩れる。空域制限の検索APIは当面MULTIPOLYGONの行で同列を使わず、水平形状(AGL側は2次元ならスカラーの天面高度を合成、WGS84側は3次元のgeometry_wgs84のみ)から天面を作って回避する。領域全体で一様な天面になり、同列が持つ頂点ごとのZ値を活かせない。geometryが2次元で天面のスカラー高度も無い行では合成もできず、高度を持つ行でありながらFeatureが1件・altitudeReference未設定で返る(高度のプロパティは持つため、5.3の1-3-6が想定する「高度を持たない行」とは応答が異なる)。収集を実装して同列を書き込む側が現れる時点で並びを決める必要があるairspace-er.mdの「上面・下面は3次元のgeometryで持つ」。回避策はdocs/issues/issue-260-airspace-gis/detailed-design.mdの11-2節未対応
実体未作成top_bottom_3d_geometryの「coordinates[0]が上面」という並びを保証する実体が、書き込み側にも読み出し側にもない。DDLのCHECK制約(ck_airspace_restriction_top_bottom_3d)は種別・SRID・次元しか見ず、ドメイン型(AirspaceGeometry.MultiPolygon)も並びを持たないため、逆順で投入されても検知されない。検索APIは先頭のPolygonを天面として取るため(docs/issues/issue-260-airspace-gis/detailed-design.mdの11-2節)、逆順の行は床面を天面として返す。水平形状は変わらず2D表示は正しいため、3D表示でのみ現れる。飛行計画ドメインでは同じ前提が実際に破れた実例がある。 issue #271は同名の列のAGL版が床面を先に並べていたことによる「3D表示で飛行領域が地表の下に描かれる」不具合として報告され、PR #275が並びを直すとともに、同じST_Collectが2つのマッパーへ手で複製され片方だけ直ると食い違う状態を一因に挙げて共通のSQLフラグメントへ集約した。空域制限は書き込み側がアプリの外(事前投入)にあるため、この集約では防げない。読み出し時にZ値を比較して検知するか、CHECK制約で縛るかを決める必要がある。PR #260(PR-04)では入れない。 検証をMapperへ置くと並びの知識が3箇所目に増えるため、知識をドメインへ引き上げる時点(収集が実装され消費者が2つになるとき。同detailed-designの11-6節)へ検証も合わせるairspace-er.mdの「上面・下面は3次元のgeometryで持つ」。契機はPR #275未対応
実体未作成空域制限検索は、ドメインへ変換できない行が1つでもあると検索全体が失敗する。AirspaceRestrictionRepositoryImpl#searchInconsistentRowExceptionRepositoryExceptionへ詰め替えて送出するため、事前投入された1行の不備でそのbbox・分類の結果が全件失われる。InconsistentRowExceptionのjavadocは「当該行だけを結果から除いて続行してよい」と宣言しており、実装はこれに従っていない。同じ「一部が読めない」状況について周辺計画収集は逆の方針を採った。 PR #276は1件の高度換算失敗をその計画のWGS84/AMSL列の除外にとどめ、根拠を「バッチ処理でありUTM側が内容を検証して拒否する対象ではない」ことに置いている。空域制限も取得元が与えるデータを表示するだけで内容を検証して拒否する立場にない点は同じため、方針を揃えるかを決める必要があるdetailed-design.mdの10-1節。契機はPR #276未対応
OAS反映空域制限検索はaltitudeReference=WGS84のFeatureが_wgs84列のNULLで欠落しても、クライアント側にそれを検知する信号がない。Featureが1件で返る理由は「高度を持たない行」(5.3の1-3-6)と「WGS84側を組み立てられなかった行」(同1-3-5)の2つあるが、totalCountは空域制限の件数でfeaturesの要素数と一致せず、truncatedは打ち切りだけを表すため、後者が「本来2件返る行」であることは応答に現れない。同じ論点が他Operator計画検索にもあり本台帳に別行で登録済みだが、あちらが持つexcludedCount/degraded()に相当するものをAirspaceRestrictionSearchResultは持たない点が異なる。issue #271は他Operator計画検索でこの欠落が不具合報告として上がったものであり、空域制限でも検索APIの提供開始後に同じ報告が起こりうる。信号の追加はOASの変更を伴うため、他Operator計画検索側と一体で決める(PR #260(PR-04)では足さない)detailed-design.mdの11-7節。契機はissue #271PR #276未対応
実体未作成接尾辞のないgeometry系カラムのZ値がAGL基準であるという前提を保証する実体が、書き込み側にも読み出し側にもない。altitude_reference列の値域はAGLWGS84の2値で、CHECK制約(ck_airspace_restriction_altitude_reference_required)はZ値を持つ行にNOT NULLを課すだけで値をAGLへ固定していない。検索APIは同列を参照せず接尾辞なしの列から組み立てた天面を無条件にaltitudeReference=AGLとして返すため(src/main/java/com/intent_exchange/utm/handler/response/AirspaceRestrictionResponseMapper.java。応答のFeatureを作り分けるフラグとして値をそのまま写さないのは5.3の1-3-2に沿った意図的な実装である)、事前投入が唯一の書き込み経路である現状でWGS84と宣言された行が入ると、楕円体高のZ値がAGLとしてラベルされて返る。水平形状は変わらず2D表示では現れないため3D表示でのみ現れる点は、本台帳の「coordinates[0]が上面という並びを保証する実体がない」行と同型である。DDLの列コメント・airspace-er.mdgeospatial-api-design.mdの5.2節・docs/issues/issue-260-airspace-gis/overview.mdはいずれも「現時点では常にAGL」で揃っており、決めるべきはCHECK (altitude_reference = 'AGL')で縛るか読み出し時にAGL以外を弾くかである。PR #260(PR-04)では入れない。 該当列は#236の成果物で本PRは変更せず、読み出し側に判定を置くと基準の知識が2箇所目に増えるため、上記の並びの検証と同じく知識をドメインへ引き上げる時点(収集が実装され消費者が2つになるとき)へ合わせるairspace-er.mdの「図1 カラム補足」(altitude_referenceの行)。契機はPR #260のレビュー(@nes-miyasaka の指摘3未対応
実体未作成周辺計画収集がDIPSへ渡す検索時間帯を、DIPSが受理する上限より広く組み立てられる。暦日の終端を翌日0時(=検索開始ちょうど24時間後)として送っているが、DIPSはこの指定を受理しない。受理される範囲に収まる終端の送り方へ改め、あわせてドメイン側の上限(src/main/java/com/intent_exchange/utm/domain/model/DipsFlightPlanSearchPeriod.javaMAX_DURATIONforFlightPeriod)も受理される範囲で弾くようにする必要があるflight-plan-er.mdの「収集時の検索条件はDIPS参照APIの制約に合わせて変換する」(時刻形式の行)未対応

既存のフォローアップとの関係

Section titled “既存のフォローアップとの関係”

飛行計画・AssetドメインER図(PR #43)が挙げた「OAS・他ドメインへ反映が必要な項目」は、同設計の 結論に対する申し送りとしてflight-plan-er.mdに 残してある。同節はPR #43のスコープに閉じた記録として維持し、新しく気づいた項目は本台帳へ追加する