# 機能設計書 61-ゴール設定

## 概要

本ドキュメントは、Actualアプリケーションにおけるゴール設定（Budget Automation）機能の設計仕様を記載したものである。カテゴリごとの貯蓄目標や予算自動化を設定する機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：予算管理において、毎月の予算設定を手動で行うことは手間がかかる。ゴール設定機能は、カテゴリごとに予算の自動計算ルール（テンプレート）を設定することで、月次予算の自動計算・提案を可能にする。これにより、定期的な支出（家賃、光熱費）や貯蓄目標（旅行資金、緊急予備費）の計画的な管理が実現される。

**機能の利用シーン**：
- 毎月固定の予算を設定したい場合（家賃、保険料など）
- スケジュールに基づいた予算設定を行いたい場合（年払いの保険、四半期ごとの支払い）
- 収入の一定割合を自動的に貯蓄に回したい場合
- 過去の支出パターンに基づいて予算を設定したい場合

**主要な処理内容**：
1. 予算自動化テンプレートの作成（simple, week, schedule, percentage, historical）
2. テンプレートタイプに応じたパラメータ設定
3. テンプレートの保存・更新・削除
4. 月次予算計算時のテンプレート適用
5. 予算自動化の読み取り専用表示

**関連システム・外部連携**：
- スケジュール機能との連携（スケジュールベースの予算計算）
- カテゴリ機能との連携（カテゴリグループ、収入カテゴリ）

**権限による制御**：特別な権限制御はなく、予算ファイルにアクセス可能なユーザーが利用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 9 | 予算画面（デスクトップ） | 主画面 | カテゴリごとの貯蓄目標設定 |
| 10 | 予算画面（モバイル） | 参照画面 | モバイルでの予算自動化設定 |

## 機能種別

CRUD操作 / 計算処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| type | DisplayTemplateType | Yes | テンプレートタイプ（simple/week/schedule/percentage/historical） | 5種類のいずれか |
| monthly | number | No | 月間予算額（simpleタイプ用） | 0以上の数値 |
| amount | number | No | 金額（weekタイプ用） | 0以上の数値 |
| name | string | No | スケジュール名（scheduleタイプ用） | 有効なスケジュールID |
| percent | number | No | パーセンテージ（percentageタイプ用） | 0-100の数値 |
| category | string | No | カテゴリID（percentageタイプ用） | 有効なカテゴリID |
| previous | boolean | No | 前月の収入を使用するか | - |
| numMonths | number | No | 平均月数（historicalタイプ用） | 1以上の整数 |
| lookBack | number | No | 遡る月数（copyタイプ用） | 1以上の整数 |
| priority | number | Yes | 優先度 | デフォルト値1 |

### 入力データソース

- 画面入力（BudgetAutomationEditorコンポーネント経由）
- カテゴリ情報（useCategories Hook）
- スケジュール情報（schedules prop）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| template | Template | 設定された予算自動化テンプレート |
| displayType | DisplayTemplateType | 表示用テンプレートタイプ |

### 出力先

- ローカルストレージ（予算データベース）
- 画面表示（BudgetAutomationReadOnlyコンポーネント）

## 処理フロー

### 処理シーケンス

