# 通知設計書 15-休暇申請関連通知

## 概要

本ドキュメントは、休暇申請の承認・却下・更新時に表示されるアプリ内通知の設計を記載する。

### 本通知の処理概要

本通知は、time-offプラグインにおける休暇申請（Leave）のライフサイクル全体を通じて、各種操作完了時にユーザーへフィードバックを提供するアプリ内通知である。

**業務上の目的・背景**：従業員の休暇申請に関する処理状態をリアルタイムで伝達し、人事・労務管理業務の円滑な運用を支援する。申請者と承認者の双方が操作結果を即座に確認でき、業務フローの透明性を確保する。

**通知の送信タイミング**：休暇申請の作成、編集、削除、カレンダーウィジェットでの作成・編集時、およびバリデーションエラー発生時に表示される。

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

**通知内容の概要**：操作種別（作成、更新、削除）と結果（成功、エラー）に応じたメッセージ。成功時は緑色、エラー時は赤色で表示される。

**期待されるアクション**：成功通知の場合は確認のみ。エラー通知の場合は、エラー内容を確認し、データを修正してから再試行する。

## 通知種別

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

## 送信仕様

### 基本情報

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

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

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

## 通知テンプレート

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

| 項目 | 内容 |
|-----|------|
| 表示位置 | 画面右上（Filamentデフォルト） |
| 表示色 | 成功：緑色（success）、エラー：赤色（danger） |
| 自動消去 | あり（数秒後） |
| 手動消去 | 可能 |

### 本文テンプレート

```
【休暇申請作成成功】
タイトル: "Time Off Created"
本文: "Time off request has been created successfully."

【休暇申請更新成功】
タイトル: "Time Off Updated"
本文: "Time off request has been updated successfully."

【休暇申請削除成功】
タイトル: "Time Off Deleted"
本文: "Time off request has been deleted successfully."

【カレンダーからの作成成功】
タイトル: "Time Off Created"
本文: "Time off has been created from the calendar."

【カレンダーからの編集成功】
タイトル: "Time Off Updated"
本文: "Time off has been updated from the calendar."

【期間重複エラー】
タイトル: "Overlap Detected"
本文: "The selected dates overlap with an existing time off request."

【割当なしエラー】
タイトル: "No Allocation"
本文: "You have no allocation for {leaveType}."

【残高不足エラー】
タイトル: "Insufficient Balance"
本文: "Requested {requestedDays} days but only {availableBalance} days available."
```

### 添付ファイル

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

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| title | 通知タイトル | 言語ファイル | Yes |
| body | 通知本文 | 言語ファイル | Yes |
| leaveType | 休暇タイプ名 | LeaveType->name | No（エラー時） |
| requestedDays | 申請日数 | 計算値 | No（エラー時） |
| availableBalance | 利用可能残高 | 計算値 | No（エラー時） |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 画面操作 | CreateTimeOff成功 | 作成処理完了 | 休暇申請新規作成 |
| 画面操作 | EditTimeOff成功 | 更新処理完了 | 休暇申請編集 |
| 画面操作 | DeleteTimeOff成功 | 削除処理完了 | 休暇申請削除 |
| 画面操作 | CalendarWidget Create成功 | 作成処理完了 | カレンダーから作成 |
| 画面操作 | CalendarWidget Edit成功 | 更新処理完了 | カレンダーから編集 |
| 画面操作 | 期間重複検出 | バリデーションエラー | 他の休暇と重複 |
| 画面操作 | 割当なし検出 | バリデーションエラー | 休暇タイプの割当がない |
| 画面操作 | 残高不足検出 | バリデーションエラー | 申請日数が残高を超過 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| バリデーションエラーなし | エラー系通知は該当条件発生時のみ |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[休暇申請操作開始] --> B[TimeOffHelper::mutateTimeOffData]
    B --> C{従業員存在?}
    C -->|No| D[従業員未設定エラー通知]
    C -->|Yes| E{期間重複?}
    E -->|Yes| F[重複エラー通知]
    E -->|No| G{割当あり?}
    G -->|No| H[割当なしエラー通知]
    G -->|Yes| I{残高十分?}
    I -->|No| J[残高不足エラー通知]
    I -->|Yes| K[CRUD処理実行]
    K --> L{処理成功?}
    L -->|Yes| M[成功通知表示]
    L -->|No| N[失敗通知表示]
    D --> O[action->cancel]
    F --> O
    H --> O
    J --> O
    M --> P[終了]
    N --> P
    O --> P
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| employees_employees | 従業員情報取得 | 申請者特定 |
| time_off_leaves | 既存休暇確認 | 重複チェック |
| time_off_leave_allocations | 割当残高確認 | 残高計算 |
| time_off_leave_types | 休暇タイプ情報 | 名称取得 |

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

#### time_off_leaves

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| employee_id | 重複チェック対象特定 | 申請者と同一 |
| request_date_from | 期間重複判定 | 申請期間と比較 |
| request_date_to | 期間重複判定 | 申請期間と比較 |
| number_of_days | 消化日数計算 | 承認済み休暇 |

#### time_off_leave_allocations

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| number_of_days | 割当日数取得 | 対象従業員・休暇タイプ |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| time_off_leaves | INSERT/UPDATE/DELETE | 休暇申請データ操作（通知とは別処理） |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 従業員未設定 | employee_id がnull | エラー通知表示、処理中断 |
| 期間重複 | 既存休暇と期間が重複 | エラー通知表示、処理中断 |
| 割当なし | totalAllocated <= 0 | エラー通知表示、処理中断 |
| 残高不足 | requestedDays > availableBalance | エラー通知表示、処理中断 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし（ユーザーがデータ修正後に再試行） |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

### レート制限

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

### 配信時間帯

特に制限なし（操作時に即時表示）

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

- 休暇情報は個人情報として適切に取り扱う
- 他従業員の休暇情報は通知に含めない
- 残高情報は本人のみに表示

## 備考

- time-offプラグインで使用
- TimeOffHelper traitにバリデーションロジックを集約
- CalendarWidget/OverviewCalendarWidgetでカレンダーUI連携
- 言語ファイルは `time-off::filament/clusters/` 配下に配置
- Management（管理者向け）とMyTime（従業員向け）で同一の通知パターン
- 関連ページ:
  - CreateTimeOff.php
  - EditTimeOff.php
  - ViewTimeOff.php
  - CalendarWidget.php
  - OverviewCalendarWidget.php
