# 通知設計書 22-予算テンプレートチェック結果

## 概要

本ドキュメントは、予算テンプレート（ゴールテンプレート）の構文チェック結果をユーザーに表示する通知の仕様を定義します。

### 本通知の処理概要

予算テンプレートチェック結果通知は、カテゴリに設定されたゴールテンプレート（#template や #goal 形式で記述された予算自動化ルール）の構文検証を実行し、その結果をユーザーにフィードバックする機能です。

**業務上の目的・背景**：ゴールテンプレートはカテゴリのノートに特定の構文で記述される予算自動化機能です。構文エラーがあるとテンプレートが正しく動作しないため、事前に検証することでユーザーが問題を発見・修正できるようにします。これにより、月次予算の自動設定が正常に機能することを保証します。

**通知の送信タイミング**：ユーザーが予算画面のメニューから「Check templates」アクションを実行した際に、テンプレートの構文チェックが行われ、結果が通知として表示されます。

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

**通知内容の概要**：テンプレートの検証結果として、すべてのテンプレートが正常な場合は成功メッセージ、構文エラーや存在しないスケジュール参照がある場合はエラー詳細が表示されます。

**期待されるアクション**：エラーがある場合、ユーザーは該当カテゴリのノートを確認し、テンプレート構文を修正することが期待されます。

## 通知種別

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

## 送信仕様

### 基本情報

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

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

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

## 通知テンプレート

### アプリ内通知

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

### 本文テンプレート

**成功時：**
```
All templates passed! 🎉
```

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

{カテゴリ名}: {エラー内容}
{カテゴリ名}: Schedule "{スケジュール名}" does not exist
...
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| pre | エラー詳細（改行区切り） | テンプレート解析結果 | No（エラー時のみ） |
| message | メインメッセージ | 固定値 | Yes |

## 送信トリガー・条件

### トリガー一覧

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

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| なし | チェック実行時は常に結果を通知 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[ユーザーがCheck templatesを実行] --> B[applyBudgetAction dispatch]
    B --> C[budget/check-templates API呼び出し]
    C --> D[runCheckTemplates実行]
    D --> E[カテゴリのテンプレートノート取得]
    E --> F[各テンプレートを解析]
    F --> G{エラーあり?}
    G -->|Yes| H[エラー詳細を含む通知生成]
    G -->|No| I[成功メッセージ通知生成]
    H --> J[addNotification dispatch]
    I --> J
    J --> K[UIに通知表示]
    K --> L[終了]
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| notes | カテゴリに紐づくテンプレートノートの取得 | #template/#goalで始まる行を抽出 |
| categories | カテゴリ情報の取得 | カテゴリ名をエラーメッセージに使用 |
| schedules | アクティブなスケジュール一覧取得 | scheduleテンプレートの検証用 |

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

#### notes

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| id | カテゴリIDとして使用 | - |
| note | テンプレート定義の取得 | #template または #goal を含む行 |

#### categories

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| id | カテゴリ識別 | - |
| name | エラーメッセージ表示用 | - |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| なし | - | チェック処理は参照のみ |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 構文エラー | テンプレート構文が不正 | エラー行を通知に表示 |
| スケジュール未存在 | 参照されたスケジュールが存在しない | スケジュール名を通知に表示 |
| 調整値範囲外 | adjustment percentageが-100%〜1000%の範囲外 | 具体的なエラーメッセージを表示 |

### リトライ仕様

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

## 配信設定

### レート制限

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

### 配信時間帯

時間帯制限なし

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

- テンプレート構文のパースはサーバー側で安全に実行
- ユーザー入力（テンプレート内容）はサニタイズして表示

## 備考

- エラー時は `sticky: true` が設定され、ユーザーが明示的に閉じるまで表示され続ける
- 成功時のみ絵文字（🎉）が表示される
- テンプレート構文はPEG.js（goal-template.pegjs）でパースされる

---

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

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

### 推奨読解順序

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

テンプレートの型定義とNotification型を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | templates.ts | `packages/loot-core/src/types/models/templates.ts` | Template型の定義を確認 |
| 1-2 | template-notes.ts | `packages/loot-core/src/server/budget/template-notes.ts` | Notification型の定義（12-17行目） |

