MAS-046: 投資カタログマスタ(Investment Catalog Master・FP&A データ層基盤の補完強化)
概要
| 項目 | 内容 |
|---|---|
| 案件 ID | MAS-046 |
| カテゴリ | 💾 Data(FP&A マスタ系) |
| Phase | P2.5(自動入力パイプライン拡張・SaaS 連携・D.8-D.10 補助機能) |
| 優先度 | ★★ |
| 所要時間 | 推定 1-2 週間 |
| 実装ステータス | 📝 仕様書段階・実装未着手 (2026-05-01 起票時点) |
| 対象ファイル(新規) | 200_data/205_investment_catalog_repository.js(新設)100_config/101_sys_config.js schemas 配列に 30_mst_investment_catalog 追加webapp_client/src/cockpit/InvestmentCatalogPanel.tsx(新設)800_ops/8XX_migration_investment_catalog_seed.js(番号は実装着手時に採番・本仕様書時点で 824 以降を想定) |
| 新規シート | 30_mst_investment_catalog(投資カタログ・DDL 管理) |
| 前提案件 | MAS-013(投資回収シミュレーション・既存) MAS-042(投資ハードルレートマスタ・InProgress) MAS-055(SaaS カタログマスタ・パターン参考) |
| 後続案件 | MAS-050(投資回収ベンチマーク・本マスタが前提) MAS-052(軽量版 Stage-Gate・ステージ管理連携) MAS-067(マルチイヤー計画・投資案件引き当て・将来 v2 連携) |
bizlp の投資判断機能は MAS-013(投資回収シミュレーション)+ MAS-042(投資ハードルレートマスタ)で構成されているが、投資案件のカタログ的な保管機構が欠けている。本案件は「個別投資シミュレーションを越えて、投資案件のメタデータ(業種・カテゴリ・規模・ステータス・実績)を統合管理するマスタ層」を新設し、Solo-CEO が複数投資案件の Go/No-Go を 1 画面で俯瞰できる基盤を整備する。
目的
現状の制約
- MAS-013 投資回収シミュレーション: 個別シナリオ計算機(
67_report_investment_analysis)として動作するが、過去・現在・将来の投資案件を一覧で管理する仕組みがない。シミュレーション結果が各実行ごとに使い捨てられている - MAS-042 投資ハードルレートマスタ: 判定基準(Payback 年数・ROI 等)のみ保管。判定対象の案件側に「ハードルを満たしたか」のスナップショットが残らない
- 業界ベンチマーク比較が困難: SaaS 業界の SaaS 投資 Payback 中央値 = 12 ヶ月などの参考値と自社実績の比較が手動 Excel ベース
- Excel ベース管理の限界: 投資案件の「過去実績」「現在進行中」「検討中」のステータス追跡が GAS 外で行われ、SSoT(Single Source of Truth)が成立していない
User Story(4 件)
- Solo-CEO(複数案件俯瞰): 「現在検討中の投資 3 案件(Vertex AI 拡張 / Jr 採用 / 機材更新)のうち、Go 判定を 1 画面で見たい」
- Solo-CEO(過去実績参照): 「過去の HC 投資の Payback が業界中央値より早いか確認したい」
- MAS-067 マルチイヤー連携: 「3 年後の追加投資 X 億をマスタから引き当てたい」
- MAS-050 ベンチマーク比較: 「業種別(IT / コンサル / 製造)の Payback 中央値と自社実績を比較したい」
MAS-013 / MAS-042 / MAS-050 / MAS-055 / MAS-067 との位置づけ
| 関連案件 | 役割 | 本案件との関係 |
|---|---|---|
| MAS-013 投資回収シミュレーション | 計算エンジン | 計算結果(Payback / ROI / NPV 等)を本マスタにメタデータ付きで保管。計算機 → カタログの一方向連携 |
| MAS-042 投資ハードルレートマスタ | 判定基準マスタ | 本マスタの Go/No-Go 判定 列で findByCategory(category) を呼び自動判定 |
| MAS-050 投資回収ベンチマーク | 業界比較レポート | 本マスタが前提。業種・カテゴリのメタデータがないとベンチマーク比較が成立しない |
| MAS-055 SaaS カタログマスタ | パターン参考 | 同型(マスタ + Repository + cockpit パネル)のため実装テンプレートとして流用 |
| MAS-067 マルチイヤー計画ワークスペース | 多年計画統合 | 将来 v2 で多年シミュレーション内の投資項目を本マスタから引き当て |
本案件の SSoT 位置づけ: 投資案件のメタデータの SSoT は本マスタ。MAS-013 は計算機(使い捨て)、MAS-042 は閾値マスタ(参照のみ)、本マスタは 「案件のライフサイクル全体を保持する正本」 として機能する。
現在のコード
100_config/101_sys_config.js(DDL スキーマ)
schemas 配列の DDL パターンに従い、'MST_INVESTMENT_CATALOG' キーで新規エントリを追加する。MAS-055 の MST_SAAS_TMPL と同型の構造(headers / color / validations)。existKeys 拡張も同時に行い、01_sys_config シートに MST_INVESTMENT_CATALOG キーを登録する。
MENU_DEFINITION(カスタムメニュー定義)に「💼 投資管理」セクションを追加し、本マスタへのアクセス UI を設置する。
200_data/202_repository.js(Repository パターン・参考元)
既存 PartnerRepository / AccountRepository 等のマスタ系 Repository は以下パターンで実装されている:
- 内部キャッシュ(
_cacheプロパティ)を持つ findAll()で全件取得(DTO 配列)findAsMap()で ID → DTO マップ取得(重複は先着採用)save(dto)で 1 件保存(新規 → append、更新 → update_cells)- 有効フラグ FALSE 行は読み取り時にスキップ
Utils.getSheetByKey(systemKey, fallbackName)でシート取得
本案件では新規ファイル 200_data/205_investment_catalog_repository.js として独立させ、ファイル数膨張を抑える方針(MAS-055 までは 202_repository.js 末尾追記だったが、Repository 数が増えてきたため本案件以降はファイル分離)。
docs/dev/dev_mas-055_saas_catalog_master.md(パターン参考)
SaaS マスタ設計パターンと完全同型の構造(DDL + Repository + cockpit / サイドバー UI + マスタシード migration)。本案件のテンプレートとして流用する。MAS-055 が読み取り専用マスタであるのに対し、本案件は書き込み可能(ステータス遷移・実績反映) な点が主要な差分。
docs/dev/dev_mas-013_investment_simulation.md(連携先)
投資回収シミュレーションのデータ構造(67_report_investment_analysis 動的シート)。本マスタに保管するフィールド(Payback / ROI / NPV / IRR)は MAS-013 の計算結果列名と整合させる必要がある。
docs/dev/dev_mas-042_investment_hurdle_rate.md(前提案件)
ハードルレートマスタ(29_mst_investment_hurdle_rate)。本案件の Go/No-Go 判定 列で findByCategory(category) を呼び、対応する閾値(Payback 上限月数・ROI 下限 %)を取得して自動判定する。
修正方針
Step 1: DDL シート追加 + Constants 拡張
1-A. 100_config/101_sys_config.js schemas に追加
'MST_INVESTMENT_CATALOG': {
headers: [
"有効フラグ", "投資カタログID", "案件名", "投資カテゴリ", "業種", "投資規模",
"想定金額", "想定 Payback (月)", "想定 ROI (%)", "ステータス", "Go/No-Go 判定",
"判定根拠", "関連 ORD ID", "関連 INV ID", "開始予定日", "完了予定日",
"実績 Payback (月)", "実績 ROI (%)", "備考", "タグ", "作成日時", "更新日時"
],
color: "#3d85c6", // 投資管理系の色(MAS-013/042 と同系統)
validations: {
"投資カテゴリ": { type: 'list', values: ['HC', 'CAPEX', 'SAAS', 'R&D', 'MARKETING', 'OTHER'] },
"業種": { type: 'list', values: ['IT', 'コンサル', '製造', '小売', '飲食', 'その他'] },
"投資規模": { type: 'list', values: ['小 (<100万)', '中 (100-1,000万)', '大 (1,000万-)'] },
"ステータス": { type: 'list', values: ['検討中', '実行中', '完了', '中止', '保留'] },
"Go/No-Go 判定": { type: 'list', values: ['Go', 'Conditional Go', 'No-Go', '未判定'] },
"想定 Payback (月)": { type: 'range', min: 0, max: 240 },
"想定 ROI (%)": { type: 'range', min: -100, max: 1000 },
"実績 Payback (月)": { type: 'range', min: 0, max: 240 },
"実績 ROI (%)": { type: 'range', min: -100, max: 1000 }
}
},
existKeys への追加:
if (!existKeys.includes('MST_INVESTMENT_CATALOG')) {
confSheet.appendRow(['MST_INVESTMENT_CATALOG', '', '30_mst_investment_catalog', '投資カタログマスタ']);
}
1-B. 000_infra/002_constants.js Constants.ID_PREFIXES に追加
ID_PREFIXES: {
// 既存...
INV_CAT: 'INV_CAT_', // 投資カタログ ID(4 桁連番・MAS-046)
}
ID 採番ルール: INV_CAT_NNNN(4 桁連番、例: INV_CAT_0001)。既存 ID 命名規則(ORD_YYYY_NNNN 等)と整合させる。
1-C. シート設計(22 列)
| 列 | 内容 | 例 |
|---|---|---|
有効フラグ | 論理削除用 | true |
投資カタログID | INV_CAT_NNNN(4 桁連番) | INV_CAT_0001 |
案件名 | 案件のタイトル | Vertex AI 拡張・dev quota |
投資カテゴリ | HC / CAPEX / SAAS / R&D / MARKETING / OTHER | R&D |
業種 | 自社業種 | IT |
投資規模 | 小 (<100万) / 中 (100-1,000万) / 大 (1,000万-) | 中 |
想定金額 | 投資総額(税込・JPY) | 3000000 |
想定 Payback (月) | 想定回収期間 | 18 |
想定 ROI (%) | 想定 ROI | 35 |
ステータス | 検討中 / 実行中 / 完了 / 中止 / 保留 | 検討中 |
Go/No-Go 判定 | Go / Conditional Go / No-Go / 未判定(MAS-042 連携) | 未判定 |
判定根拠 | 自由記述(MAS-042 ハードルレートとの比較根拠) | Payback 18 < 24 で Go |
関連 ORD ID | 関連発注 ID(カンマ区切り複数可・Q1 推奨案 X) | ORD_2026_0123 |
関連 INV ID | 関連請求 ID(カンマ区切り複数可) | INV_20260331_0045 |
開始予定日 | 投資期間開始 | 2026-04-01 |
完了予定日 | 投資期間終了 | 2027-09-30 |
実績 Payback (月) | 完了後の実績(完了時に MAS-013 から取得) | (空欄) |
実績 ROI (%) | 実績 ROI | (空欄) |
備考 | フリーテキスト | Vertex AI 検証段階 |
タグ | カンマ区切りタグ | AI,検証,2026Q2 |
作成日時 | 監査列(自動設定) | 2026-05-01 10:00 |
更新日時 | 監査列(save 時に自動更新) | 2026-05-01 10:00 |
Step 2: InvestmentCatalogRepository 新設(200_data/205_investment_catalog_repository.js)
MAS-055 の SaasTemplateRepository パターンを流用しつつ、書き込み機能(save / linkActuals) を追加する:
// =====================================================================
// InvestmentCatalogRepository — 30_mst_investment_catalog (読み書き両用マスタ)
// =====================================================================
var InvestmentCatalogRepository = {
_getSheet: function() {
return Utils.getSheetByKey('MST_INVESTMENT_CATALOG', '30_mst_investment_catalog');
},
findAll: function() {
var result = readSheetAsDtos_(InvestmentCatalogRepository._getSheet());
return result.dtos.filter(function(dto) {
var flag = dto['有効フラグ'];
return !(flag === false || String(flag).toUpperCase() === 'FALSE');
});
},
findById: function(catalogId) {
var dtos = InvestmentCatalogRepository.findAll();
for (var i = 0; i < dtos.length; i++) {
if (dtos[i]['投資カタログID'] === catalogId) return dtos[i];
}
return null;
},
findByStatus: function(status) {
return InvestmentCatalogRepository.findAll().filter(function(dto) {
return dto['ステータス'] === status;
});
},
findByCategory: function(category) {
return InvestmentCatalogRepository.findAll().filter(function(dto) {
return dto['投資カテゴリ'] === category;
});
},
save: function(catalog) {
// 新規 → append(次の連番 ID を採番)/ 既存 → update_cells
// 詳細実装は Step 2 のプロンプトで指示
},
linkActuals: function(catalogId, payback, roi) {
// ステータス完了時に MAS-013 から実績値を反映
},
recalculateGoNoGoAll: function() {
// MAS-042 ハードルレート変更時のバッチ再判定(Q5 推奨案 X)
},
_cache: null,
resetCache: function() { InvestmentCatalogRepository._cache = null; },
};
Step 3: cockpit パネル UI(webapp_client/src/cockpit/InvestmentCatalogPanel.tsx)
Q3 推奨案 X(cockpit パネル)に従い、MAS-057 cockpit 配下にパネルを新設:
- 投資案件一覧テーブル: ステータス別フィルタ(検討中 / 実行中 / 完了 / 中止 / 保留)
- 新規作成ダイアログ: MAS-013 シミュレーション結果から「カタログに登録」ボタン経由で自動入力
- Go/No-Go 判定: MAS-042 ハードルレート連携で自動判定(手動上書き許可)
- 完了案件の実績反映 UI: ステータス完了時にダイアログで実績 Payback / ROI を確認 → 保存
- 業界ベンチマーク表示(将来 MAS-050 と連携・本案件では UI プレースホルダーのみ)
Step 4: メニュー追加(100_config/101_sys_config.js MENU_DEFINITION)
💼 投資管理
├─ 投資カタログ表示
├─ 新規案件登録
├─ Go/No-Go 一括再判定(MAS-042 変更時)
└─ 完了案件の実績反映
Step 5: マスタシード migration(800_ops/8XX_migration_investment_catalog_seed.js)
- 既存の MAS-013 シミュレーション結果(
67_report_investment_analysis)をスキャンし、初期投入候補として抽出 - bizlp の現在検討中 3 案件(Vertex AI 拡張 / Jr 採用 / 機材更新)をシード投入
- 冪等性ガード必須(既存 ID は上書きしない)
ファイル番号は実装着手時に最新確認(本仕様書時点で 822 まで使用済 + MAS-336/337/338 で予約 → 824 以降を採番予定)。
影響範囲
新規ファイル
| ファイル | 種類 | 役割 |
|---|---|---|
200_data/205_investment_catalog_repository.js | GAS 新規 | Repository 実装(約 200 行) |
webapp_client/src/cockpit/InvestmentCatalogPanel.tsx | React 新規 | cockpit パネル UI(約 400 行) |
800_ops/8XX_migration_investment_catalog_seed.js | GAS 新規 | マスタシード(約 100 行) |
既存ファイル変更
| ファイル | 変更種別 | 内容 |
|---|---|---|
100_config/101_sys_config.js | 追加のみ | schemas に MST_INVESTMENT_CATALOG 追加 / existKeys 1 行 / MENU_DEFINITION に「💼 投資管理」セクション |
000_infra/002_constants.js | 追加のみ | Constants.ID_PREFIXES.INV_CAT 追加 |
400_domain/430_what_if_simulator.js 等 MAS-013 連携箇所 | 変更 | シミュレーション結果から「カタログに登録」ボタン追加(連携経路) |
docs/_config.json | 追加のみ | nav に仕様書登録 |
既存動作への影響
- MAS-013 投資回収シミュレーション: 既存の
67_report_investment_analysis動的シートはそのまま残す。本マスタへの登録は新規ボタン経由のみで、既存シミュレーション動作は無変更 - MAS-042 投資ハードルレートマスタ: 既存ハードルレート値はそのまま参照のみ。本マスタ側から
findByCategory()を呼び出す一方向連携 - GAS マニフェスト権限: シート読み書きのみ。OAuth スコープ追加なし
- DDL 全更新(Full):
setupAllSchemas実行時に30_mst_investment_catalogが新規生成
運用・デプロイ手順
npm run push:dev→ サイドバー🔧 開発・設定 → DDL 全更新 (Full)→30_mst_investment_catalog生成initConfigs実行 →01_sys_configにMST_INVESTMENT_CATALOG登録- マスタシード migration 実行 → 過去 12 ヶ月の
67_report_investment_analysisから抽出 + 現在検討中 3 案件投入 - cockpit 起動 → 「💼 投資管理 → 投資カタログ表示」 → 投入された案件一覧表示確認
- MAS-013 シミュレーション実行 → 「カタログに登録」ボタン → 本マスタに新規追加されることを確認
- ステータスを
完了に変更 → 実績 Payback / ROI 反映ダイアログ動作確認 - dev で全テスト合格後
npm run push:prod→ prod で同手順
注意事項
- ⚠️ MAS-013 シミュレーション結果との重複回避: シミュレーション(
67_report_investment_analysis)は計算結果・本マスタはメタデータ。重複ではなく役割分担(計算 vs 管理)。MAS-013 結果を本マスタに転記する際は「いつのシミュレーション結果か」を備考列に記録 - ⚠️ ID 採番ルール:
INV_CAT_NNNN4 桁連番・既存Constants.ID_PREFIXES命名規則踏襲・Constants.ID_PREFIXES.INV_CAT追加。failure_patterns #18-#20(命名造語禁止)に従い、Constants 追加前に既存 ID プレフィックスを Read で確認 - ⚠️ ステータス遷移ルール:
検討中 → 実行中 → 完了を主軸・中止/保留は例外的に許可。Action A 同様の遷移ルール明文化(完了 → 検討中は不可・監査ログ記録) - ⚠️ Go/No-Go 判定の自動化と上書き: MAS-042 ハードルレートとの比較で自動判定 + 手動上書き許可(UI 上書き優先)。手動上書き時は
判定根拠列に記録 - ⚠️ 完了案件の実績反映タイミング: ステータス
完了時に MAS-013 から実績 Payback / ROI を自動取得・手動入力許可。MAS-013 が再実行される場合に備え、linkActuals()は最新値で上書きせず**追記モード(履歴残し)**にするか Q2 で議論 - ⚠️ 冪等性(migration): マスタシード migration は既存 ID を上書きしない(
既存_有り → スキップ)。失敗時の再実行で重複生成を防ぐ - ⚠️ ヘッダー名一貫性(failure_patterns #25 並列対称性): 投資シミュレーション側(MAS-013)のヘッダー名と整合・「投資カテゴリー」(MAS-013) → 「投資カテゴリ」(本マスタ)で表記揺れがある場合、本マスタ側を SSoT として MAS-013 に合わせる
- ⚠️ MAS-055 SaaS マスタとの並列性(failure_patterns #25): 同パターン実装で実装コスト削減・テストパターン共通化。
SaasTemplateRepositoryとInvestmentCatalogRepositoryの構造対称性を実装時に確認 - ⚠️ GAS マニフェスト権限: シート読み書きのみで OAuth スコープ追加なし。
appsscript.json編集不要(failure_patterns #26 回避) - ⚠️ テストランナー追加:
F046-01〜F046-12を901_test_runner.jsに追加。MAS-055 のtest_SaasTemplateRepository_*と同型のテストケース構成 - ⚠️ MAS-067 マルチイヤー連携時の Y0 着地予測: 完了予定日が Y0 内なら実績想定・Y1 以降なら計画想定の区別。多年計画統合時の判定ロジックは MAS-067 仕様書側で詳述
- ⚠️ failure_patterns #31 (ID 衝突): 800_ops/ 採番は実装着手時に最新確認(本仕様書時点で 822 + MAS-336/337/338 予約 = 824 以降)。仕様書で
8XXプレースホルダーとし、実装時に確定
エッジケース
| # | 条件 | 検知方法 | 期待される挙動 | ログ出力 |
|---|---|---|---|---|
| 1 | ステータス 検討中 で 関連 ORD ID が空 | findById(catalogId) 取得時 | NORMAL(MAS-013 シミュレーションのみ実行段階で本マスタには未紐付け) | ログ出力なし |
| 2 | 投資カテゴリ が OTHER で MAS-042 に対応閾値なし | MAS-042 findByCategory('OTHER') が空 | デフォルト閾値(Payback 24 ヶ月・ROI 20%)を適用 + 警告ログ | Utils.persistLog('WARN', 'GoNoGoAuto', 'MAS-042 未登録カテゴリ: OTHER') |
| 3 | 想定 Payback が空欄 | dto['想定 Payback (月)'] が null | MAS-013 シミュレーション未実行案件として許容・Go/No-Go 判定は 未判定 | ログ出力なし(正常系) |
| 4 | 実績 Payback が 想定 Payback を 50% 以上超過 | linkActuals() 時に比較 | 警告ダイアログ表示(要原因調査)+ 強制保存可 | Utils.persistLog('WARN', 'linkActuals', '実績乖離: catalogId=' + id) |
| 5 | ステータス 中止 の場合の Go/No-Go 判定 | dto['ステータス'] === '中止' | 判定列は無効化(空欄表示・自動判定スキップ) | ログ出力なし |
| 6 | 関連 ORD/INV が複数(1:N) | カンマ区切り入力 | カンマで split → 配列扱い(Q1 推奨案 X) | ログ出力なし |
| 7 | 投資カテゴリ追加(例: MARKETING → M&A) | DDL validations.values 拡張 | DDL 拡張 + 既存 ID 影響なし(既存値は引き続き有効) | ログ出力なし |
| 8 | 大規模投資(1 億超) | 想定金額 > 100000000 | 投資規模 区分 4 段階目 特大 を将来追加検討(v1.1) | ログ出力なし |
| 9 | 複数組織での投資(子会社) | 単一組織前提 | MAS-177 と整合・本案件では単一組織のみサポート | ログ出力なし |
| 10 | 過去案件の遡及登録 | migration script で抽出 | 既存 67_report_investment_analysis から抽出 + 冪等性ガード | Utils.logInfo('migration_seed', '過去案件投入: ' + count + ' 件') |
| 11 | MAS-013 側で投資カテゴリ変更 | シミュレーション再実行 | 本マスタの該当案件は自動更新せず手動同期(Q2 推奨案 X・本マスタ SSoT) | Utils.persistLog('WARN', 'mas013_sync', 'カテゴリ不一致: ' + id) |
| 12 | ハードルレート変更(MAS-042) | バッチ再判定 API 呼び出し | recalculateGoNoGoAll() で全案件再評価(Q5 推奨案 X) | Utils.logInfo('recalculateGoNoGoAll', '再評価: ' + count + ' 件 / 変更: ' + changed + ' 件') |
| 13 | 同一 投資カタログID の重複 | save() 時に既存チェック | エラー(重複は許可しない・採番ロジックで防止) | Utils.persistLog('ERROR', 'save', '重複ID: ' + id) |
| 14 | 開始予定日 > 完了予定日 | save() バリデーション | エラーダイアログ + 保存中止 | Utils.persistLog('ERROR', 'save', '日付逆転: ' + id) |
冪等性・再実行の設計
- マスタシード migration: 既存
投資カタログIDをチェックし、存在すればSKIPログ出力で次へ。何度実行しても同じ最終状態 linkActuals()再実行: ステータス完了案件に対して再度 MAS-013 シミュレーションが実行された場合、最新値で上書き(Q2 推奨案 X)。履歴を残したい場合は備考列に追記recalculateGoNoGoAll(): 何度呼んでも同じ結果(MAS-042 ハードルレートが変わらない限り)
Human-in-the-Loop
- 自動 Go/No-Go 判定は初期値であり、最終判断は人間(Solo-CEO)が行う。手動上書き UI を提供
- ステータス遷移は手動操作のみ(自動遷移なし)。
完了 → 検討中の異常遷移は監査ログ記録 + 警告ダイアログ linkActuals()は完了時にダイアログで確認 → 保存。自動的にバックグラウンドで上書きしない
テスト要件(900_test/901_test_runner.js への追加)
| テスト関数 | 合格基準 |
|---|---|
test_F046_01_repository_findAll_emptyMaster | 空マスタで [] 返却 |
test_F046_02_repository_findAll_disabledFlag | 有効フラグ=FALSE 行が除外される |
test_F046_03_repository_findById_notFound | 存在しない ID で null 返却 |
test_F046_04_repository_findByStatus | ステータス別フィルタが正しく動作 |
test_F046_05_repository_save_newRecord | 新規保存で連番 ID が採番される |
test_F046_06_panel_renderList | cockpit パネルで投資案件一覧が表示される |
test_F046_07_panel_filterByStatus | ステータス別フィルタが UI で動作 |
test_F046_08_panel_createDialog | 新規作成ダイアログから保存が成功 |
test_F046_09_goNoGo_autoEvaluation | MAS-042 連携で自動判定が機能 |
test_F046_10_goNoGo_manualOverride | 手動上書きが優先される |
test_F046_11_recalculateGoNoGoAll_batch | バッチ再判定 API が全件評価 |
test_F046_12_linkActuals_completeCase | ステータス完了時に実績反映が機能 |
実データ検証
実装前に MCP で以下を確認:
30_mst_investment_catalogシートの有無(DDL 実行前は存在しない)67_report_investment_analysisの現行ヘッダー構成(MAS-013 計算結果列名と整合確認)29_mst_investment_hurdle_rateのカテゴリ列値(MAS-042 連携時のキー対応確認)01_sys_configにMST_INVESTMENT_CATALOGキーが未登録であることConstants.ID_PREFIXESにINV_CATが未定義であること(衝突チェック)
具体シナリオ + 期待値
- bizlp 現在検討中 3 案件投入:
- Vertex AI 拡張(R&D / 中規模 / 想定 Payback 18 ヶ月)→ MAS-042 R&D ハードル 24 ヶ月 → Go
- Jr 採用(HC / 大規模 / 想定 Payback 30 ヶ月)→ MAS-042 HC ハードル 24 ヶ月 → No-Go(または Conditional Go)
- 機材更新(CAPEX / 小規模 / 想定 Payback 12 ヶ月)→ MAS-042 CAPEX ハードル 36 ヶ月 → Go
- Vertex AI 拡張のシミュレーション完了: MAS-013 計算結果(Payback 18 ヶ月)を本マスタに反映・ハードル 24 ヶ月 → Go 判定維持
- Jr 採用(D-180)の登録: HC カテゴリ・想定金額 600 万(TCO)・MAS-048 採用 TCO シミュレーション結果反映
- 過去案件(PR #459 cockpit 拡張)の遡及登録: 完了案件として実績 ROI 反映
- Go/No-Go 一覧表示: ステータス
検討中3 件のうち、Go 2 件 / No-Go 1 件 を 1 画面で確認
関連ドキュメント
| 仕様書・ドキュメント | 関連箇所 |
|---|---|
| dev_mas-013_investment_simulation.md | 計算エンジン・本マスタへの連携経路。シミュレーション結果から「カタログに登録」ボタン経由で本マスタに保管 |
| dev_mas-042_investment_hurdle_rate.md | Go/No-Go 判定の閾値マスタ。findByCategory(category) で対応する閾値取得・自動判定 |
| dev_mas-050_investment_roi_benchmark.md | 後続案件(本マスタが前提)。業種別 Payback 中央値と自社実績の比較 |
| dev_mas-052_lightweight_stage_gate.md | ステージ管理の連携(将来)。本マスタの ステータス 列と Stage-Gate ステージの対応 |
| dev_mas-055_saas_catalog_master.md | 同パターンマスタの先例。Repository + cockpit パネルの実装テンプレート |
| dev_mas-067_multiyear_planning_workspace.md | 多年計画統合(将来 v2)。多年シミュレーション内の投資項目を本マスタから引き当て |
| dev_mas-048_hiring_tco_bep_simulator.md | HC 投資の実績連携。Jr 採用案件の TCO 計算結果を本マスタに反映 |
| CLAUDE.md | コーディング規約(ヘッダー名ベース列参照・有効フラグスキップ・キャッシュ付きマスタ) |
| failure_patterns.md | #18-#20 命名造語禁止 / #25 並列実装対称性 / #31 ID 衝突回避 |
人間が検討すべき事項
Q1. 関連 ORD/INV の 1:N 関係の表現
- 案 X:
関連 ORD ID/関連 INV ID列にカンマ区切り or JSON 配列で複数 ID 保存 - 案 Y: 別タブ
30b_mst_investment_catalog_linksで正規化(1 投資 N 関連)
トレードオフ:
- 案 X: 実装シンプル・既存 PartnerRepository 等のパターン踏襲・検索性は劣る(GAS 側で split 必須)
- 案 Y: 正規化された綺麗な構造・JOIN 処理が必要・実装コスト増
推奨: 案 X(カンマ区切り) 推奨理由: 1 投資あたり関連 ORD/INV は通常 1-3 件で正規化のメリット小。既存 PartnerRepository 等のパターン踏襲で実装統一性。検索が必要になった時点(投資数 100 件超)で案 Y に移行検討。
Q2. MAS-013 シミュレーション側の変更との同期
- 案 X: 本マスタが SSoT・MAS-013 結果は本マスタに保存後、編集は本マスタ側のみ
- 案 Y: MAS-013 計算結果が SSoT・本マスタは参照のみ(編集ロック)
トレードオフ:
- 案 X: メタデータ管理の主体が本マスタ・MAS-013 は計算機(使い捨て)として明確化・本マスタの完全性が保たれる
- 案 Y: MAS-013 が SSoT・本マスタに編集できないと UI 上の不便
推奨: 案 X(本マスタ SSoT) 推奨理由: メタデータ管理の主体は本マスタ。MAS-013 は計算機として「シミュレーション → 本マスタへ転記 → 本マスタ側で編集」の一方向フローを確立する。MAS-013 を再実行した場合の取り扱いはエッジケース #11 で警告のみ(自動上書きしない)。
Q3. UI 配置の選択
- 案 X: cockpit パネル(
webapp_client/src/cockpit/InvestmentCatalogPanel.tsx) - 案 Y: サイドバー(MAS-232 サイドバー SPA 配下)
- 案 Z: 独立 Web アプリ(将来)
トレードオフ:
- 案 X: 経営判断の中核 UI として一元化・cockpit の他パネル(PL/BS/CF)と並列表示可能
- 案 Y: GAS スプレッドシート上での操作が中心の場合に親和性高
- 案 Z: 将来の独立運用・実装コスト最大
推奨: 案 X(cockpit パネル) 推奨理由: MAS-057 cockpit が経営判断のメインビュー。投資判断は経営判断の中核であり、cockpit の他パネル(PL/BS/CF・MAS-067 マルチイヤー)と並列表示することで「投資 → 財務影響」の俯瞰が可能。
Q4. 過去案件の遡及登録
- 案 X: migration script で
67_report_investment_analysisから自動抽出 - 案 Y: 手動投入のみ
トレードオフ:
- 案 X: 過去 12 ヶ月分のシミュレーション結果を初期データとして自動投入・冪等性ガードで安全・初期データ充実
- 案 Y: 手動投入工数大・過去案件の見落としリスク
推奨: 案 X(自動抽出) 推奨理由: 過去 12 ヶ月分のシミュレーション結果を初期データとして自動投入。冪等性ガード(既存 ID は上書きしない)で再実行安全。手動修正は投入後に UI から可能。
Q5. ハードルレート変更時の再評価
- 案 X: バッチ再判定 API 提供(
InvestmentCatalogRepository.recalculateGoNoGoAll()) - 案 Y: 個別案件編集時のみ再評価
トレードオフ:
- 案 X: 一括変更が容易・MAS-042 ハードルレート変更時の運用効率高・ログで再評価結果を可視化
- 案 Y: 個別編集時のみ再評価のため一括変更時の運用負荷大
推奨: 案 X(バッチ提供) + 案 Y(個別編集時)の併用
推奨理由: 両方提供する。MAS-042 ハードルレート変更時はメニューから手動でバッチ実行(💼 投資管理 → Go/No-Go 一括再判定)。個別編集時は自動再評価でリアルタイム性確保。
その他検討事項
- 業界ベンチマーク連携の本格実装: MAS-050 完成後に本マスタの「業界 Payback 中央値」列を追加するか
- タグ機能の高度化: 現状はカンマ区切りフリーテキスト。将来的にタグマスタ化するか
- アラート機能: ステータス
実行中案件で完了予定日を過ぎた場合の自動通知 - 権限管理: 投資情報の機密性から、cockpit パネルのアクセス権限を Solo-CEO のみに制限するか(MAS-200 個人情報保護連携)
- MAS-067 連携時のシナリオ別投資: 多年計画でシナリオ A/B/C で投資案件を切り替えるユースケースのサポート
実装プロンプト(Claude Code 用)
あなたは GAS 会計システム (bizlp-gas-accounting) のシニア開発者です。
案件 MAS-046「投資カタログマスタ」を以下の 5 Step で実装してください。
MAS-013(投資回収シミュレーション)/ MAS-042(投資ハードルレートマスタ)/ MAS-055(SaaS カタログマスタ)が前提。
## 実行前タスク(必須・5 件)
1. `200_data/202_repository.js` の `PartnerRepository` / `AccountRepository` を Read し、Repository パターンを確認
2. `100_config/101_sys_config.js` の `schemas`(L879 起点)で MAS-055 `MST_SAAS_TMPL` の記述位置を確認
3. `000_infra/002_constants.js` の `Constants.ID_PREFIXES` を Read し、既存 ID プレフィックス命名規則を確認(failure_patterns #18-#20 回避)
4. `docs/dev/dev_mas-013_investment_simulation.md` を Read し、`67_report_investment_analysis` のヘッダー構成を確認
5. `docs/dev/dev_mas-042_investment_hurdle_rate.md` を Read し、`findByCategory()` の戻り値構造を確認
## Step 1: DDL シート追加 + Constants 拡張(推奨モデル: Sonnet)
- `100_config/101_sys_config.js` `schemas` に `MST_INVESTMENT_CATALOG` 追加(22 列・MAS-055 `MST_SAAS_TMPL` の直下に配置推奨)
- `existKeys` に 1 行追加
- `MENU_DEFINITION` に「💼 投資管理」セクション追加(4 メニュー)
- `000_infra/002_constants.js` の `Constants.ID_PREFIXES` に `INV_CAT: 'INV_CAT_'` 追加
- 単体テスト F046-01〜F046-05
- `npm run push:dev` → `setupAllSchemas` 実行 → `30_mst_investment_catalog` 生成確認
## Step 2: Repository 新設 + マスタシード migration(推奨モデル: Sonnet)
- 新規ファイル: `200_data/205_investment_catalog_repository.js`(~200 行・PartnerRepository パターン踏襲)
- `findAll` / `findById` / `findByStatus` / `findByCategory` / `save` / `linkActuals` / `recalculateGoNoGoAll` / `resetCache` を実装
- 新規ファイル: `800_ops/8XX_migration_investment_catalog_seed.js`(番号は実装着手時に最新確認・本仕様書時点で 824 以降を想定)
- 過去 12 ヶ月の `67_report_investment_analysis` から抽出 + 現在検討中 3 案件投入
- 冪等性ガード必須(既存 ID は上書きしない)
## Step 3: cockpit パネル + メニュー(推奨モデル: Sonnet)
- 新規ファイル: `webapp_client/src/cockpit/InvestmentCatalogPanel.tsx`(約 400 行)
- 投資案件一覧テーブル(ステータス別フィルタ)
- 新規作成ダイアログ(MAS-013 シミュレーション結果から自動入力)
- 完了案件の実績反映 UI
- `100_config/101_sys_config.js` `MENU_DEFINITION` に「💼 投資管理」セクション 4 メニュー追加
- 単体テスト F046-06〜F046-08
## Step 4: MAS-013/042 連携(推奨モデル: Opus)
- MAS-013 シミュレーション結果から「カタログに登録」ボタン追加(連携経路実装)
- MAS-042 ハードルレートと自動 Go/No-Go 判定(`Constants.ID_PREFIXES` 命名規則踏襲)
- 手動上書き UI 提供(`判定根拠` 列に記録)
- バッチ再判定 API(`recalculateGoNoGoAll()`)
- 単体テスト F046-09〜F046-11
## Step 5: 完了案件の実績反映 + 監査ログ(推奨モデル: Haiku)
- ステータス完了時に MAS-013 から実績 Payback / ROI 取得(`linkActuals()` 実装)
- 監査ログ(`Utils.auditLog('INV_CATALOG_COMPLETED', catalogId, ...)`)
- 異常遷移(`完了 → 検討中`)の警告ダイアログ
- 単体テスト F046-12
## 制約
- `appsscript.json` の `oauthScopes` を変更しない(failure_patterns #26 回避)
- 列番号ハードコード禁止(CLAUDE.md コーディング規約)
- MAS-055 との並列実装対称性を維持(failure_patterns #25)
- MAS-013 / MAS-042 の既存動作を破壊しない(一方向連携)
- ID プレフィックス `INV_CAT_` を Constants 経由で参照(直接文字列リテラル禁止)
## 動作確認
1. cockpit 起動 → 「💼 投資管理 → 投資カタログ表示」 → 案件一覧表示
2. MAS-013 シミュレーション実行 → 「カタログに登録」 → 本マスタに新規追加
3. ステータス変更 `検討中 → 実行中` → 監査ログ記録
4. ステータス変更 `実行中 → 完了` → 実績反映ダイアログ → 保存
5. MAS-042 ハードルレート変更 → 「Go/No-Go 一括再判定」 → 全案件再評価
6. `01_sys_config` に `MST_INVESTMENT_CATALOG` が登録されている
推奨実行モデル
| 工程 | 推奨モデル | 理由 |
|---|---|---|
| Step 1: DDL + Constants | Claude Sonnet 4.6 | MAS-055 パターン応用 + Constants 衝突確認の判断 |
| Step 2: Repository + シード | Claude Sonnet 4.6 | PartnerRepository パターンの同型複製 + 過去データ抽出ロジック |
| Step 3: cockpit パネル + メニュー | Claude Sonnet 4.6 | React + cockpit パネルパターン応用・既存パネルとの統合判断 |
| Step 4: MAS-013/042 連携 | Claude Opus 4 | Go/No-Go 判定ロジック設計判断・複数ファイル横断 |
| Step 5: 実績反映 + 監査ログ | Claude Haiku 4.5 | 機械的書込・既存パターン踏襲 |
変更履歴
| 日付 | 変更内容 |
|---|---|
| 2026-05-01 | v0.1 起票(main 側起票依頼を受けて MAS-046 として起草。FP&A マスタ系 P2.5 として位置づけ・MAS-013/042 連携 + MAS-050 ベンチマーク比較の前提案件として整理。Q1-Q5 推奨判断 + Step 1-5 段階リリース計画。MAS-055 SaaS カタログマスタの同パターン実装で実装コスト削減。FP&A データ層基盤の補完強化として、投資案件のメタデータ統合管理マスタ層を新設し、Solo-CEO が複数投資案件の Go/No-Go を 1 画面で俯瞰できる基盤を整備。エッジケース 14 件・人間検討事項 10 件・推奨実行モデル 5 工程(Sonnet×3 / Opus×1 / Haiku×1)を定義) |
仕様書作成プロンプト(本仕様書を生成した際のプロンプト全文)
あなたは bizlp-gas-accounting プロジェクトの仕様書起票担当です。新規仕様書 **MAS-046: 投資カタログマスタ (Investment Catalog Master)** の本体を起草し、ファイルに書き出してください。
## ゴール
`docs/dev/dev_mas-046_investment_catalog_master.md` を新規作成。約 500〜700 行・14 セクション全網羅・`docs/_internal/dev_spec_prompt_template.md` のテンプレート遵守。
## 案件位置づけ (確定済)
- **案件 ID**: MAS-046 (TODO_future.md §1 P2.5・💾 Data カテゴリ・FP&A マスタ系)
- **背景**: TODO_future.md 行 47「P2.5 自動入力パイプライン(拡張)+ SaaS連携 + D.8-D.10 補助機能 - **MAS-046(投資カタログマスタ🆕D)**, MAS-047(RICE スコアリング🆕D), **MAS-050(ベンチマーク比較🆕D)**, MAS-051(PSF KPI ダッシュボード🆕D)」
- **連携先**: MAS-013 (投資回収シミュレーション・既存) / MAS-042 (投資ハードルレートマスタ・InProgress) / MAS-050 (投資回収ベンチマーク・後続案件) / MAS-055 (SaaS カタログマスタ・パターン参考)
## 背景・問題意識
### 現状の制約
bizlp の投資判断機能は MAS-013 (投資回収シミュレーション) + MAS-042 (投資ハードルレート) で構成されているが、**投資案件のカタログ的な保管機構がない**:
- MAS-013 の投資シミュレーションは個別のシナリオ計算機・**過去・現在・将来の投資案件を一覧で管理する仕組みがない**
- MAS-042 のハードルレートマスタは**判定基準のみ**保管 (Payback 年数・ROI 等)
- 投資案件の「過去実績」「現在進行中」「検討中」のステータス追跡が手動 Excel ベース
- 業界ベンチマーク (例: SaaS 業界の SaaS 投資 Payback 中央値 = 12 ヶ月) の比較が困難
### 顕在化している不足
- **複数投資案件の Go/No-Go 一覧管理**: 「現在検討中の投資 3 件のうち、ハードルレートを満たす案件はどれか」を一画面で確認できない
- **業種別投資ベンチマーク比較**: MAS-050 (投資回収ベンチマーク・後続) の前提として、bizlp 内に投資案件のメタデータ (業種・カテゴリ・規模) が必要
- **投資カテゴリ別の傾向分析**: 「過去 3 年の HC 投資 vs CAPEX 投資の Payback 平均」等の分析が手動
- **将来の MAS-067 マルチイヤー計画統合**: 多年シミュレーション内で投資案件をマスタとして引き当てる仕組み
### User Story
- **Solo-CEO**: 「現在検討中の投資 3 案件 (Vertex AI 拡張 / Jr 採用 / 機材更新) のうち、Go 判定を 1 画面で見たい」
- **Solo-CEO**: 「過去の HC 投資の Payback が業界中央値より早いか確認したい」
- **MAS-067 マルチイヤー連携**: 「3 年後の追加投資 X 億をマスタから引き当てたい」
- **MAS-050 ベンチマーク比較**: 「業種別 (IT / コンサル / 製造) の Payback 中央値と自社実績を比較したい」
## frontmatter (先頭)
```yaml
---
id: MAS-046
aliases: ["F-46", "INVESTMENT-CATALOG"]
type: Story
status: Open
---
```
## 仕様書に必ず含めるべき内容
### Section 1. 概要 (frontmatter + 概要テーブル)
| 項目 | 内容 |
|---|---|
| 案件 ID | MAS-046 |
| カテゴリ | 💾 Data (FP&A マスタ系) |
| Phase | P2.5 |
| 優先度 | ★★ |
| 所要時間 | 推定 1-2 週間 |
| 対象ファイル | (新規) `200_data/205_investment_catalog_repository.js` (新設) / (新規) `100_config/101_sys_config.js` schemas に `30_mst_investment_catalog` 追加 / (新規) `webapp_client/src/cockpit/InvestmentCatalogPanel.tsx` |
| 前提案件 | MAS-013 (投資回収シミュレーション・既存) / MAS-042 (投資ハードルレートマスタ・InProgress) / MAS-055 (SaaS カタログマスタ・パターン参考) |
| 後続案件 | MAS-050 (投資回収ベンチマーク・本マスタが前提) / MAS-052 (軽量版 Stage-Gate) / MAS-067 (マルチイヤー計画・投資案件引き当て・将来連携) |
### Section 2. 目的
上記の問題意識・User Story 4 件・MAS-013 / MAS-042 / MAS-050 / MAS-055 / MAS-067 との位置づけ。**「個別投資シミュレーションを越えて、投資案件のメタデータを統合管理するマスタ層」**を一文で明示。
### Section 3. 現在のコード (検証済の正確な参照)
以下を Read で確認したうえで記述:
- `100_config/101_sys_config.js` の `schemas` 配列の DDL パターン
- `200_data/202_repository.js` の Repository パターン (cache + findAll + save + append)・特に `PartnerRepository` / `AccountRepository` 等のマスタ系を Read
- `docs/dev/dev_mas-055_saas_catalog_master.md` の SaaS マスタ設計パターン (本案件のテンプレート)
- `docs/dev/dev_mas-013_investment_simulation.md` の投資回収シミュレーションのデータ構造 (連携先)
- `docs/dev/dev_mas-042_investment_hurdle_rate.md` のハードルレートマスタ (前提案件)
### Section 4. 修正方針
#### 4.1 シート設計
新規シート `30_mst_investment_catalog` (DDL 管理):
| 列 | 内容 | 例 |
|---|---|---|
| `投資カタログID` | `INV_CAT_NNNN` (4 桁連番) | `INV_CAT_0001` |
| `案件名` | 案件のタイトル | `Vertex AI 拡張・dev quota` |
| `投資カテゴリ` | `HC` / `CAPEX` / `SAAS` / `R&D` / `MARKETING` / `OTHER` | `R&D` |
| `業種` | 自社業種 (IT / コンサル / 製造 / 小売 / 飲食) | `IT` |
| `投資規模` | `小 (<100万)` / `中 (100-1,000万)` / `大 (1,000万-)` | `中` |
| `想定金額` | 投資総額 (税込・JPY) | `300万` |
| `想定 Payback (月)` | 想定回収期間 | `18` |
| `想定 ROI (%)` | 想定 ROI | `35%` |
| `ステータス` | `検討中` / `実行中` / `完了` / `中止` / `保留` | `検討中` |
| `Go/No-Go 判定` | `Go` / `Conditional Go` / `No-Go` / `未判定` (MAS-042 連携) | `未判定` |
| `判定根拠` | 自由記述 (MAS-042 ハードルレートとの比較根拠) | `Payback 18 < 24 で Go` |
| `関連 ORD ID` | 関連発注 ID (32_wrk_invoice 連携) | `ORD_2026_0123` |
| `関連 INV ID` | 関連請求 ID | `INV_20260331_0045` |
| `開始予定日` / `完了予定日` | 投資期間 | `2026-04-01 / 2027-09-30` |
| `実績 Payback (月)` | 完了後の実績 (完了時に MAS-013 から取得) | (空欄) |
| `実績 ROI (%)` | 実績 ROI | (空欄) |
| `備考` / `タグ` | フリーテキスト | `Vertex AI 検証段階` |
| `作成日時` / `更新日時` | 監査列 | `2026-05-01` |
| `有効フラグ` | true / false | `true` |
#### 4.2 InvestmentCatalogRepository (新規)
`200_data/205_investment_catalog_repository.js`:
- `InvestmentCatalogRepository.findAll()` - 全件取得 + キャッシュ
- `InvestmentCatalogRepository.findByStatus(status)` - ステータス別取得
- `InvestmentCatalogRepository.findByCategory(category)` - カテゴリ別取得
- `InvestmentCatalogRepository.save(catalog)` - 1 件保存 (新規 / 更新)
- `InvestmentCatalogRepository.findById(catalogId)` - ID で 1 件取得
- `InvestmentCatalogRepository.linkActuals(catalogId, payback, roi)` - 完了時に実績値を反映 (MAS-013 連携)
#### 4.3 UI (cockpit パネル or サイドバー)
`webapp_client/src/cockpit/InvestmentCatalogPanel.tsx` (新規) または `webapp_client/src/sidebar/InvestmentCatalogSidebar.tsx`:
- 投資案件一覧テーブル (ステータス別フィルタ)
- 新規作成ダイアログ (MAS-013 シミュレーション結果から自動入力)
- Go/No-Go 判定 (MAS-042 ハードルレート連携で自動判定)
- 完了案件の実績反映 UI
#### 4.4 メニュー
`100_config/101_sys_config.js` の MENU_DEFINITION に「💼 投資管理 → 投資カタログ表示」「💼 投資管理 → 新規案件登録」を追加。
#### 4.5 マスタシード migration (`800_ops/8XX_migration_investment_catalog_seed.js`)
- 既存の MAS-013 シミュレーション結果 (`67_report_investment_analysis`) をスキャンし、初期投入候補として抽出
- bizlp の現在検討中 3 案件 (例: Vertex AI 拡張 / Jr 採用 / 機材更新) をシード投入
### Section 5. 影響範囲
- **新規ファイル**: `200_data/205_investment_catalog_repository.js` / `webapp_client/src/cockpit/InvestmentCatalogPanel.tsx` / `800_ops/8XX_migration_investment_catalog_seed.js` (実装着手時に番号確定・822 まで使用済 + MAS-336/337/338 で予約・824 以降を採番)
- **DDL 拡張** (`100_config/101_sys_config.js`): `30_mst_investment_catalog` 1 シート追加
- **MAS-013 投資回収シミュレーション**: シミュレーション結果から「カタログに登録」ボタン追加・本マスタへの連携経路
- **MAS-042 ハードルレート判定**: `findByCategory(category)` で対応する閾値取得・自動判定
- **MAS-050 ベンチマーク比較**: 後続案件・本マスタが前提
- **MAS-067 マルチイヤー連携**: 将来 v2 で多年計画内の投資項目を本マスタから引き当て
### Section 6. 注意事項 (10-12 件)
1. **MAS-013 シミュレーション結果との重複**: シミュレーション (`67_report_investment_analysis`) は計算結果・本マスタはメタデータ。重複ではなく**役割分担** (計算 vs 管理)。
2. **ID 採番**: `INV_CAT_NNNN` 4 桁連番・既存 `Constants.ID_PREFIXES` 命名規則踏襲・`Constants.ID_PREFIXES.INV_CAT` 追加。
3. **ステータス遷移**: `検討中 → 実行中 → 完了` を主軸・`中止` / `保留` は例外的に許可。Action A 同様の遷移ルール明文化。
4. **Go/No-Go 判定の自動化**: MAS-042 ハードルレートとの比較で自動判定 + 手動上書き許可 (UI 上書き優先)。
5. **完了案件の実績反映**: ステータス `完了` 時に MAS-013 から実績 Payback / ROI を自動取得・手動入力許可。
6. **冪等性**: マスタシード migration は既存 ID を上書きしない (`既存_有り → スキップ`)。
7. **ヘッダー名一貫性**: 投資シミュレーション側 (MAS-013) のヘッダー名と整合・「投資カテゴリー」(MAS-013) → 「投資カテゴリ」(本マスタ) で表記揺れ防止。
8. **MAS-055 SaaS マスタとの並列性**: 同パターン実装で実装コスト削減・テストパターン共通化。
9. **GAS マニフェスト権限**: シート読み書きのみで OAuth スコープ追加なし。
10. **テストランナー**: `F046-01〜F046-12` を `901_test_runner.js` に追加。
11. **MAS-067 マルチイヤー連携時の Y0 着地予測**: 完了予定日が Y0 内なら実績想定・Y1 以降なら計画想定の区別。
12. **failure_patterns #31 (ID 衝突)**: 800_ops/ 採番は実装着手時に最新確認 (本仕様書時点で 822 + MAS-336/337/338 予約 = 824 以降)。
### Section 7. エッジケース (10-12 件)
1. ステータス `検討中` の案件で `関連 ORD ID` が空 → MAS-013 シミュレーションのみ実行段階で本マスタには未紐付け (NORMAL)
2. `投資カテゴリ` が「OTHER」 → MAS-042 ハードルレートで対応するカテゴリがない場合のフォールバック (デフォルト閾値 or 警告)
3. `想定 Payback` が空欄 → MAS-013 シミュレーション未実行案件 (検討初期段階) で許容
4. `実績 Payback` が `想定 Payback` を大きく超過 (50% 以上ずれ) → 警告表示 (要原因調査)
5. ステータス `中止` の場合の Go/No-Go 判定 → 判定列は無効化 (空欄表示)
6. 関連 ORD/INV が**複数 (1:N)** の場合 → JSON 配列保存 or 別タブで関連表 (Q1 で議論)
7. 投資カテゴリ追加 (例: `MARKETING` → `M&A`) → DDL 拡張 + 既存 ID 影響なし
8. 大規模投資 (1 億超) → `投資規模` 区分 4 段階目 `特大` を追加検討 (将来)
9. 複数組織での投資 (子会社) → 単一組織前提 (MAS-177 と整合)
10. 過去案件の遡及登録 → migration script で既存 67_report_investment_analysis から抽出
11. MAS-013 シミュレーション側で投資カテゴリ変更 → 本マスタの該当案件も自動更新 (要 Q2 議論)
12. ハードルレート変更 (MAS-042) → 既存案件の Go/No-Go 判定再評価が必要 (バッチ再判定 API)
### Section 8. 実データ検証 (具体シナリオ + 期待値)
1. **bizlp 現在検討中 3 案件投入**: Vertex AI 拡張 / Jr 採用 / 機材更新を投入・MAS-042 ハードルレートと比較し Go/No-Go 自動判定
2. **Vertex AI 拡張のシミュレーション完了**: MAS-013 計算結果 (Payback 18 ヶ月) を本マスタに反映・ハードル 24 ヶ月 → Go 判定
3. **Jr 採用 (D-180) の登録**: HC カテゴリ・想定金額 600 万 (TCO)・MAS-048 採用 TCO シミュレーション結果反映
4. **過去案件 (PR #459 cockpit 拡張) の遡及登録**: 完了案件として実績 ROI 反映
5. **Go/No-Go 一覧表示**: ステータス `検討中` 3 件のうち、Go 2 件 / No-Go 1 件 を 1 画面で確認
### Section 9. 関連ドキュメント
- [MAS-013 投資回収シミュレーション](dev_mas-013_investment_simulation.md) - 計算エンジン・本マスタへの連携経路
- [MAS-042 投資ハードルレートマスタ](dev_mas-042_investment_hurdle_rate.md) - Go/No-Go 判定の閾値マスタ
- [MAS-050 投資回収ベンチマーク](dev_mas-050_investment_roi_benchmark.md) - 後続案件 (本マスタが前提)
- [MAS-052 軽量版 Stage-Gate](dev_mas-052_*) - ステージ管理の連携 (将来)
- [MAS-055 SaaS カタログマスタ](dev_mas-055_saas_catalog_master.md) - 同パターンマスタの先例
- [MAS-067 マルチイヤー計画ワークスペース](dev_mas-067_multiyear_planning_workspace.md) - 多年計画統合 (将来 v2)
- [MAS-048 採用 TCO & BEP シミュレーター](dev_mas-048_hiring_tco_bep_simulator.md) - HC 投資の実績連携
- [失敗パターン #31](../../_internal/06_ops/failure_patterns.md) - ID 衝突回避ルール
### Section 10. 人間が検討すべき事項 (Q1-Q5 必須・推奨 + トレードオフ + 推奨理由)
#### Q1. 関連 ORD/INV の 1:N 関係の表現
- 案 X: `関連 ORD ID` / `関連 INV ID` 列に**カンマ区切り or JSON 配列**で複数 ID 保存
- 案 Y: 別タブ `30b_mst_investment_catalog_links` で正規化 (1 投資 N 関連)
- 推奨: **案 X (カンマ区切り)** - 1 投資あたり関連 ORD/INV は通常 1-3 件で正規化のメリット小・既存 PartnerRepository 等のパターン踏襲
#### Q2. MAS-013 シミュレーション側の変更との同期
- 案 X: 本マスタが SSoT・MAS-013 結果は本マスタに保存後、編集は本マスタ側のみ
- 案 Y: MAS-013 計算結果が SSoT・本マスタは参照のみ (編集ロック)
- 推奨: **案 X (本マスタ SSoT)** - メタデータ管理の主体・MAS-013 は計算機 (使い捨て)
#### Q3. UI 配置の選択
- 案 X: cockpit パネル (`webapp_client/src/cockpit/InvestmentCatalogPanel.tsx`)
- 案 Y: サイドバー (MAS-232 サイドバー SPA 配下)
- 案 Z: 独立 Web アプリ (将来)
- 推奨: **案 X (cockpit パネル)** - MAS-057 cockpit が経営判断のメインビュー・投資判断は経営判断の中核
#### Q4. 過去案件の遡及登録
- 案 X: migration script で `67_report_investment_analysis` から自動抽出
- 案 Y: 手動投入のみ
- 推奨: **案 X (自動抽出)** - 過去 12 ヶ月分のシミュレーション結果を初期データとして自動投入・冪等性ガード必須
#### Q5. ハードルレート変更時の再評価
- 案 X: バッチ再判定 API 提供 (`InvestmentCatalogRepository.recalculateGoNoGoAll()`)
- 案 Y: 個別案件編集時のみ再評価
- 推奨: **案 X (バッチ提供) + 案 Y (個別編集時)** - 両方提供・MAS-042 ハードルレート変更時は手動でバッチ実行
### Section 11. 実装プロンプト (Claude Code 用・Step 1-5)
(本文中の実装プロンプトに記載)
### Section 12. 推奨実行モデル (Step ごと)
- Step 1 DDL + Repository: Sonnet (既存パターン応用)
- Step 2 マスタシード: Sonnet (機械的展開)
- Step 3 UI + メニュー: Sonnet (cockpit パネルパターン応用)
- Step 4 MAS-013/042 連携: Opus (Go/No-Go 判定ロジック設計判断)
- Step 5 実績反映: Haiku (機械的書込)
### Section 13. 変更履歴
| 日付 | 変更内容 |
|---|---|
| 2026-05-01 | v0.1 起票(main 側起票依頼を受けて MAS-046 として起草。FP&A マスタ系 P2.5 として位置づけ・MAS-013/042 連携 + MAS-050 ベンチマーク比較の前提案件として整理。Q1-Q5 推奨判断 + Step 1-5 段階リリース計画。MAS-055 SaaS カタログマスタの同パターン実装で実装コスト削減。**FP&A データ層基盤の補完強化**) |
### Section 14. 仕様書作成プロンプト (`<details>` で本プロンプトを丸ごと格納)
## 進め方
1. まず以下の参照ファイルを Read して理解 (それぞれ読み終えたら破棄して構わない・本タスクではノート程度でOK):
- `docs/_internal/dev_spec_prompt_template.md` (テンプレート構造を把握)
- `docs/dev/dev_mas-055_saas_catalog_master.md` (SaaS マスタパターン・本案件のテンプレート)
- `docs/dev/dev_mas-013_investment_simulation.md` (連携先・データ構造把握)
- `docs/dev/dev_mas-042_investment_hurdle_rate.md` (ハードルレートマスタ・前提案件)
- `100_config/101_sys_config.js` の `schemas` 配列冒頭 (DDL パターン把握・READ のみ)
2. `docs/dev/dev_mas-046_investment_catalog_master.md` を Write で**1 回の出力で**作成 (約 500〜700 行)
3. テンプレートのセクション構成と本プロンプト記載のセクションリストの両方を満たすこと
4. `<details>` ブロック (Section 14) には**本プロンプト全文を丸ごと**コピーすること
## 制約
- sub workspace 制約: `100_config/`, `200_data/`, `400_domain/`, `500_import/`, `600_report/`, `800_ops/`, `webapp_client/src/`, `appsscript.json` は触らない (READ のみ可)
- 仕様書本体のみ書き出す。`docs/_config.json` 反映 / `id_mapping_table.csv` / `todo_master_tables.md` / `changelog.md` 更新 / 関連 spec のクロスリンク追記は親が担当
- 1 つの Write tool call で全文を出力すること (500-700 行は 1 call で十分)
- 出力後はファイルパスと行数を報告するだけでよい (要約や説明は不要)
実行してください。