# 通知設計書 14-警告通知

## 概要

本ドキュメントは、ユーザーへの警告メッセージを表示するアプリ内通知の設計を記載する。

### 本通知の処理概要

本通知は、操作自体は完了可能だが、ユーザーに注意を促したい状況や、前提条件の不備、データ不整合の可能性などを警告するためのアプリ内通知である。

**業務上の目的・背景**：ユーザーが気づかない可能性のある問題や、操作を続行する前に確認すべき事項を明示する。これにより、業務上のミスや意図しない結果を防止する。エラー（danger）ほど深刻ではないが、成功（success）とは異なり注意が必要な状況を示す。

**通知の送信タイミング**：操作実行中または実行前のバリデーション時点で、警告条件に該当した際に表示される。例えば、在庫操作で移動明細が未設定の場合や、休暇申請で重複期間がある場合などに発生する。

**通知の受信者**：操作を実行したログインユーザー自身。画面上にトースト形式で通知が表示される。

**通知内容の概要**：警告の内容と対処方法。オレンジ/黄色のwarning状態でハイライト表示される。

**期待されるアクション**：警告内容を確認し、必要に応じて入力データを修正してから操作を続行する。または警告を認識した上で操作を続行する。

## 通知種別

アプリ内通知（Filament Notification - トースト形式）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（画面即時表示） |
| 優先度 | 中 |
| リトライ | なし（UI通知のため） |

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

操作を実行した現在ログイン中のユーザーのブラウザ画面に直接表示される。

## 通知テンプレート

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

| 項目 | 内容 |
|-----|------|
| 表示位置 | 画面右上（Filamentデフォルト） |
| 表示色 | オレンジ/黄色（warning） |
| 自動消去 | あり（数秒後） |
| 手動消去 | 可能 |

### 本文テンプレート

```
タイトル: {警告種別}メッセージ
本文: {警告詳細と対処方法}

例1（在庫操作 - 移動明細なし）:
  タイトル: "Warning"
  本文: "Please add at least one move line before proceeding."

例2（休暇申請 - 従業員未設定）:
  タイトル: "Employee Not Found"
  本文: "Please select an employee before creating a time off request."

例3（在庫操作 - シリアル番号重複）:
  タイトル: "Serial Number Issue"
  本文: "Each serial tracked product must have exactly 1 quantity."
```

### 添付ファイル

| ファイル名 | 形式 | 条件 | 説明 |
|----------|------|------|------|
| なし | - | - | アプリ内通知のため添付ファイルなし |

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| title | 通知タイトル | 言語ファイル（各リソース固有） | Yes |
| body | 警告詳細メッセージ | 言語ファイル（各リソース固有） | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 画面操作 | 在庫操作のTodo/Validate実行 | 移動明細なし | moves->count() == 0 |
| 画面操作 | 在庫操作のValidate実行 | 明細行なし | lines->isEmpty() |
| 画面操作 | 在庫操作のValidate実行 | ロット番号未設定 | lot_id未設定でロット追跡商品 |
| 画面操作 | 在庫操作のValidate実行 | シリアル番号数量不正 | シリアル追跡で数量が1以外 |
| 画面操作 | 在庫操作のValidate実行 | 部分パッケージ移動 | パッケージの一部のみ移動 |
| 画面操作 | 休暇申請作成 | 従業員未設定 | employee_id未設定 |
| 画面操作 | 休暇申請作成 | 期間重複 | 既存休暇と期間が重複 |
| 画面操作 | 休暇申請作成 | 割当残高なし | 休暇タイプの割当がない |
| 画面操作 | 休暇申請作成 | 残高不足 | 申請日数が残高を超過 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| 条件クリア | 警告条件に該当しない場合は表示されない |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[ユーザー操作開始] --> B[バリデーションチェック]
    B --> C{警告条件該当?}
    C -->|No| D[通常処理続行]
    C -->|Yes| E[Notification::make]
    E --> F[->warning]
    F --> G[->title設定]
    G --> H[->body設定]
    H --> I[->send]
    I --> J[画面にトースト表示]
    J --> K{処理継続可能?}
    K -->|Yes| L[処理続行]
    K -->|No| M[処理中断]
    D --> N[終了]
    L --> N
    M --> N
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| inventories_moves | 移動明細の存在確認 | 在庫操作時 |
| inventories_move_lines | 明細行の存在確認 | 在庫操作時 |
| inventories_product_quantities | 在庫数量確認 | パッケージ移動時 |
| employees | 従業員存在確認 | 休暇申請時 |
| time_off_leaves | 重複確認 | 休暇申請時 |
| time_off_leave_allocations | 残高確認 | 休暇申請時 |

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

#### inventories_moves

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| id | 移動明細の存在確認 | operation_id = 対象操作ID |

#### time_off_leaves

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| request_date_from, request_date_to | 期間重複確認 | employee_id = 対象従業員ID |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| なし | - | 警告通知表示のみでDB更新なし |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 表示失敗 | JavaScriptエラー等 | ブラウザ開発者ツールでデバッグ |

### リトライ仕様

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

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | なし（警告発生回数に依存） |
| 1日あたり上限 | なし |

### 配信時間帯

特に制限なし（警告発生時に即時表示）

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

- XSS対策：メッセージは適切にエスケープされる
- 機密情報は通知に含めない
- 業務データの詳細は必要最小限に留める

## 備考

- Filament Notificationコンポーネントを使用
- warning()メソッドでオレンジ/黄色のスタイルが適用される
- danger()との違い：処理続行可能だが注意が必要な場合に使用
- 主な使用箇所：
  - inventories: TodoAction、ValidateAction
  - time-off: TimeOffHelper trait
- 言語ファイルは各プラグインの `resources/lang/{locale}/filament/` 配下に配置