**読解のコツ**: Template型は複数の種類（simple, schedule, average等）があり、それぞれ異なるプロパティを持ちます。

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | budgetSlice.ts | `packages/desktop-client/src/budget/budgetSlice.ts` | applyBudgetAction関数（442行目〜）でcheck-templatesケース（468-474行目）を確認 |

**主要処理フロー**:
1. **468行目**: `case 'check-templates':` でアクション分岐
2. **469-473行目**: `send('budget/check-templates')` でサーバーAPIを呼び出し、結果を `addNotification` でディスパッチ

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

テンプレートチェックの実装を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | goal-template.ts | `packages/loot-core/src/server/budget/goal-template.ts` | runCheckTemplates関数（114-116行目）がエントリー |
| 3-2 | template-notes.ts | `packages/loot-core/src/server/budget/template-notes.ts` | checkTemplateNotes関数（36-72行目）で実際の検証処理 |

**主要処理フロー**:
- **36行目**: `checkTemplateNotes` 関数開始
- **37行目**: `getCategoriesWithTemplates` でテンプレートを持つカテゴリを取得
- **38行目**: `getActiveSchedules` でアクティブなスケジュールを取得
- **42-57行目**: 各テンプレートをループしてエラーをチェック
- **60-71行目**: エラーの有無に応じて適切な通知オブジェクトを返却

#### Step 4: APIルーティングを理解する

サーバー側のAPIハンドラー登録を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | app.ts | `packages/loot-core/src/server/budget/app.ts` | budget/check-templatesの登録（83-86行目） |

**主要処理フロー**:
- **83-86行目**: `app.method('budget/check-templates', mutator(undoable(goalActions.runCheckTemplates)))` でAPI登録

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

```
applyBudgetAction (budgetSlice.ts:442)
    │
    ├─ case 'check-templates' (budgetSlice.ts:468)
    │      │
    │      └─ send('budget/check-templates') (budgetSlice.ts:471)
    │             │
    │             └─ app.method('budget/check-templates') (app.ts:83)
    │                    │
    │                    └─ goalActions.runCheckTemplates (goal-template.ts:114)
    │                           │
    │                           └─ checkTemplateNotes (template-notes.ts:36)
    │                                  │
    │                                  ├─ getCategoriesWithTemplates (template-notes.ts:74)
    │                                  │      └─ parse() - PEG.jsパーサー
    │                                  │
    │                                  └─ getActiveSchedules (statements.ts)
    │
    └─ addNotification (budgetSlice.ts:469)
```

### データフロー図

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

ユーザーアクション ───▶ budget/check-templates API ───▶ checkTemplateNotes
                                                              │
                                                              ▼
                                                   カテゴリのノート取得
                                                              │
                                                              ▼
                                                   テンプレート構文解析
                                                              │
                                                              ▼
                                                   スケジュール存在確認
                                                              │
                                                              ▼
                                                   Notification生成
                                                              │
                                                              ▼
                                                   addNotification
                                                              │
                                                              ▼
                                                   UI表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| budgetSlice.ts | `packages/desktop-client/src/budget/budgetSlice.ts` | ソース | クライアント側のアクション処理 |
| goal-template.ts | `packages/loot-core/src/server/budget/goal-template.ts` | ソース | ゴールテンプレート処理のエントリー |
| template-notes.ts | `packages/loot-core/src/server/budget/template-notes.ts` | ソース | テンプレートノートの解析・検証 |
| app.ts | `packages/loot-core/src/server/budget/app.ts` | ソース | 予算関連APIのルーティング |
| goal-template.pegjs | `packages/loot-core/src/server/budget/goal-template.pegjs` | パーサー | テンプレート構文のPEG.js定義 |
| statements.ts | `packages/loot-core/src/server/budget/statements.ts` | ソース | データベースクエリ関数 |
| notificationsSlice.ts | `packages/desktop-client/src/notifications/notificationsSlice.ts` | ソース | 通知の状態管理 |
