# 機能設計書 51-通知一覧表示

## 概要

本ドキュメントは、InvenTreeモバイルアプリにおける通知一覧表示機能の設計を記述する。

### 本機能の処理概要

サーバーからの通知メッセージを一覧表示し、ユーザーが未読通知を確認できる機能を提供する。

**業務上の目的・背景**：在庫管理システムでは、在庫切れ警告、発注の承認依頼、システムアラートなど、様々な通知がサーバーから送信される。ユーザーはこれらの通知をリアルタイムに確認することで、迅速な対応が可能となり、業務効率が向上する。通知機能により、重要な情報の見落としを防止し、適切なタイミングでのアクション実行を支援する。

**機能の利用シーン**：ドロワーメニューの通知アイコンをタップした際に通知画面へ遷移し、未読の通知一覧を確認する。また、定期的なバックグラウンド更新により通知カウンターが更新され、新着通知の存在をユーザーに知らせる。

**主要な処理内容**：
1. サーバーAPIから未読通知一覧を取得する
2. 通知メッセージをリスト形式で表示する
3. 通知件数をアプリバーに表示する
4. 60秒間隔でバックグラウンド更新を実行する

**関連システム・外部連携**：InvenTree REST API（notifications/エンドポイント）との通信を行う。

**権限による制御**：認証済みユーザーのみがアクセス可能。通知はユーザー単位で管理され、自身の通知のみ表示される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 4 | 通知画面 | 主機能 | サーバーからの通知一覧を取得・表示 |
| 2 | ドロワーメニュー | 遷移元 | 通知メニュー押下時に通知画面へ遷移 |

## 機能種別

データ連携 / CRUD操作（Read）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| read | String | No | 既読フィルタ（デフォルト: "false"） | "true" / "false" |

### 入力データソース

InvenTree REST API: `notifications/` エンドポイント

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| pk | int | 通知の一意識別子 |
| name | String | 通知タイトル |
| message | String | 通知メッセージ本文 |
| creation | DateTime | 通知作成日時 |
| read | bool | 既読フラグ |

### 出力先

画面表示（ListTile形式のリストビュー）

## 処理フロー

### 処理シーケンス

```
1. 画面初期化
   └─ RefreshableStateのinitStateでonBuildをスケジュール
2. データ取得リクエスト
   └─ InvenTreeNotification().list()でAPI呼び出し
3. デフォルトフィルタ適用
   └─ read=falseで未読通知のみ取得
4. 結果リスト構築
   └─ 取得した通知をnotificationsリストに格納
5. UI更新
   └─ setStateでリスト表示を更新
```

### フローチャート

