# 通知設計書 39-フォーミュラルールエラー

## 概要

本ドキュメントは、Actual Budget アプリケーションにおける「フォーミュラルールエラー」通知の設計仕様を記述する。この通知は、取引にルールを適用する際に、ルール内の数式（フォーミュラ）にエラーがある場合に表示される。

### 本通知の処理概要

**業務上の目的・背景**：Actual Budget の高度な機能として、ルールアクションで数式を使用できる。例えば、取引金額に基づいて動的にカテゴリを設定したり、計算結果を使用することができる。しかし、数式の構文エラーや評価エラーが発生した場合、ユーザーにその問題を明確に通知し、ルールの修正を促す必要がある。

**通知の送信タイミング**：取引に対してルールを適用する際（`rules-run` API 呼び出し時）に、ルール内の数式でエラーが発生した場合に表示される。トランザクションリスト画面で取引を編集・追加する際にルールが自動適用されるタイミングで発生しうる。

**通知の受信者**：取引を編集・追加しているユーザー。

**通知内容の概要**：「Formula errors in rules:」というプレフィックスと共に、発生したエラーメッセージが改行区切りで表示される。この通知は sticky として設定され、ユーザーが明示的に閉じるまで表示され続ける。

**期待されるアクション**：ユーザーはエラー内容を確認し、問題のあるルールの数式を修正する。

## 通知種別

アプリ内通知（トースト通知 - エラータイプ）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（ルール適用結果受信時） |
| 優先度 | 高 |
| リトライ | 無 |

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

- `rules-run` API の応答で `_ruleErrors` 配列が存在し、要素がある場合に表示
- 操作を実行したユーザーのローカル画面に表示

## 通知テンプレート

### アプリ内通知の場合

| 項目 | 内容 |
|-----|------|
| 通知タイプ | `error` |
| 表示位置 | 画面右下（固定位置） |
| sticky | `true`（自動消去されない） |

### 本文テンプレート

```
Message: Formula errors in rules:
{error1}
{error2}
...
```

エラーメッセージは改行（`\n`）で区切られて表示される。

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| type | 通知タイプ | 固定値 `error` | Yes |
| message | エラーメッセージ | `_ruleErrors` 配列を改行で結合 | Yes |
| sticky | 自動消去無効フラグ | 固定値 `true` | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| API レスポンス | rules-run | afterRules._ruleErrors が存在し非空 | TransactionList.tsx で検知 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| `_ruleErrors` が空または存在しない | エラーがない場合は通知しない |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[取引編集/追加] --> B[onApplyRules 呼び出し]
    B --> C[rules-run API 呼び出し]
    C --> D{afterRules._ruleErrors が存在?}
    D -->|No| E[通常処理継続]
    D -->|Yes| F{_ruleErrors.length > 0?}
    F -->|No| E
    F -->|Yes| G[addNotification dispatch]
    G --> H[sticky エラー通知を表示]
    H --> I[通常処理継続]
    E --> J[ルール適用結果を返す]
    I --> J
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| rules | ルール情報 | 数式を含むアクションの取得 |

### 処理の詳細

サーバー側でルールを実行する際、数式アクションの評価でエラーが発生すると、エラーメッセージが `_ruleErrors` 配列に追加されてクライアントに返される。

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 数式構文エラー | 数式の構文が不正 | sticky 通知でエラーを表示、ルール修正を促す |
| 数式評価エラー | 数式の評価時にエラー発生 | sticky 通知でエラーを表示、ルール修正を促す |

### リトライ仕様

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

## 配信設定

### レート制限

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

### 配信時間帯

制限なし（エラー発生時に即時表示）

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

- エラーメッセージにはルールの内部実装詳細が含まれる可能性があるが、ユーザー自身が作成したルールに関するものであり、問題ない
- sticky 通知のため、ユーザーが明示的に閉じるまで表示され続ける

## 備考

- この通知は sticky として設定され、自動消去されない
- 複数のエラーがある場合は改行で区切って表示される
- フォーミュラ機能は実験的機能として提供されている可能性がある
- No.40「ルール適用失敗」とは異なり、こちらは数式固有のエラーを扱う

---

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

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

### 推奨読解順序

#### Step 1: ルール適用処理を理解する

トランザクションリストでのルール適用処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | TransactionList.tsx | `packages/desktop-client/src/components/transactions/TransactionList.tsx` | onApplyRules 関数（507-561行目） |

**主要処理フロー**:
1. **512行目**: `rules-run` API を呼び出し
2. **515行目**: `afterRules._ruleErrors` の存在チェック
3. **516-524行目**: エラーがある場合、`addNotification` で sticky エラー通知を dispatch
4. **520行目**: エラーメッセージを改行で結合

#### Step 2: サーバー側のルール実行を理解する

サーバー側でのルール実行と数式評価を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | transaction-rules.ts | `packages/loot-core/src/server/transactions/transaction-rules.ts` | runRules 関数（314-369行目） |
| 2-2 | action.ts | `packages/loot-core/src/server/rules/action.ts` | 数式アクションの実行 |

**読解のコツ**: ルール実行中にエラーが発生した場合、どのように `_ruleErrors` 配列に追加されるかを追う。

#### Step 3: フォーミュラ機能の詳細を理解する

数式機能の実装詳細を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | formula-action.test.ts | `packages/loot-core/src/server/rules/formula-action.test.ts` | 数式アクションのテストケース |

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

```
TransactionList.tsx / TransactionsTable.tsx
    │
    ├─ onApplyRules (useCallback)
    │      │
    │      └─ send('rules-run', { transaction })
    │             │
    │             └─ server: runRules(transaction)
    │                    │
    │                    ├─ ルール評価
    │                    │      │
    │                    │      └─ 数式アクション実行
    │                    │             │
    │                    │             └─ (エラー発生)
    │                    │                    └─ _ruleErrors に追加
    │                    │
    │                    └─ return { ...transaction, _ruleErrors }
    │
    ├─ (afterRules._ruleErrors が存在)
    │      │
    │      └─ dispatch(addNotification({
    │             type: 'error',
    │             message: `Formula errors in rules:\n${errors.join('\n')}`,
    │             sticky: true
    │         }))
    │
    └─ return newTransaction
```

### データフロー図

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

取引データ ──────────────────▶ rules-run API ────────────────▶ ルール適用結果
                                   │
                                   ├─▶ 数式アクション評価
                                   │      │
                                   │      ├─▶ (成功) → 結果を適用
                                   │      │
                                   │      └─▶ (エラー) → _ruleErrors に追加
                                   │
                                   └─▶ { transaction, _ruleErrors }

_ruleErrors ────────────────▶ onApplyRules ────────────────▶ sticky エラー通知
                                   │
                                   └─▶ エラーメッセージを改行で結合
                                          │
                                          └─▶ addNotification dispatch
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| TransactionList.tsx | `packages/desktop-client/src/components/transactions/TransactionList.tsx` | ソース | 取引リスト、ルール適用処理 |
| transaction-rules.ts | `packages/loot-core/src/server/transactions/transaction-rules.ts` | ソース | サーバー側ルール実行 |
| action.ts | `packages/loot-core/src/server/rules/action.ts` | ソース | ルールアクション実行（数式含む） |
| notificationsSlice.ts | `packages/desktop-client/src/notifications/notificationsSlice.ts` | ソース | 通知の Redux slice 定義 |
| Notifications.tsx | `packages/desktop-client/src/components/Notifications.tsx` | ソース | 通知表示コンポーネント |
