# 機能設計書 34-カテゴリ別支出

## 概要

本ドキュメントは、カテゴリごとの支出内訳を表示するレポート機能について記述する。

### 本機能の処理概要

**業務上の目的・背景**：家計管理において、「どのカテゴリに最もお金を使っているか」を把握することは、支出削減や予算配分の見直しに不可欠である。本機能は、支出をカテゴリ別に分類・集計し、グラフや表形式で視覚化することで、ユーザーが支出パターンを分析し、より効果的な予算管理を行えるよう支援する。

**機能の利用シーン**：
- 月次の支出内訳確認
- 特定カテゴリの支出傾向分析
- 支出削減対象カテゴリの特定
- カテゴリ別予算と実績の比較
- ダッシュボードでの支出サマリー表示

**主要な処理内容**：
1. カテゴリグループとカテゴリの階層取得
2. カテゴリの選択・フィルタリング機能の提供
3. 選択されたカテゴリに対する取引データの集計
4. グラフ（棒グラフ、円グラフ等）用データの生成
5. カテゴリ別の合計金額と割合の計算
6. 非表示カテゴリの表示/非表示切替

**関連システム・外部連携**：AQL（Actual Query Language）によるデータベースクエリ、カテゴリグループ管理機能

**権限による制御**：予算ファイルへの読み取り権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 30 | レポートダッシュボード画面 | 補助機能 | カテゴリ別支出カードの表示 |
| 32 | キャッシュフローレポート画面 | 補助機能 | カテゴリごとの収支内訳表示 |
| 33 | 支出レポート画面 | 主機能 | カテゴリ別支出の詳細分析 |

## 機能種別

計算処理 / データ集計 / 可視化

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| categoryGroups | CategoryGroupEntity[] | Yes | カテゴリグループ一覧 | - |
| selectedCategories | CategoryEntity[] | No | 選択されたカテゴリ一覧 | デフォルト: 全カテゴリ |
| showHiddenCategories | boolean | No | 非表示カテゴリを含めるか | デフォルト: true |

### 入力データソース

- category_groupsテーブル（カテゴリグループ一覧）
- categoriesテーブル（カテゴリ一覧）
- transactionsテーブル（取引データ）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| selectedCategories | CategoryEntity[] | 選択状態のカテゴリ一覧 |
| filteredGroups | CategoryGroupEntity[] | フィルタ適用後のグループ一覧 |
| categoryTotals | Map<string, number> | カテゴリIDごとの合計金額 |

### 出力先

レポート画面のサイドバー（カテゴリセレクター）

## 処理フロー

### 処理シーケンス

