# 通知設計書 26-ゴールテンプレートクリーンアップ結果

## 概要

本ドキュメントは、ゴールテンプレートのクリーンアップ処理結果をユーザーに表示する通知の仕様を定義します。

### 本通知の処理概要

ゴールテンプレートクリーンアップ結果通知は、予算の「source」（資金返却）カテゴリから「sink」（資金配分先）カテゴリへの自動資金移動処理の結果をユーザーにフィードバックする機能です。月末の予算整理を自動化します。

**業務上の目的・背景**：予算管理において、月末に未使用の予算を特定のカテゴリ（source）から回収し、別のカテゴリ（sink）に配分するワークフローがあります。例えば、「食費」カテゴリで余った金額を「貯蓄」カテゴリに自動的に移動させるような処理です。この通知により、ユーザーはクリーンアップ処理でどれだけの資金が移動したかを確認できます。

**通知の送信タイミング**：ユーザーが予算画面のメニューから「End of month cleanup」アクションを実行した際に、クリーンアップ処理が行われ、結果が通知として表示されます。

**通知の受信者**：クリーンアップアクションを実行したユーザー（現在の予算ファイルを操作中のユーザー）に対して通知が表示されます。

**通知内容の概要**：クリーンアップ処理の結果として、処理されたsourceとsinkの数、資金が不足している場合の警告、またはテンプレート解釈エラーの詳細が表示されます。

**期待されるアクション**：成功時は予算の再配分が正しく行われたことを確認し、警告がある場合は該当カテゴリの状態を確認することが期待されます。

## 通知種別

アプリ内通知（メッセージタイプ、警告タイプ、またはエラータイプ）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（ユーザーアクション駆動） |
| 優先度 | 中 |
| リトライ | なし |

### 送信先決定ロジック

クリーンアップアクションを実行したユーザーに対して結果を表示します。

## 通知テンプレート

### アプリ内通知

| 項目 | 内容 |
|-----|------|
| 通知タイプ | message（成功時）/ warning（警告時）/ error（エラー時） |
| 件名/タイトル | なし |
| 表示形式 | トースト通知 |

### 本文テンプレート

**成功時：**
```
Successfully returned funds from {source数} sources and funded {sink数} sinking funds.
```

**最新状態時：**
```
All categories were up to date.
```

**警告時：**
```
Global: Funds not available:

{カテゴリ名} does not have available funds.
{グループ名} has no matching sink categories.
...
```

**エラー時：**
```
{成功メッセージ} There were errors interpreting some templates:

{エラー詳細}
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| source数 | 資金返却元カテゴリの数 | 処理結果 | No |
| sink数 | 資金配分先カテゴリの数 | 処理結果 | No |
| pre | 警告/エラー詳細（改行区切り） | 処理結果 | No |
| message | メインメッセージ | 動的生成 | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 画面操作 | cleanup-goal-templateアクション | 常時 | 予算メニューからクリーンアップ実行時 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| なし | クリーンアップ実行時は常に結果を通知 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[ユーザーがEnd of month cleanupを実行] --> B[applyBudgetAction dispatch]
    B --> C[budget/cleanup-goal-template API呼び出し]
    C --> D[cleanupTemplate実行]
    D --> E[カテゴリテンプレート取得]
    E --> F[source/sinkグループ分類]
    F --> G[グループ間資金移動処理]
    G --> H[未充足カテゴリの充足]
    H --> I[sinkカテゴリへの配分]
    I --> J{結果判定}
    J -->|成功| K[成功メッセージ生成]
    J -->|警告| L[警告メッセージ生成]
    J -->|エラー| M[エラーメッセージ生成]
    K --> N[addNotification dispatch]
    L --> N
    M --> N
    N --> O[UIに通知表示]
    O --> P[終了]
```

## データベース参照・更新仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| notes | #cleanup テンプレート定義の取得 | LIKE '%#cleanup %' |
| v_categories | カテゴリ情報（ビュー） | tombstone = 0 |
| zero_budgets | 現在の予算値とcarryover設定 | 月次予算情報 |

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

#### notes

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| id | カテゴリIDとして使用 | - |
| note | クリーンアップテンプレート定義 | #cleanup で始まる行 |

#### zero_budgets

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| carryover | 繰越設定の確認 | month = 対象月, category = カテゴリID |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| zero_budgets | UPDATE | sourceからの資金回収、sinkへの配分 |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| テンプレート解釈エラー | cleanup構文が不正 | エラー詳細を通知に表示 |
| 資金不足 | sourceカテゴリに余剰資金がない | 警告として表示 |
| sink未設定 | グループにsinkカテゴリがない | 警告として表示 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし |
| 1日あたり上限 | 制限なし |

### 配信時間帯

時間帯制限なし

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