```
1. ユーザーがカテゴリの予算自動化ボタンをクリック
   └─ CategoryAutomationButtonコンポーネントがBudgetAutomationEditorを表示

2. テンプレートタイプを選択
   └─ setType actionがdispatchされ、reducerが状態を更新

3. テンプレート固有のパラメータを入力
   └─ updateTemplate actionでテンプレートを更新

4. 自動保存（useEffectAfterMount経由）
   └─ onSave callbackが呼び出され、テンプレートが保存される

5. 読み取り専用表示に切り替え
   └─ BudgetAutomationReadOnlyコンポーネントで設定内容を表示
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{テンプレート存在?}
    B -->|No| C[DEFAULT_TEMPLATE使用]
    B -->|Yes| D[既存テンプレートをロード]
    C --> E[BudgetAutomationEditor表示]
    D --> E
    E --> F{タイプ変更?}
    F -->|Yes| G[changeType関数実行]
    G --> H[新規テンプレート構造生成]
    H --> E
    F -->|No| I{パラメータ変更?}
    I -->|Yes| J[updateTemplate実行]
    J --> K[状態更新]
    K --> L[onSave callback]
    L --> E
    I -->|No| M{編集終了?}
    M -->|Yes| N[ReadOnly表示]
    M -->|No| E
    N --> O[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-61-001 | テンプレートタイプ互換性 | タイプ変更時は新しいテンプレート構造を生成 | タイプ選択時 |
| BR-61-002 | 優先度デフォルト値 | 優先度のデフォルト値は1 | 新規作成時 |
| BR-61-003 | average/copy相互変換 | historicalタイプ内でaverage/copyは相互に変換可能で、lookBackとnumMonthsの値を保持 | タイプ切替時 |
| BR-61-004 | スケジュール連携 | scheduleタイプはスケジュール機能と連携し、スケジュールの発生タイミングに基づいて予算を計算 | scheduleタイプ選択時 |

### 計算ロジック

1. **Simple（月間固定）**: 毎月指定された金額を予算として設定
2. **Week（週間固定）**: 週あたりの金額 x その月の週数 = 月間予算
3. **Schedule（スケジュール連動）**: スケジュールの次回発生日までの期間に応じて按分計算
4. **Percentage（割合指定）**: 収入カテゴリまたは予算可能額の指定割合を予算として設定
5. **Historical（履歴ベース）**: 過去N月の平均値または特定月からのコピー

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| テンプレート保存 | budget_templates | INSERT/UPDATE | 予算自動化テンプレートの保存 |
| テンプレート削除 | budget_templates | DELETE | 予算自動化テンプレートの削除 |
| テンプレート取得 | budget_templates | SELECT | カテゴリに紐づくテンプレートの取得 |

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

#### budget_templates

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT/UPDATE | directive | 'template' | 固定値 |
| INSERT/UPDATE | type | テンプレートタイプ | simple/periodic/schedule/percentage/average/copy |
| INSERT/UPDATE | priority | 優先度 | デフォルト1 |
| INSERT/UPDATE | その他フィールド | タイプ固有のパラメータ | タイプに応じて変動 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ERR-61-001 | テンプレートnull | テンプレートがnullの状態でgetInitialState呼び出し | Error: 'Template cannot be null' |
| ERR-61-002 | 未サポートタイプ | spend/by/remainder/limit/goalタイプの使用 | Error: '{type} is not yet supported' |
| ERR-61-003 | パースエラー | テンプレートパースエラー | Error: 'An error occurred while parsing the template' |
| ERR-61-004 | 不明タイプ | 未定義のテンプレートタイプ | Error: 'Unknown template type: {type}' |

### リトライ仕様

リトライは実装されていない。エラー発生時はユーザーに通知し、再入力を促す。

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

テンプレートの保存・更新は単一トランザクションで処理される。useEffectAfterMountによる自動保存のため、即時コミットされる。

## パフォーマンス要件

- テンプレート編集時のUI応答: 100ms以内
- テンプレート保存: 500ms以内

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

- 予算データはローカルファイルに保存され、E2E暗号化の対象となる
- クラウド同期時は暗号化されて転送される

## 備考

- 現在、spend/by/remainder/limit/goalタイプは未サポート
- テンプレートのバリデーションはフロントエンドで実施

---

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

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

### 推奨読解順序

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

まず、テンプレートの型定義とReducer状態を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | constants.ts | `packages/desktop-client/src/components/budget/goals/constants.ts` | DisplayTemplateType型とReducerState型の定義 |
| 1-2 | templates.ts | `loot-core/types/models/templates.ts` | 各テンプレートタイプ（SimpleTemplate, PeriodicTemplate等）の詳細型定義 |

**読解のコツ**: TypeScriptの判別共用体（discriminated union）パターンを理解すると、ReducerStateの構造が明確になる。displayTypeとtemplate.typeの対応関係に注目。

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

処理の起点となるコンポーネントを特定。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | BudgetAutomation.tsx | `packages/desktop-client/src/components/budget/goals/BudgetAutomation.tsx` | メインコンポーネント、useReducerによる状態管理 |

**主要処理フロー**:
1. **36-45行目**: コンポーネントProps定義とデフォルト値
2. **48-51行目**: useReducerによる状態初期化
3. **55-57行目**: useEffectAfterMountで変更検知し自動保存
4. **59-69行目**: カテゴリ名マップの生成（useMemo）
5. **78-86行目**: BudgetAutomationReadOnlyの表示
6. **87-95行目**: 編集モード時のBudgetAutomationEditor表示

#### Step 3: Reducer処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | reducer.ts | `packages/desktop-client/src/components/budget/goals/reducer.ts` | templateReducer関数、changeType関数、mapTemplateTypesForUpdate関数 |
| 3-2 | actions.ts | `packages/desktop-client/src/components/budget/goals/actions.ts` | Action型とaction creator関数 |

**主要処理フロー（reducer.ts）**:
- **8-54行目**: getInitialState関数 - テンプレートタイプに応じた初期状態生成
- **56-140行目**: changeType関数 - タイプ変更時の新規テンプレート構造生成
- **142-202行目**: mapTemplateTypesForUpdate関数 - average/copy間の相互変換を含むテンプレート更新
- **204-224行目**: templateReducer関数 - メインReducer処理

#### Step 4: エディターコンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | BudgetAutomationEditor.tsx | `packages/desktop-client/src/components/budget/goals/BudgetAutomationEditor.tsx` | タイプ選択UI、タイプ別エディターのswitchレンダリング |
| 4-2 | SimpleAutomation.tsx | `packages/desktop-client/src/components/budget/goals/editor/SimpleAutomation.tsx` | シンプルタイプのエディター |
| 4-3 | ScheduleAutomation.tsx | `packages/desktop-client/src/components/budget/goals/editor/ScheduleAutomation.tsx` | スケジュールタイプのエディター |

**主要処理フロー（BudgetAutomationEditor.tsx）**:
- **38-70行目**: displayTypeToDescription - 各タイプの説明文マッピング
- **82-122行目**: switch文によるタイプ別エディターコンポーネントの選択
- **141-150行目**: タイプ選択セレクトボックス

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

```
BudgetAutomation (メインコンポーネント)
    │
    ├─ useReducer(templateReducer, getInitialState)
    │      └─ reducer.ts: templateReducer
    │             ├─ getInitialState
    │             ├─ changeType
    │             └─ mapTemplateTypesForUpdate
    │
    ├─ useEffectAfterMount → onSave callback
    │
    ├─ BudgetAutomationReadOnly
    │      └─ 各ReadOnlyコンポーネント (SimpleAutomationReadOnly等)
    │
    └─ BudgetAutomationEditor
           ├─ SimpleAutomation
           ├─ WeekAutomation
           ├─ ScheduleAutomation
           ├─ PercentageAutomation
           │      └─ useBudgetAutomationCategories
           └─ HistoricalAutomation
