# バッチ設計書 7-通知カウンター更新

## 概要

本ドキュメントは、InvenTreeモバイルアプリがサーバー接続後に未読通知数を定期的に取得・更新するアプリ内定期処理「通知カウンター更新」の設計仕様を記載します。

### 本バッチの処理概要

本バッチは、InvenTreeサーバーへの接続が確立された後、60秒間隔でサーバーから未読通知の件数を取得し、アプリ内の通知カウンターを更新するTimer.periodicを使用した定期処理です。

**業務上の目的・背景**：InvenTreeは在庫管理システムであり、ユーザーには様々な通知（在庫不足、発注アラート、タスク完了など）が送信されます。ユーザーが新しい通知を見逃さないよう、アプリは定期的に未読通知数をサーバーから取得し、UIに反映する必要があります。この定期的な更新により、ユーザーはリアルタイムに近い形で通知を把握できます。

**バッチの実行タイミング**：サーバーへの接続が成功した直後に開始され、60秒間隔で継続的に実行されます。サーバーから切断されると停止します。

**主要な処理内容**：
1. サーバー接続確立時にTimer.periodicを開始
2. 60秒ごとに_refreshNotifications()メソッドを呼び出し
3. InvenTreeNotification APIで未読通知件数を取得（read=falseフィルタ）
4. notification_counter変数を更新

**前後の処理との関連**：connectToServer()メソッド内でサーバー接続成功後に開始されます。disconnectFromServer()では明示的なタイマーキャンセルは行われませんが、接続状態チェックにより処理がスキップされます。

**影響範囲**：InvenTreeAPIクラスのnotification_counter変数が更新され、UIに反映されます。

## バッチ種別

定期ポーリング処理（アプリ内バックグラウンド処理）

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 60秒間隔 |
| 実行時刻 | サーバー接続後継続的に実行 |
| 実行曜日 | なし（常時） |
| 実行日 | なし（常時） |
| トリガー | サーバー接続成功時に自動開始 |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| サーバー接続済み | InvenTreeサーバーへの接続が確立されていること |
| 認証済み | ユーザーが認証されトークンが有効であること |
| _notification_timerがnull | 既存のタイマーが存在しないこと |

### 実行可否判定

isConnected()がtrueを返す場合にのみ実際のAPI呼び出しが実行されます。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| なし | - | - | - | パラメータ不要 |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| InvenTree API | REST API | サーバーから未読通知件数を取得 |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| notification_counter | int | 未読通知件数（メモリ内変数） |

### 出力ファイル仕様

ファイル出力はありません。

## 処理フロー

### 処理シーケンス

```
1. サーバー接続成功
   └─ connectToServer()内で_connected=trueに設定
2. タイマー初期化チェック
   └─ _notification_timerがnullかどうか確認
3. Timer.periodic開始
   └─ 60秒間隔で_refreshNotifications()を呼び出し
4. 定期実行
   └─ isConnected()チェック後、未読通知件数を取得
5. カウンター更新
   └─ notification_counter変数を更新
```

### フローチャート

```mermaid
flowchart TD
    A[サーバー接続成功] --> B{_notification_timer == null?}
    B -->|はい| C[Timer.periodic 開始]
    B -->|いいえ| D[既存タイマー継続]
    C --> E[60秒待機]
    D --> E
    E --> F[_refreshNotifications 呼び出し]
    F --> G{isConnected?}
    G -->|はい| H[未読通知件数取得 API呼び出し]
    G -->|いいえ| I[処理スキップ]
    H --> J[notification_counter 更新]
    J --> E
    I --> E
```

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

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

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 通知件数取得 | notifications | SELECT | サーバー側で未読通知件数をカウント |

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

#### notifications（サーバー側）

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ネットワークエラー | サーバーに接続できない | 次回の定期実行で再試行 |
| - | 認証エラー | トークンが無効 | ユーザーに再ログインを促す |
| - | サーバーエラー | サーバー内部エラー | 次回の定期実行で再試行 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 自動（次回定期実行） |
| リトライ間隔 | 60秒 |
| リトライ対象エラー | 全てのエラー |

### 障害時対応

エラーが発生してもタイマーは継続し、次回の定期実行で再試行されます。継続的なエラーの場合は接続状態を確認してください。

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | なし（読み取りのみ） |
| コミットタイミング | - |
| ロールバック条件 | - |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 1リクエスト/60秒 |
| 目標処理時間 | 1秒以内 |
| メモリ使用量上限 | 特に制限なし |

## 排他制御

タイマーの重複起動を防ぐため、_notification_timerがnullの場合のみ新しいタイマーを作成します。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| デバッグログ | タイマー開始時 | "starting notification timer" |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| なし | - | - |

## 備考

- 本処理はアプリのフォアグラウンド/バックグラウンド状態に関係なく実行されます
- バッテリー消費を考慮し、60秒という比較的長い間隔が設定されています
- サーバー切断時は_refreshNotifications()内のisConnected()チェックで処理がスキップされます
- connectToServer()内でタイマーをキャンセルしてから再接続を行うことで、タイマーの重複を防いでいます