- テンプレート処理はサーバー側で安全に実行
- 予算金額の変更はUndoable（取り消し可能）

## 備考

- クリーンアップテンプレートは `#cleanup source`, `#cleanup sink {weight}` の形式
- グループ単位でのsource/sink処理もサポート（`#cleanup source {groupName}`）
- carryover（繰越）が有効なカテゴリは未充足処理をスキップ
- 処理はUndoable（取り消し可能）

---

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

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

### 推奨読解順序

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

Notification型とクリーンアップテンプレートの構造を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | cleanup-template.ts | `packages/loot-core/src/server/budget/cleanup-template.ts` | Notification型（8-14行目） |
| 1-2 | cleanup-template.pegjs | `packages/loot-core/src/server/budget/cleanup-template.pegjs` | クリーンアップ構文定義 |

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

クライアント側からの呼び出しフローを理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | budgetSlice.ts | `packages/desktop-client/src/budget/budgetSlice.ts` | cleanup-goal-templateケース（500-506行目） |

**主要処理フロー**:
1. **500行目**: `case 'cleanup-goal-template':` でアクション分岐
2. **501-505行目**: `send('budget/cleanup-goal-template', { month })` でAPIを呼び出し、結果を `addNotification` でディスパッチ

#### Step 3: サーバー側処理を理解する

クリーンアップ処理の実装を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | cleanup-template.ts | `packages/loot-core/src/server/budget/cleanup-template.ts` | cleanupTemplate関数（16-18行目） |
| 3-2 | cleanup-template.ts | `packages/loot-core/src/server/budget/cleanup-template.ts` | processCleanup関数（137-378行目）が中心処理 |
| 3-3 | cleanup-template.ts | `packages/loot-core/src/server/budget/cleanup-template.ts` | applyGroupCleanups関数（20-135行目）でグループ処理 |

**主要処理フロー**:
- **137行目**: `processCleanup` 関数開始
- **147行目**: `getCategoryTemplates()` でクリーンアップテンプレート取得
- **157-191行目**: source/sink/generalグループの分類
- **193-199行目**: `applyGroupCleanups` でグループ間の資金移動
- **201-297行目**: 個別カテゴリの処理（source回収、未充足充足）
- **305-329行目**: sinkカテゴリへの配分
- **331-378行目**: 結果通知の生成

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

```
applyBudgetAction (budgetSlice.ts:442)
    │
    ├─ case 'cleanup-goal-template' (budgetSlice.ts:500)
    │      │
    │      └─ send('budget/cleanup-goal-template', { month })
    │             │
    │             └─ app.method('budget/cleanup-goal-template') (app.ts:103)
    │                    │
    │                    └─ cleanupActions.cleanupTemplate (cleanup-template.ts:16)
    │                           │
    │                           └─ processCleanup (cleanup-template.ts:137)
    │                                  │
    │                                  ├─ getCategoryTemplates()
    │                                  ├─ グループ分類
    │                                  ├─ applyGroupCleanups()
    │                                  │      └─ setBudget() 複数回
    │                                  ├─ source処理
    │                                  │      └─ setBudget(), setGoal()
    │                                  ├─ 未充足充足処理
    │                                  │      └─ setBudget()
    │                                  └─ sink配分処理
    │                                         └─ setBudget()
    │
    └─ addNotification (budgetSlice.ts:501)
```

### データフロー図

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

ユーザーアクション ───▶ budget/cleanup-goal-template API ───▶ processCleanup
      │                                                              │
      │                                                              ▼
      │                                                    getCategoryTemplates
  month引数                                                          │
                                                                     ▼
                                                          source/sink分類
                                                                     │
                                          ┌──────────────────────────┴──────────────────────────┐
                                          ▼                          ▼                          ▼
                                   グループ処理              source処理                    sink処理
                                   (applyGroupCleanups)      (資金回収)                   (資金配分)
                                          │                          │                          │
                                          └──────────────────────────┴──────────────────────────┘
                                                                     │
                                                                     ▼
                                                          zero_budgets更新
                                                                     │
                                                                     ▼
                                                          Notification生成
                                                                     │
                                                                     ▼
                                                               UI表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| budgetSlice.ts | `packages/desktop-client/src/budget/budgetSlice.ts` | ソース | クライアント側のアクション処理 |
| cleanup-template.ts | `packages/loot-core/src/server/budget/cleanup-template.ts` | ソース | クリーンアップ処理のメイン実装 |
| cleanup-template.pegjs | `packages/loot-core/src/server/budget/cleanup-template.pegjs` | パーサー | クリーンアップ構文のPEG.js定義 |
| app.ts | `packages/loot-core/src/server/budget/app.ts` | ソース | 予算関連APIのルーティング |
| actions.ts | `packages/loot-core/src/server/budget/actions.ts` | ソース | setBudget, setGoalなどの基本操作 |