```

### データフロー図

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

ユーザー操作 ─────────┐
(タイプ選択、        │
 パラメータ入力)     │
                     ▼
              ┌─────────────────┐
              │ dispatch(action)│
              └────────┬────────┘
                       ▼
              ┌─────────────────┐
              │ templateReducer │
              │ - set-type      │
              │ - set-template  │
              │ - update-template│
              └────────┬────────┘
                       ▼
              ┌─────────────────┐
              │ state更新       │
              │ {template,      │
              │  displayType}   │
              └────────┬────────┘
                       │
    ┌──────────────────┴──────────────────┐
    ▼                                      ▼
┌──────────────────┐              ┌──────────────────┐
│ 画面再レンダリング │              │ useEffectAfterMount│
│ BudgetAutomation  │              │ → onSave(template) │
│ Editor/ReadOnly   │              └──────────┬──────────┘
└──────────────────┘                         ▼
                                   ┌──────────────────┐
                                   │ DBに保存          │
                                   │ budget_templates │
                                   └──────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| BudgetAutomation.tsx | `packages/desktop-client/src/components/budget/goals/BudgetAutomation.tsx` | ソース | メインコンポーネント |
| BudgetAutomationEditor.tsx | `packages/desktop-client/src/components/budget/goals/BudgetAutomationEditor.tsx` | ソース | 編集UIコンポーネント |
| BudgetAutomationReadOnly.tsx | `packages/desktop-client/src/components/budget/goals/BudgetAutomationReadOnly.tsx` | ソース | 読み取り専用表示 |
| CategoryAutomationButton.tsx | `packages/desktop-client/src/components/budget/goals/CategoryAutomationButton.tsx` | ソース | カテゴリごとの自動化ボタン |
| reducer.ts | `packages/desktop-client/src/components/budget/goals/reducer.ts` | ソース | Reducer処理 |
| actions.ts | `packages/desktop-client/src/components/budget/goals/actions.ts` | ソース | Action定義 |
| constants.ts | `packages/desktop-client/src/components/budget/goals/constants.ts` | ソース | 型定義・定数 |
| useBudgetAutomationCategories.ts | `packages/desktop-client/src/components/budget/goals/useBudgetAutomationCategories.ts` | ソース | カテゴリ取得Hook |
| SimpleAutomation.tsx | `packages/desktop-client/src/components/budget/goals/editor/SimpleAutomation.tsx` | ソース | Simpleタイプエディター |
| WeekAutomation.tsx | `packages/desktop-client/src/components/budget/goals/editor/WeekAutomation.tsx` | ソース | Weekタイプエディター |
| ScheduleAutomation.tsx | `packages/desktop-client/src/components/budget/goals/editor/ScheduleAutomation.tsx` | ソース | Scheduleタイプエディター |
| PercentageAutomation.tsx | `packages/desktop-client/src/components/budget/goals/editor/PercentageAutomation.tsx` | ソース | Percentageタイプエディター |
| HistoricalAutomation.tsx | `packages/desktop-client/src/components/budget/goals/editor/HistoricalAutomation.tsx` | ソース | Historicalタイプエディター |
