• #refactoring
  • #typescript
  • #financial-data
  • #handoff
開発アクティブ

財務データ構造リファクタリング - 引き継ぎドキュメント

進捗状況(2026-01-05確認): 未着手

  • ❌ 型定義(PLData配列型への変更)未実装
  • ❌ 【】検証用項目の除外処理未実装
  • ❌ 「資本金等」合算表示未実装
  • ❌ useNvidiaData.ts等の再生成未実施

TODOリスト(進捗管理用)

#タスク状態詳細
1型定義の更新⬜ 未着手ProportionalFinancialStatementsAnimated.vueCompanyData型を新構造に変更
2表示コンポーネントの対応⬜ 未着手【】検証用項目の除外、「資本金等」合算表示の実装
3既存composablesの移行⬜ 未着手useNvidiaData.ts等を新しいプロンプトで再生成
4ブラウザでの動作確認⬜ 未着手表示が正しいかChrome DevToolsで確認

状態の凡例: ⬜ 未着手 / 🔄 作業中 / ✅ 完了


背景

Gemini APIで財務データを変換する際、集約ロジック(例:資本金+資本剰余金→資本金等)がブレる問題があった。これを解決するため、データ構造を以下の方針で変更した。

  1. 生データをそのまま転記(Geminiには単純な転記のみさせる)
  2. 集約・計算はコンポーネント側で実行(ロジックをコードで制御)
  3. Total値を検証用に出力(差額計算の検証が可能)

今回のセッションで完了した作業

1. Geminiプロンプトの更新

ファイル: apps/web/content/2025-12-11/qqq-financial-data-pipeline.md

BS(貸借対照表)の変更

流動資産 (currentAssets):

【総資産】: Total Assets(検証用)
【流動資産合計】: Total Current Assets(検証用)
現預金・短期投資: Total Cash And Short Term Investments
売掛金: Total Receivables
棚卸資産: Inventory
その他流動資産: Total Current Assets - 上記3項目(差額算出)

固定資産 (fixedAssets):

有形固定資産: Net Property Plant And Equipment
長期投資: Long-term Investments(独立項目・株式/債券等)
のれん: Goodwill
無形資産: Other Intangibles
繰延税金資産: Deferred Tax Assets Long-Term
その他長期資産: Other Long-Term Assets(調整項目)

※ 固定資産合計 = Total Assets - Total Current Assets で検証
※ Long-term InvestmentsはGoodwill等の上位カテゴリではなく独立項目

流動負債 (currentLiabilities):

【流動負債合計】: Total Current Liabilities(検証用)
買掛金: Accounts Payable
短期借入金: Short-Term Debt
短期リース: Current Portion of Leases(元データにある場合のみ)
前受収益(流動): Unearned Revenue (Current)(元データにある場合のみ)
その他流動負債: Total Current Liabilities - 上記の独立掲記した項目(差額算出)

固定負債 (fixedLiabilities):

【負債合計】: Total Liabilities(検証用)
長期借入金: Long-Term Debt
長期リース: Long-Term Leases(元データにある場合のみ)
長期前受収益: Unearned Revenue (Non-Current)(元データにある場合のみ)
その他固定負債: (Total Liabilities - Total Current Liabilities) - 上記の独立掲記した項目(差額・調整項目)

純資産 (equity):

【純資産合計】: Total Equity(検証用)
資本金: Common Stock
資本剰余金: Additional Paid In Capital
利益剰余金: Retained Earnings
自己株式: Treasury Stock(負の値)
その他包括利益: Accumulated Other Comprehensive Income

PL(損益計算書)の変更

売上高・売上総利益 (revenue):

【売上高】: Total Revenues(検証用)
【売上総利益】: Gross Profit(検証用)
売上原価: Cost Of Revenues
※ 売上高 - 売上原価 = 売上総利益 で検証

営業費用 (operatingExpenses):

【営業利益】: Operating Income(検証用)
販管費: Selling General & Admin Expenses
研究開発費: R&D Expenses
減価償却費: Depreciation & Amortization(元データにある場合のみ)
その他営業費用: Other Operating Expenses(元データにある場合のみ)
※ 売上総利益 - 営業費用合計 = 営業利益 で検証

営業外損益 (nonOperating):

支払利息: Interest Expense(負の値)
受取利息・投資収益: Interest And Investment Income
その他営業外損益: Other Non Operating Income (Expenses)(元データにある場合のみ)

税金・純利益 (netIncome):

【税引前利益】: EBT, Incl. Unusual Items(検証用)
【純利益】: Net Income(検証用)
法人税等: Income Tax Expense
※ 税引前利益 - 法人税等 = 純利益 で検証

2. NVDAデータでの検証結果

固定資産の構造を検証し、Long-term Investmentsが上位カテゴリではなく独立項目であることを確認:

FY2025検証:
Total Assets: 111,601M
Total Current Assets: 80,126M
固定資産合計(計算値): 31,475M

固定資産の内訳:
- Net PPE: 8,076M
- Long-term Investments: 3,387M
- Goodwill: 5,188M
- Other Intangibles: 807M
- Deferred Tax Assets: 10,979M
- Other Long-Term Assets: 3,038M
合計: 31,475M ✓