```
1. カテゴリグループとカテゴリの取得
   └─ 階層構造でカテゴリデータを取得
2. 非表示カテゴリのフィルタリング
   └─ showHiddenCategoriesに応じて表示対象を決定
3. 選択状態の管理
   └─ 全選択/全解除/個別選択の状態管理
4. グループ単位での選択操作
   └─ グループ内全カテゴリの一括選択/解除
5. 選択状態の親コンポーネントへの通知
   └─ setSelectedCategoriesコールバックの呼び出し
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[categoryGroups取得]
    B --> C{showHiddenCategories?}
    C -->|Yes| D[全カテゴリ表示]
    C -->|No| E[hidden=false のみ表示]
    D --> F[選択状態の計算]
    E --> F
    F --> G{操作種別}
    G -->|全選択| H[selectAll適用]
    G -->|全解除| I[空配列設定]
    G -->|グループ選択| J[グループ内カテゴリ一括操作]
    G -->|個別選択| K[単一カテゴリ追加/削除]
    H --> L[setSelectedCategories呼び出し]
    I --> L
    J --> L
    K --> L
    L --> M[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 非表示カテゴリ除外 | hidden=trueのカテゴリは showHiddenCategories=false時に除外 | フィルタリング時 |
| BR-02 | グループ全選択 | グループチェックボックスで配下カテゴリを一括選択/解除 | グループ操作時 |
| BR-03 | 選択解除表示切替 | 未選択カテゴリを非表示にするオプション | uncheckedHidden=true時 |
| BR-04 | デフォルト全選択 | selectedCategoriesが未定義の場合は全カテゴリを選択状態 | 初期化時 |

### 計算ロジック

**グループ選択状態判定**:
```javascript
allCategoriesInGroupSelected = filteredGroup(categoryGroup).every(
  category => selectedCategories.some(selected => selected.id === category.id)
)
```

## データベース操作仕様

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| カテゴリグループ取得 | category_groups | SELECT | 全カテゴリグループを取得 |
| カテゴリ取得 | categories | SELECT | グループに属するカテゴリを取得 |

### テーブル別操作詳細

#### categories

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | id | - | カテゴリID |
| SELECT | name | - | カテゴリ名 |
| SELECT | hidden | フィルタ条件 | 非表示フラグ |
| SELECT | cat_group | グループID | 所属グループ |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | データなし | カテゴリが存在しない | 空のセレクターを表示 |

### リトライ仕様

特になし。

## トランザクション仕様

読み取り専用。データベースの更新は行わない。

## パフォーマンス要件

- カテゴリ数が多い場合でもスムーズに選択操作できるよう、useMemoでリスト計算を最適化

## セキュリティ考慮事項

特になし。

## 備考

- CategorySelectorコンポーネントはレポート機能のサイドバーで共通利用される
- カテゴリの表示/非表示切替は画面右上のトグルボタンで操作

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

カテゴリ関連の型定義を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | models.ts | `packages/loot-core/types/models/index.ts` | CategoryEntity, CategoryGroupEntity型定義 |

#### Step 2: UIコンポーネントを理解する

カテゴリセレクターの実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | CategorySelector.tsx | `packages/desktop-client/src/components/reports/CategorySelector.tsx` | カテゴリ選択UIの実装 |

**主要処理フロー**:
- **24-29行目**: `CategorySelectorProps` - コンポーネントのプロパティ定義
- **31-36行目**: コンポーネント初期化とデフォルト値
- **38-43行目**: `filteredGroup` - 非表示カテゴリのフィルタリング
- **45-48行目**: `selectAll` - 全選択用カテゴリ配列の構築
- **50-52行目**: 未定義時のデフォルト選択
- **54-57行目**: `selectedCategoryMap` - 選択状態のマップ化（パフォーマンス最適化）
- **59-65行目**: 全選択/全解除状態の判定
- **77-79行目**: 表示/非表示切替ボタン
- **122-141行目**: 全選択/全解除ボタン
- **156-211行目**: グループヘッダーとチェックボックス
- **221-263行目**: 個別カテゴリのチェックボックス

**読解のコツ**:
- `useMemo`は選択状態のID配列を効率的にマップ化
- `filteredGroup`は非表示カテゴリの表示/非表示をフィルタリング
- グループチェックボックスは配下全カテゴリの一括操作を行う

#### Step 3: 関連レポート画面を理解する

カテゴリセレクターを使用するレポート画面を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Spending.tsx | `packages/desktop-client/src/components/reports/reports/Spending.tsx` | 支出レポート画面での使用例 |
| 3-2 | CustomReport.tsx | `packages/desktop-client/src/components/reports/reports/CustomReport.tsx` | カスタムレポートでの使用例 |

### プログラム呼び出し階層図

```
CustomReport / Spending / etc.
    │
    └─ CategorySelector (CategorySelector.tsx:31)
           │
           ├─ filteredGroup() ───▶ 非表示カテゴリフィルタ
           │
           ├─ selectedCategoryMap (useMemo) ───▶ 選択状態マップ
           │
           ├─ GraphButton (全選択)
           │      └─ setSelectedCategories(selectAll)
           │
           ├─ GraphButton (全解除)
           │      └─ setSelectedCategories([])
           │
           ├─ Checkbox (グループ)
           │      └─ setSelectedCategories(グループ一括操作)
           │
           └─ Checkbox (個別カテゴリ)
                  └─ setSelectedCategories(追加/削除)
```

### データフロー図

```
[入力]                    [処理]                         [出力]

categoryGroups ────┐
                   │
selectedCategories ┼──▶ CategorySelector ──▶ フィルタリング
                   │          │                   │
showHiddenCategories          │                   │
                              ▼                   ▼
                        選択状態管理 ───▶ setSelectedCategories
                              │                   │
                              ▼                   ▼
                        チェックボックス     選択済みカテゴリ
                         レンダリング           配列
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| CategorySelector.tsx | `packages/desktop-client/src/components/reports/CategorySelector.tsx` | ソース | カテゴリ選択UIコンポーネント |
| GraphButton.tsx | `packages/desktop-client/src/components/reports/GraphButton.tsx` | ソース | グラフ操作ボタン |
| Spending.tsx | `packages/desktop-client/src/components/reports/reports/Spending.tsx` | ソース | 支出レポート画面 |
| CustomReport.tsx | `packages/desktop-client/src/components/reports/reports/CustomReport.tsx` | ソース | カスタムレポート画面 |
| spending-spreadsheet.ts | `packages/desktop-client/src/components/reports/spreadsheets/spending-spreadsheet.ts` | ソース | 支出データ取得 |
| forms.tsx | `packages/desktop-client/src/components/forms.tsx` | ソース | Checkboxコンポーネント |
