# 機能設計書 44-通知設定管理

## 概要

本ドキュメントは、InvenTreeシステムにおける通知設定管理機能の設計仕様を定義する。この機能は、システム通知の配信方法（メール、アプリ内通知等）やタイミングの設定を管理する。

### 本機能の処理概要

**業務上の目的・背景**：
在庫管理システムでは、在庫不足アラート、発注完了通知、製造指示のステータス変更など、様々なイベントをユーザーに通知する必要がある。本機能は、通知の配信チャネル（メール、Webプッシュ、アプリ内通知等）の設定、通知頻度の制御、通知対象ユーザーの管理を行い、適切なタイミングで適切な人に情報を届ける基盤を提供する。

**機能の利用シーン**：
- システム管理者がメール通知の有効/無効を設定する
- ユーザーが自分の通知設定をカスタマイズする
- 通知プラグインの有効化・設定変更
- 重複通知を防ぐための間隔設定

**主要な処理内容**：
1. グローバル通知設定の管理（ENABLE_NOTIFICATIONS_INTERFACE等）
2. 通知配信プラグインの管理（NotificationMixin）
3. NotificationEntryによる通知重複制御
4. ユーザー別の通知設定管理

**関連システム・外部連携**：
- プラグインシステム（NotificationMixin）
- メール送信システム
- Webhookプラグイン
- 外部通知サービス（Slack、Teams等）

**権限による制御**：
- グローバル設定の変更はスタッフ権限が必要
- ユーザー設定は自分自身の設定のみ変更可能

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 34 | 管理センター画面 | 主機能 | グローバル通知設定管理 |
| 35 | システム設定画面 | 主機能 | システムレベル通知設定 |
| 36 | ユーザー設定画面 | 主機能 | ユーザー別通知設定 |

## 機能種別

設定管理 / CRUD操作

## 入力仕様

### 入力パラメータ（グローバル設定）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ENABLE_NOTIFICATIONS_INTERFACE | boolean | No | 通知インターフェースの有効化 | |
| NOTIFICATION_CHECK_INTERVAL | integer | No | 通知チェック間隔（秒） | 0以上 |

### 入力パラメータ（ユーザー設定）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| NOTIFICATION_SEND_EMAILS | boolean | No | メール通知の有効化 | |

### 入力データソース

- 管理画面のフォーム入力
- ユーザー設定画面
- APIリクエスト

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| key | string | 設定キー |
| value | string | 設定値 |
| name | string | 設定名 |
| description | string | 設定の説明 |

### 出力先

- APIレスポンス（JSON形式）
- 設定画面表示

## 処理フロー

### 処理シーケンス

```
1. 設定変更リクエストの受信
   └─ InvenTreeSetting.set_setting() または UserSetting.set_setting()
2. 権限チェック
   └─ スタッフ権限またはユーザー本人
3. バリデーション実行
   └─ 設定キーと値の検証
4. データベースへの保存
   └─ common_inventreesetting または users_usersetting
5. キャッシュの更新
   └─ 設定値のキャッシュを無効化
```

### フローチャート

```mermaid
flowchart TD
    A[設定変更リクエスト] --> B{設定タイプ判定}
    B -->|グローバル| C[スタッフ権限チェック]
    B -->|ユーザー| D[ユーザー本人チェック]
    C --> E{権限OK?}
    D --> E
    E -->|No| F[権限エラー]
    E -->|Yes| G[バリデーション]
    G --> H{検証OK?}
    H -->|No| I[バリデーションエラー]
    H -->|Yes| J[DB保存]
    J --> K[キャッシュ更新]
    K --> L[レスポンス返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-44-01 | 通知重複制御 | NotificationEntryで過去24時間以内の同一通知を抑制 | 通知トリガー時 |
| BR-44-02 | キャッシュ同期 | 設定変更時はキャッシュを更新 | 全ての設定変更 |
| BR-44-03 | デフォルト値適用 | 未設定の項目はSETTINGS定義のデフォルト値を使用 | 設定取得時 |
| BR-44-04 | ユーザー設定スコープ | ユーザー設定はそのユーザーのみに適用 | ユーザー設定変更時 |

### 計算ロジック

通知重複チェック：
```python
def check_recent(key: str, uid: int, delta: timedelta):
    since = current_date() - delta
    return NotificationEntry.objects.filter(
        key=key, uid=uid, updated__gte=since
    ).exists()
