# 通知設計書 25-単一カテゴリテンプレート適用結果

## 概要

本ドキュメントは、特定のカテゴリに対してゴールテンプレートを適用した結果をユーザーに表示する通知の仕様を定義します。

### 本通知の処理概要

単一カテゴリテンプレート適用結果通知は、ユーザーが選択した特定のカテゴリに対してのみゴールテンプレートを適用し、その処理結果をフィードバックする機能です。全カテゴリへの一括適用ではなく、個別カテゴリへの適用を行います。

**業務上の目的・背景**：予算管理において、特定のカテゴリのみテンプレートを再適用したい場合があります。例えば、そのカテゴリのテンプレートを修正した直後や、手動で変更した予算をテンプレートの値に戻したい場合です。この通知により、ユーザーは個別カテゴリへの適用結果を即座に確認できます。

**通知の送信タイミング**：ユーザーが特定カテゴリの予算メニューから「Apply budget template」を実行した際に、そのカテゴリへのテンプレート適用処理が行われ、結果が通知として表示されます。

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

**通知内容の概要**：テンプレートの適用結果として、適用されたカテゴリ数（通常は1）、既に最新の状態である場合のメッセージ、またはテンプレート解釈エラーの詳細が表示されます。

**期待されるアクション**：成功時は予算が正しく設定されたことを確認し、エラーがある場合は該当カテゴリのテンプレートを修正することが期待されます。

## 通知種別

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

## 送信仕様

### 基本情報

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

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

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

## 通知テンプレート

### アプリ内通知

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

### 本文テンプレート

**成功時（適用あり）：**
```
Successfully applied templates to {カテゴリ数} categories
```

**成功時（適用なし）：**
```
Everything is up to date
```

**エラー時：**
```
There were errors interpreting some templates:

{カテゴリ名}: {エラー内容}
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| カテゴリ数 | 適用されたカテゴリの数（通常1） | 処理結果 | No |
| pre | エラー詳細（改行区切り） | テンプレート解析結果 | No（エラー時のみ） |
| message | メインメッセージ | 固定値/動的生成 | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 画面操作 | apply-single-category-templateアクション | 常時 | カテゴリメニューからテンプレート適用実行時 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| なし | 適用実行時は常に結果を通知 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[ユーザーがカテゴリメニューからApply templateを実行] --> B[applyBudgetAction dispatch]
    B --> C[budget/apply-single-template API呼び出し]
    C --> D[applySingleCategoryTemplate実行]
    D --> E[対象カテゴリ情報取得]
    E --> F[テンプレートノートを保存]
    F --> G[カテゴリテンプレート取得]
    G --> H[processTemplate実行 force=true]
    H --> I{エラーあり?}
    I -->|Yes| J[エラー詳細を含む通知生成]
    I -->|No| K{適用あり?}
    K -->|Yes| L[成功メッセージ通知生成]
    K -->|No| M[最新状態メッセージ通知生成]
    J --> N[addNotification dispatch]
    L --> N
    M --> N
    N --> O[UIに通知表示]
    O --> P[終了]
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| categories | 対象カテゴリ情報とテンプレート定義の取得 | 指定されたカテゴリIDでフィルタ |
| zero_budgets / reflect_budgets | 現在の予算値 | 上書き前の値参照 |

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

#### categories

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| id | カテゴリ識別 | 引数で指定されたID |
| name | エラーメッセージ表示用 | - |
| goal_def | テンプレート定義JSON | - |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| zero_budgets | UPDATE | 指定カテゴリの予算金額を設定 |
| reflect_budgets | UPDATE | Reflect予算の場合の予算金額設定 |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| テンプレート解釈エラー | CategoryTemplateContext初期化失敗 | エラー詳細を通知に表示 |
| 構文エラー | テンプレート構文が不正 | エラー行を通知に表示 |
| テンプレート未設定 | カテゴリにテンプレートがない | 「Everything is up to date」を表示 |

### リトライ仕様

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

## 配信設定

### レート制限

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

### 配信時間帯

時間帯制限なし

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

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

## 備考

- 単一カテゴリに対する処理であるため、処理は高速
- force=trueで呼び出されるため、既存の予算も上書きされる
- 処理はUndoable（取り消し可能）
- カテゴリにテンプレートが設定されていない場合は何も適用されない

---

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

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

### 推奨読解順序

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

Notification型とカテゴリ関連の型を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | goal-template.ts | `packages/loot-core/src/server/budget/goal-template.ts` | Notification型（17-23行目） |
| 1-2 | models/index.ts | `packages/loot-core/src/types/models/index.ts` | CategoryEntity型の定義 |

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | budgetSlice.ts | `packages/desktop-client/src/budget/budgetSlice.ts` | apply-single-category-templateケース（490-499行目） |

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

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

単一カテゴリテンプレート適用の実装を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | goal-template.ts | `packages/loot-core/src/server/budget/goal-template.ts` | applySingleCategoryTemplate関数（93-112行目） |

**主要処理フロー**:
- **93行目**: `applySingleCategoryTemplate` 関数開始
- **100-102行目**: AQL queryで対象カテゴリ情報を取得
- **103行目**: `storeNoteTemplates()` でノートからテンプレートを保存
- **104行目**: `getTemplates(c => c.id === category)` で対象カテゴリのテンプレートのみ取得
- **105-110行目**: `processTemplate(month, true, categoryTemplates, categoryData)` で適用（force=true）

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

```
applyBudgetAction (budgetSlice.ts:442)
    │
    ├─ case 'apply-single-category-template' (budgetSlice.ts:490)
    │      │
    │      └─ send('budget/apply-single-template', { month, category })
    │             │
    │             └─ app.method('budget/apply-single-template') (app.ts:99)
    │                    │
    │                    └─ goalActions.applySingleCategoryTemplate (goal-template.ts:93)
    │                           │
    │                           ├─ aqlQuery - 対象カテゴリ取得
    │                           ├─ storeNoteTemplates()
    │                           ├─ getTemplates(c => c.id === category)
    │                           └─ processTemplate(month, true, categoryTemplates, categoryData)
    │
    └─ addNotification (budgetSlice.ts:491)
```

### データフロー図

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

ユーザーアクション ───▶ budget/apply-single-template API ───▶ applySingleCategoryTemplate
      │                                                              │
      │                                                              ▼
      │                                                    カテゴリ情報取得
  month引数                                                (AQL query)
  category引数                                                       │
                                                                     ▼
                                                          getTemplates
                                                          (対象カテゴリのみ)
                                                                     │
                                                                     ▼
                                                          processTemplate
                                                          (force=true)
                                                                     │
                                                                     ▼
                                                          Notification生成
                                                                     │
                                                                     ▼
                                                               UI表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| budgetSlice.ts | `packages/desktop-client/src/budget/budgetSlice.ts` | ソース | クライアント側のアクション処理 |
| goal-template.ts | `packages/loot-core/src/server/budget/goal-template.ts` | ソース | 単一カテゴリテンプレート適用のメイン処理 |
| app.ts | `packages/loot-core/src/server/budget/app.ts` | ソース | 予算関連APIのルーティング |
| EnvelopeBudgetMenuModal.tsx | `packages/desktop-client/src/components/modals/EnvelopeBudgetMenuModal.tsx` | ソース | 予算メニューUI（モバイル） |
| BudgetMenu.tsx | `packages/desktop-client/src/components/budget/envelope/BudgetMenu.tsx` | ソース | 予算メニューUI（デスクトップ） |