```mermaid
flowchart TD
    A[画面表示開始] --> B[onBuild呼び出し]
    B --> C[refresh実行]
    C --> D[request呼び出し]
    D --> E[InvenTreeNotification.list]
    E --> F[API通信]
    F --> G{レスポンス成功?}
    G -->|Yes| H[通知リスト構築]
    G -->|No| I[エラー表示]
    H --> J[setState]
    J --> K[リスト表示更新]
    I --> K
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-51-01 | 未読フィルタ | デフォルトで未読通知のみを表示 | 通知一覧取得時 |
| BR-51-02 | 通知カウンター | 60秒間隔でバックグラウンド更新 | サーバー接続中 |

### 計算ロジック

該当なし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 通知一覧取得 | notifications | SELECT | ユーザーの通知一覧を取得 |

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

#### notifications（リモートAPI）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | all | read=false | 未読通知のみ取得 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 接続エラー | サーバー未接続時 | 接続ステータスを表示 |
| 401 | 認証エラー | トークン無効時 | 再ログインを促す |

### リトライ仕様

プルダウンリフレッシュによる手動リトライが可能

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

読み取り専用のためトランザクション制御なし

## パフォーマンス要件

- 通知一覧の表示は2秒以内
- バックグラウンド更新は60秒間隔

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

- 認証トークンによるアクセス制御
- ユーザー単位の通知分離（自身の通知のみ表示）
- HTTPS通信による通信暗号化

## 備考

API バージョン82以降では、通知の既読化がupdate APIを使用するモダンな実装に変更されている。

---

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

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

### 推奨読解順序

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

まず、通知データのモデル構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | notification.dart | `lib/inventree/notification.dart` | InvenTreeNotificationクラスの構造、APIエンドポイント、データフィールド |

**読解のコツ**: InvenTreeModelを継承しており、URL、defaultListFilters()、dismiss()メソッドが重要。

**主要処理フロー**:
- **7-8行目**: InvenTreeNotificationクラス定義、InvenTreeModelを継承
- **19行目**: APIエンドポイント `notifications/`
- **22-25行目**: デフォルトフィルタで未読のみ取得
- **27行目**: messageプロパティ定義
- **40-47行目**: dismiss()メソッドでAPI バージョンによる分岐処理

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

ウィジェットの構造と画面初期化処理を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | notifications.dart | `lib/widget/notifications.dart` | NotificationWidgetクラス、状態管理、画面構築 |

**主要処理フロー**:
- **10-13行目**: StatefulWidgetとしてのNotificationWidget定義
- **15-16行目**: RefreshableStateを継承した_NotificationState
- **18行目**: 通知リストの状態保持
- **26-36行目**: request()メソッドでAPIからデータ取得

#### Step 3: リスト表示処理を理解する

通知アイテムの表示ロジックを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | notifications.dart | `lib/widget/notifications.dart` | getTiles()メソッドのListTile構築 |

**主要処理フロー**:
- **68-100行目**: getTiles()で通知一覧のUIを構築
- **71-80行目**: ヘッダータイル（通知件数表示）
- **82-97行目**: 各通知アイテムのListTile生成

#### Step 4: バックグラウンド更新を理解する

通知カウンターの定期更新処理を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | api.dart | `lib/api.dart` | _notification_timer、_refreshNotifications() |

**主要処理フロー**:
- **1763-1764行目**: notification_counter変数
- **1765行目**: Timerインスタンス
- **1770-1778行目**: _refreshNotifications()で60秒ごとにカウント更新
- **688-691行目**: connectToServer()でタイマー開始

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

```
NotificationWidget (notifications.dart)
    │
    ├─ _NotificationState
    │      ├─ request()
    │      │      └─ InvenTreeNotification().list()
    │      │             └─ InvenTreeModel.list() (model.dart)
    │      │                    └─ InvenTreeAPI.get() (api.dart)
    │      │
    │      ├─ dismissNotification()
    │      │      └─ notification.dismiss()
    │      │             └─ InvenTreeModel.update() or api.post()
    │      │
    │      └─ getTiles()
    │             └─ ListTile widgets
    │
    └─ RefreshableState (refreshable_state.dart)
           ├─ refresh()
           └─ getBody()
```

### データフロー図

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

ユーザー操作     ───▶  NotificationWidget          ───▶  通知リスト画面
(画面遷移/リフレッシュ)     │
                          ├─ request()
                          │      │
                          │      ▼
API通信          ◀───  InvenTreeNotification.list()
(notifications/)           │
                          │
                          ▼
サーバーレスポンス ───▶  notifications List       ───▶  ListTile表示
(JSON)                     │
                          └─ setState()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| notifications.dart | `lib/widget/notifications.dart` | ソース | 通知一覧表示ウィジェット |
| notification.dart | `lib/inventree/notification.dart` | ソース | 通知データモデル |
| model.dart | `lib/inventree/model.dart` | ソース | 基底モデルクラス |
| api.dart | `lib/api.dart` | ソース | API通信・バックグラウンド更新 |
| refreshable_state.dart | `lib/widget/refreshable_state.dart` | ソース | リフレッシュ可能な状態管理基底クラス |
| l10.dart | `lib/l10.dart` | ソース | 多言語対応（ローカライゼーション） |
