# 帳票設計書 4-Custom Report（カスタムレポート）

## 概要

本ドキュメントは、Actual Budgetアプリケーションにおける「Custom Report（カスタムレポート）」の設計仕様を記述したものである。ユーザーが自由にカスタマイズ可能なレポート機能について詳細に解説する。

### 本帳票の処理概要

Custom Report（カスタムレポート）は、ユーザーが自由にカスタマイズ可能な多機能レポートである。カテゴリ、支払先、口座別のグループ化、様々なグラフ形式、豊富なフィルター条件の設定が可能で、作成したレポート設定を保存・読み込みできる。

**業務上の目的・背景**：定型のレポートでは対応できない多様な分析ニーズに応えるため、柔軟にカスタマイズ可能なレポート機能が必要である。本レポートは、ユーザー固有の分析視点（特定カテゴリの推移、支払先別の支出傾向等）に対応し、一度設定したレポート条件を保存して再利用できることで、継続的な分析を効率化する。

**帳票の利用シーン**：特定カテゴリの支出トレンド分析、支払先別の支出比較、口座別の残高推移確認、予算超過カテゴリの特定、カスタム期間での分析など、標準レポートでは対応できない分析場面で利用される。

**主要な出力内容**：
1. 様々な形式のグラフ（棒グラフ、線グラフ、円グラフ、面グラフ、テーブル）
2. グループ化されたデータの時系列推移
3. 凡例とサマリー情報
4. データラベルの表示/非表示

**帳票の出力タイミング**：ユーザーがレポート画面から「Custom Report」を選択した際、または保存済みのカスタムレポートを読み込んだ際にリアルタイムで生成される。

**帳票の利用者**：アプリケーションの全ユーザー（個人の家計管理者）

## 帳票種別

ユーザー定義可変レポート

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| R-004 | Custom Report | `/reports/custom` | レポートメニューから選択 |
| R-004-S | 保存済みレポート | `/reports/custom/:id` | 保存済みレポートを開く |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | HTML（画面表示）/ SVGグラフ |
| 表示形式 | インタラクティブなグラフ表示 |
| レスポンシブ対応 | 有（モバイル/デスクトップ） |
| データ更新 | リアルタイム（パラメータ変更時に再計算） |

### グラフ形式オプション

| グラフタイプ | 説明 |
|------------|------|
| BarGraph | 棒グラフ（縦） |
| StackedBarGraph | 積み上げ棒グラフ |
| LineGraph | 線グラフ |
| AreaGraph | 面グラフ |
| DonutGraph | ドーナツグラフ |
| TableGraph | テーブル形式 |

## 帳票レイアウト

### レイアウト概要

レポートは左側のサイドバー部、中央上部のトップバー部、中央のメインコンテンツ部の3つのセクションで構成される。

```
+------------------------------------------+
|              ページヘッダー                |
|  Custom Report: [レポート名]              |
+------------------------------------------+
|         |                                |
| サイド   | トップバー                       |
| バー     | [グラフ選択][凡例][サマリー][ラベル]|
|         +--------------------------------|
| 期間選択 |                                |
| モード   | フィルター条件表示               |
| グループ +--------------------------------|
| 間隔    | グラフ表示エリア                  |
| タイプ   |                                |
| 表示設定 |        [選択したグラフ]          |
| カテゴリ |                                |
| 選択    +--------------------------------|
|         | 凡例/サマリー (オプション)        |
+------------------------------------------+
```

### サイドバー部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | 期間選択 | 開始日・終了日の選択 | startDate, endDate | カレンダー |
| 2 | Date Mode | Static/Live | isDateStatic | トグル |
| 3 | Date Range | プリセット期間 | dateRange | ドロップダウン |
| 4 | Mode | total/time | mode | ドロップダウン |
| 5 | Split | Category/Payee/Account/Interval | groupBy | ドロップダウン |
| 6 | Interval | Daily/Weekly/Monthly/Yearly | interval | ドロップダウン |
| 7 | Balance Type | Expense/Income/Net/Debt/Asset | balanceType | ドロップダウン |
| 8 | Show empty | 空データの表示 | showEmpty | チェックボックス |
| 9 | カテゴリ選択 | 対象カテゴリ | selectedCategories | ツリー選択 |