次のセッションでやるべき作業

1. TypeScript型定義の更新(破壊的変更)

ファイル: apps/web/components/financial-quiz/ProportionalFinancialStatementsAnimated.vue

現在の型定義を新しい構造に対応させる必要がある。

重要: 従来形式(pl.revenue: number, expenses.sga等)は削除されたため、アプリケーション側の修正が必須。

変更前(現在):

interface CompanyData {
  name: string;
  periods: {
    label: string;
    data: {
      bs: {
        currentAssets: { label: string; value: number }[];
        fixedAssets: { label: string; value: number }[];
        currentLiabilities: { label: string; value: number }[];
        fixedLiabilities: { label: string; value: number }[];
        equity: { label: string; value: number }[];
      };
      pl: {
        revenue: number;        // ← 削除
        grossProfit: number;    // ← 削除
        operatingIncome: number;// ← 削除
        profit: number;         // ← 削除
        expenses: number;       // ← 削除
      };
      expenses: {               // ← 削除
        sga: number;
        rd: number;
      };
      // ...
    };
  }[];
}

変更後(新構造):

interface CompanyData {
  name: string;
  periods: {
    label: string;
    data: {
      bs: {
        currentAssets: { label: string; value: number }[];
        fixedAssets: { label: string; value: number }[];
        currentLiabilities: { label: string; value: number }[];
        fixedLiabilities: { label: string; value: number }[];
        equity: { label: string; value: number }[];
      };
      pl: {
        revenue: { label: string; value: number }[];           // 売上高・売上総利益
        operatingExpenses: { label: string; value: number }[]; // 営業費用(SG&A, R&D含む)
        nonOperating: { label: string; value: number }[];      // 営業外損益
        netIncome: { label: string; value: number }[];         // 税金・純利益
      };
      // expenses セクションは削除(pl.operatingExpenses に統合)
      cashFlow: { ... };
      perShare: { ... };
    };
  }[];
}

アプリケーション側で必要な対応

従来形式を使用していた箇所は、新しい配列から値を取得するように変更が必要:

// 変更前
const revenue = period.data.pl.revenue;
const sga = period.data.expenses.sga;

// 変更後
const revenue = period.data.pl.revenue.find(i => i.label === '【売上高】')?.value || 0;
const sga = period.data.pl.operatingExpenses.find(i => i.label === '販管費')?.value || 0;

// または検証用項目を除外した値を取得
const revenueItems = period.data.pl.revenue.filter(i => !i.label.startsWith(''));

2. 表示コンポーネントの対応

BSの表示時に、【】で囲まれた検証用項目を除外するか別扱いにする必要がある。

// 検証用項目を除外して表示
const displayItems = items.filter(item => !item.label.startsWith(''));

// または検証用項目は別セクションに表示
const totalItems = items.filter(item => item.label.startsWith(''));
const detailItems = items.filter(item => !item.label.startsWith(''));

3. 既存composablesの移行

以下のファイルを新しい構造に更新する必要がある。

apps/web/app/composables/
├── useNvidiaData.ts      # 要更新
├── useMicrosoftData.ts   # 要更新(存在する場合)
└── ... 他のcomposables

変更点:

  • pl セクション: 数値型 → 配列型に変更
  • expenses セクション: 削除(pl.operatingExpenses に統合)
  • BS各セクション: 検証用【】項目を先頭に追加
  • 純資産: 「資本金等」→「資本金」「資本剰余金」に分離

4. BSでの「資本金等」表示対応

純資産セクションで「資本金」と「資本剰余金」を合算して「資本金等」として表示する処理。

// 表示時に合算
const equityForDisplay = computed(() => {
  const items = period.data.bs.equity;
  const commonStock = items.find(i => i.label === '資本金')?.value || 0;
  const apic = items.find(i => i.label === '資本剰余金')?.value || 0;

  return [
    { label: '資本金等', value: commonStock + apic },
    ...items.filter(i => !['資本金', '資本剰余金'].includes(i.label))
  ];
});

関連ファイル

ファイル説明
apps/web/content/2025-12-11/qqq-financial-data-pipeline.mdGemini用プロンプト(更新済み)
apps/web/content/2025-12-10/financial-data-conversion-prompt.md旧プロンプト(一部更新済み)
apps/web/data/financial-raw/20251210/NVDA_20251210.tsvNVDA生データ(検証用)
apps/web/app/composables/useNvidiaData.tsNVDAデータ(要更新)
apps/web/components/financial-quiz/ProportionalFinancialStatementsAnimated.vue表示コンポーネント(要更新)

注意事項

  • レガシーフィールドは削除済み - pl.revenueTotal, expenses.sga, expenses.rd等の従来形式は削除されたため、アプリケーション側の修正が必須
  • 【】で囲まれた項目は検証用なので、ユーザーに表示する際は除外または別扱いにする
  • Long-term InvestmentsはGoodwill等の上位カテゴリではなく、独立した投資項目
  • 差額計算の調整項目は「その他長期資産」(資産側)と「その他固定負債」(負債側)