```

## データベース操作仕様

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| グローバル設定取得 | common_inventreesetting | SELECT | 設定値の取得 |
| グローバル設定更新 | common_inventreesetting | INSERT/UPDATE | 設定値の保存 |
| ユーザー設定取得 | users_usersetting | SELECT | ユーザー設定の取得 |
| ユーザー設定更新 | users_usersetting | INSERT/UPDATE | ユーザー設定の保存 |
| 通知エントリ確認 | common_notificationentry | SELECT | 重複チェック |
| 通知エントリ更新 | common_notificationentry | INSERT/UPDATE | 通知履歴記録 |

### テーブル別操作詳細

#### common_notificationentry

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | key, uid, updated | key=通知キー, uid=対象ID | 重複チェック |
| INSERT/UPDATE | key, uid, updated | 通知実行時に更新 | unique_together制約 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 400 | ValidationError | 無効な設定値 | 正しい設定値を指定 |
| 403 | PermissionDenied | 権限不足 | 適切な権限を取得 |
| 404 | NotFound | 設定キーが存在しない | 正しい設定キーを指定 |

### リトライ仕様

設定変更は冪等であり、再試行が可能。

## トランザクション仕様

設定の保存は単一トランザクションで実行される。

## パフォーマンス要件

- 設定取得：50ms以内（キャッシュヒット時）
- 設定更新：200ms以内

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

- グローバル設定の変更はスタッフ権限が必要
- ユーザー設定は認証済みユーザーのみアクセス可能
- 設定値にはパスワード等の機密情報を含めない

## 備考

- 通知設定はプラグインシステムと密接に連携
- NotificationMixinを持つプラグインが配信を担当

---

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

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

### 推奨読解順序

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

通知関連のデータモデルを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | models.py | `src/backend/InvenTree/common/models.py` | NotificationEntryクラス（1616-1651行目）、BaseInvenTreeSettingクラス（190-998行目） |

**読解のコツ**:
- `NotificationEntry`のunique_together制約（key, uid）に注目
- `check_recent()`メソッドで通知重複をチェック
- `notify()`メソッドで通知履歴を記録

#### Step 2: 通知処理の流れを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | notifications.py | `src/backend/InvenTree/common/notifications.py` | trigger_notification関数（87-252行目） |

**主要処理フロー**:
1. **96-98行目**: インポート/リビルド中は通知スキップ
2. **126-137行目**: NotificationEntry.check_recent()で重複チェック
3. **149-175行目**: 通知対象ユーザーの収集（Owner, Group対応）
4. **191-252行目**: プラグインによる通知配信

#### Step 3: 設定APIを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | api.py | `src/backend/InvenTree/common/api.py` | GlobalSettingsDetail, UserSettingsDetail |

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

```
trigger_notification()
    │
    ├─ NotificationEntry.check_recent()
    │      └─ 過去24時間の重複チェック
    │
    ├─ target_users収集
    │      ├─ User直接指定
    │      ├─ Group展開
    │      └─ Owner展開
    │
    └─ registry.with_mixin(NOTIFICATION)
           │
           └─ plugin.send_notification()
                  ├─ CoreNotificationsPlugin（アプリ内通知）
                  └─ EmailNotificationPlugin（メール通知）
```

### データフロー図

```
[トリガー]           [処理]                    [出力]

イベント発生    ───▶ trigger_notification  ───▶ プラグイン配信
(在庫不足等)          │                          ├─ アプリ内通知
                      │                          ├─ メール
                      │                          └─ Webhook等
                      ▼
               NotificationEntry     ───▶ DB保存
               重複チェック               common_notificationentry
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| models.py | `src/backend/InvenTree/common/models.py` | ソース | NotificationEntry, InvenTreeSetting |
| notifications.py | `src/backend/InvenTree/common/notifications.py` | ソース | 通知トリガー関数 |
| api.py | `src/backend/InvenTree/common/api.py` | ソース | 設定API |
| settings.py | `src/backend/InvenTree/common/settings.py` | ソース | get_global_setting関数 |