### トップバー部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | グラフ選択 | グラフタイプ | graphType | アイコンボタン群 |
| 2 | Show Legend | 凡例表示切替 | viewLegend | チェックボックス |
| 3 | Show Summary | サマリー表示切替 | viewSummary | チェックボックス |
| 4 | Show Labels | ラベル表示切替 | viewLabels | チェックボックス |
| 5 | Save Report | レポート保存 | - | ボタン |
| 6 | Reset | リセット | - | ボタン |

### グラフ部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | メインビジュアル | 選択されたグラフ | data | 可変 |
| 2 | 合計表示 | balanceType別合計 | data[balanceTypeOp] | 通貨形式 |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| 期間（開始） | 集計開始日 | Yes |
| 期間（終了） | 集計終了日 | Yes |
| モード | total/time | Yes |
| グループ化 | Category/Payee/Account/Interval | Yes |
| バランスタイプ | Expense/Income/Net/Debt/Asset | Yes |
| カテゴリ | 対象カテゴリ | No |
| カスタムフィルター | ルール条件 | No |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | sortByで指定 | 可変（asc/desc） |

### 改ページ条件

該当なし（単一画面表示、グラフエリアはスクロール可能）

## データベース参照仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 結合条件 |
|-----------|------|---------|
| transactions | トランザクションデータ | - |
| categories | カテゴリマスタ | category.id |
| category_groups | カテゴリグループマスタ | category.group_id |
| payees | 支払先マスタ | payee.id |
| accounts | 口座マスタ | account.id |

### テーブル別参照項目詳細

#### transactions

| 参照項目（カラム名） | 帳票項目との対応 | 取得条件 | 備考 |
|-------------------|----------------|---------|------|
| date | 期間フィルター・グループ化 | date >= start AND date <= end | - |
| amount | 金額集計 | - | balanceTypeで正負判定 |
| category | カテゴリ別グループ化 | - | グループ化時 |
| payee | 支払先別グループ化 | - | グループ化時 |
| account | 口座別グループ化 | - | グループ化時 |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| totalDebts | SUM(amount) WHERE amount < 0 | なし | 支出合計 |
| totalAssets | SUM(amount) WHERE amount > 0 | なし | 収入合計 |
| totalTotals | SUM(amount) | なし | 純合計 |

### バランスタイプ対応

| balanceType | 対応する計算 | 説明 |
|-------------|-------------|------|
| Expense | totalDebts | 支出（負の値） |
| Income | totalAssets | 収入（正の値） |
| Net | totalTotals | 純額（収支差） |
| Debt | totalDebts | 負債 |
| Asset | totalAssets | 資産 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[レポート画面表示] --> B[セッションストレージ確認]
    B --> C{保存済みレポート?}
    C -->|Yes| D[保存設定を復元]
    C -->|No| E[デフォルト設定使用]
    D --> F[パラメータ設定]
    E --> F
    F --> G[createCustomSpreadsheet]
    F --> H[createGroupedSpreadsheet]
    G --> I[useReport 並列実行]
    H --> I
    I --> J[データ統合]
    J --> K[ChooseGraph]
    K --> L[グラフ描画]
    L --> M{パラメータ変更?}
    M -->|Yes| F
    M -->|No| N[表示完了]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| フィルター警告 | 無効なフィルター値 | This report is configured to use a non-existing filter value | フィルターを修正 |
| データなし | 条件に該当するデータなし | Loading表示継続 | 条件を緩和 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 数万件のトランザクション |
| 目標出力時間 | 5秒以内 |
| 並列処理 | 2つのスプレッドシートを並列実行 |
| キャッシュ | useMemo/sessionStorageによるキャッシュ |

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

- プライバシーフィルター（PrivacyFilter）による金額のマスキング機能
- ローカルデータストレージ（サーバーへのデータ送信なし）
- セッションストレージにレポート設定を一時保存

## 備考

- レポート設定はsessionStorageに保存され、セッション間で維持される
- 複雑なカテゴリ条件（複数のcategoryフィルター、contains/matches操作）は検出され、カテゴリ選択UIが無効化される
- disabledListにより、モードとグラフタイプの組み合わせで利用可能なオプションが制限される

---

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

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

### 推奨読解順序

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

まず、レポートで使用されるデータ型を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | models.ts | `loot-core/types/models` | CustomReportEntity, DataEntity, RuleConditionEntity型 |
| 1-2 | ReportOptions.ts | `packages/desktop-client/src/components/reports/ReportOptions.ts` | デフォルトレポート設定、オプション定義 |

