ADR-0011: DTO パターンとヘッダー名ベースの列参照強制
- Status: Accepted (旧形式「## ステータス: 採用済み」より転記)
- Mode: Standard (内容から推定・旧 README 一覧より移設)
- Kruchten Type: Property
- Scope: product
- Implementation Status: Done (DTO Header-based 列参照実装済)
Kruchten Type は ADR-0031 (2026-05-13) で遡及追加。分類根拠は ADR-0031 §決定セクションおよび docs/adr/README.md の Kruchten 3 分類ガイドを参照。 Status / Mode / Scope は 2026-06-11 に遡及追加 (ADR-0031 corrigendum パターン)。出典: Status = 旧形式「## ステータス」節の機械転記 / Mode = 旧 README §既存 ADR 一覧の推定値 (git 履歴) / Scope = ADR-0049 4 層分類の遡及付与 (PR レビューで確定)。
ステータス: 採用済み
コンテキスト
Google Spreadsheet のシートは列の追加・並び替えが頻繁に発生する。列番号(インデックス)で直接参照するコードは、列構成が変わるたびに壊れるリスクがある。また、getValues() で取得した二次元配列をそのまま使い回すとコードの可読性が著しく低下する。
選択肢:
- 案A: 列番号をハードコードして参照(速度優先)
- 案B: ヘッダー名から動的にインデックスマップを構築し、名前で列を参照
- 案C:
003_contracts.jsに JSDoc@typedefでシートごとの DTO を定義し、行⇔オブジェクト変換を一箇所に集約
決定
案B + 案C を組み合わせる。 列参照は必ず buildHeaderIndex_() で取得したマップ経由とし、列番号のハードコードを禁止する。行データとのやり取りは 003_contracts.js の DTO 型(OrderDTO, InvoiceDTO 等)を介して行う。
理由
- シートのスキーマ変更(列追加・改名)に対するコードの耐性が上がる
- DTO の
@typedefにより IDE の型補完が効き、フィールド名のタイポをコンパイル前に発見できる - シート行⇔オブジェクト変換ロジックが
003_contracts.jsに集約され、各ドメインロジックがデータ形式を意識しなくて済む - ADR-0004(ヘッダー列名の統一命名規則)と合わせることで、命名規則+アクセス方法の両方が標準化される
結果・影響
- ポジティブ:
row[3]のような魔法の数字がなくなり、inv['請求金額']のように意図が明確 - ポジティブ:
RENAME_MAP(DDL で使用)とbuildHeaderIndex_()の組み合わせで、ヘッダー名変更時の後方互換性が保てる - ネガティブ: 初回の
buildHeaderIndex_()呼び出しコストが発生するため、大量行処理では 1 回構築してキャッシュする必要がある - 規約:
PropertiesService.getScriptProperties()の直呼び禁止(ADR-0013)と同じ「直接依存禁止」の思想
Confirmation (準拠確認 / Fitness Function)
本セクションは ADR-0036 (Accepted 2026-05-14) で遡及追加された。ADR-0031 パターン (業界標準準拠メタデータ後付け = 誤字修正範疇) に準拠する遡及で本文の意思決定内容は不変。
- 検証手段: scripts/adr-lint.mjs + scripts/4_review_specs_by_gemini.js
- 実行頻度: PR ごと
- 違反時の対応: 自動 fail