**読解のコツ**: CustomReportEntityが保存可能な全設定を持つ。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | CustomReport.tsx | `packages/desktop-client/src/components/reports/reports/CustomReport.tsx` | メインコンポーネント（1013行） |

**主要処理フロー**:
1. **行120-129**: CustomReport関数 - レポートIDからデータ読み込み
2. **行135-175**: 状態初期化 - セッションストレージとの同期
3. **行243-263**: 各種設定状態の定義
4. **行443-475**: getGroupData - グループ化スプレッドシート
5. **行477-520**: getGraphData - カスタムスプレッドシート
6. **行521-524**: useReport並列実行
7. **行696-763**: onReportChange - レポート変更ハンドラー
8. **行959-977**: ChooseGraph - グラフ選択・描画

#### Step 3: スプレッドシート（データ集計ロジック）を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | custom-spreadsheet.ts | `packages/desktop-client/src/components/reports/spreadsheets/custom-spreadsheet.ts` | カスタムスプレッドシート |
| 3-2 | grouped-spreadsheet.ts | `packages/desktop-client/src/components/reports/spreadsheets/grouped-spreadsheet.ts` | グループ化スプレッドシート |

#### Step 4: UI部品を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | ReportSidebar.tsx | `packages/desktop-client/src/components/reports/ReportSidebar.tsx` | サイドバーUI |
| 4-2 | ReportTopbar.tsx | `packages/desktop-client/src/components/reports/ReportTopbar.tsx` | トップバーUI |
| 4-3 | ChooseGraph.tsx | `packages/desktop-client/src/components/reports/ChooseGraph.tsx` | グラフ選択・描画 |

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

```
CustomReport.tsx
    |
    +-- useCustomReport() --> 保存済みレポート読み込み
    |
    +-- CustomReportInner
            |
            +-- sessionStorage --> レポート設定の永続化
            |
            +-- useRuleConditionFilters() --> フィルター条件管理
            |
            +-- useSelectedCategories() --> カテゴリ選択管理
            |
            +-- createGroupedSpreadsheet() --> grouped-spreadsheet.ts
            |       |
            |       +-- グループ別データ集計
            |
            +-- createCustomSpreadsheet() --> custom-spreadsheet.ts
            |       |
            |       +-- カスタム条件でのデータ集計
            |
            +-- useReport('default', ...) --> 並列データ取得
            +-- useReport('grouped', ...)
            |
            +-- ReportSidebar --> 左サイドバー
            +-- ReportTopbar --> 上部ツールバー
            +-- ChooseGraph --> グラフ選択・描画
            +-- ReportLegend --> 凡例
            +-- ReportSummary --> サマリー
```

### データフロー図

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

トランザクション ────────+
                        |
categories ─────────────+
                        +──> createCustomSpreadsheet ──> graphData
payees ─────────────────+              |                    |
                        |              v                    v
accounts ───────────────+    createGroupedSpreadsheet   DataEntity
                        |              |                    |
期間/フィルター設定 ────+              v                    v
                        |         useReport            [ChooseGraph]
mode/groupBy/etc ───────+        (並列実行)                 |
                                      |                    v
sessionStorage ─────────────────> 設定復元/保存      選択されたグラフ
                                                    (Bar/Line/Pie等)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| CustomReport.tsx | `packages/desktop-client/src/components/reports/reports/CustomReport.tsx` | ソース | メインコンポーネント |
| custom-spreadsheet.ts | `packages/desktop-client/src/components/reports/spreadsheets/custom-spreadsheet.ts` | ソース | カスタムスプレッドシート |
| grouped-spreadsheet.ts | `packages/desktop-client/src/components/reports/spreadsheets/grouped-spreadsheet.ts` | ソース | グループ化スプレッドシート |
| ReportSidebar.tsx | `packages/desktop-client/src/components/reports/ReportSidebar.tsx` | ソース | サイドバーUI |
| ReportTopbar.tsx | `packages/desktop-client/src/components/reports/ReportTopbar.tsx` | ソース | トップバーUI |
| ChooseGraph.tsx | `packages/desktop-client/src/components/reports/ChooseGraph.tsx` | ソース | グラフ選択・描画 |
| ReportOptions.ts | `packages/desktop-client/src/components/reports/ReportOptions.ts` | ソース | オプション定義 |
| disabledList.ts | `packages/desktop-client/src/components/reports/disabledList.ts` | ソース | 無効オプション定義 |
| setSessionReport.ts | `packages/desktop-client/src/components/reports/setSessionReport.ts` | ソース | セッション保存 |
