# 通知設計書 8-バーコードスキャン成功

## 概要

本ドキュメントは、InvenTreeモバイルアプリケーションにおける「バーコードスキャン成功」通知の設計仕様を定義する。バーコードスキャンが正常に完了した際に再生される音声通知の仕様を記載する。

### 本通知の処理概要

この通知は、バーコードスキャン操作が正常に完了したことをユーザーに音声フィードバックで伝える機能である。視覚的な確認なしでも操作結果を認識できる。

**業務上の目的・背景**：倉庫作業や在庫管理において、バーコードスキャンは頻繁に行われる操作である。作業者は画面を常に見ているわけではなく、音声フィードバックにより手元を見ながらでもスキャン結果を確認できる。これにより作業効率が大幅に向上し、スキャン漏れや重複スキャンを防止できる。

**通知の送信タイミング**：`barcodeSuccessTone()`関数が呼び出された際にトリガーされる。これは主に以下の場面で発生する：
- バーコードスキャン後、サーバーから成功レスポンスが返された場合
- `BarcodeHandler.onBarcodeMatched()`が呼び出された場合
- 各種バーコード処理（在庫移動、PO受入、SO割当など）が成功した場合

**通知の受信者**：アプリケーションを操作している現在のユーザー。デバイスのスピーカーから音声が再生される。

**通知内容の概要**：`sounds/barcode_scan.mp3`という音声ファイルが再生される。短い「ピッ」という成功音で、視覚に頼らず操作結果を認識できる。

**期待されるアクション**：ユーザーは音声を確認し、スキャンが成功したことを認識して次のアイテムのスキャンに移行する。画面を確認する必要がないため、連続スキャン作業の効率が向上する。

## 通知種別

音声通知（サウンドエフェクト）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 非同期 |
| 優先度 | 中 |
| リトライ | 無し（音声再生のため） |

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

現在アプリケーションを操作しているユーザーのデバイスで音声が再生される。音声再生は`AudioPlayer`ライブラリを使用し、`AndroidUsageType.notification`として再生される。

## 通知テンプレート

### 音声ファイル

| 項目 | 内容 |
|-----|------|
| ファイルパス | `sounds/barcode_scan.mp3` |
| 形式 | MP3 |
| 再生タイミング | スキャン成功時即座 |
| 音量 | システム通知音量に従う |

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| INV_SOUNDS_BARCODE | バーコード音声有効/無効 | InvenTreeSettingsManager | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| バーコード | スキャン成功 | サーバーから成功レスポンス | BarcodeHandler.onBarcodeMatched |
| バーコード | 在庫移動成功 | StockLocationScanHandler成功 | 在庫アイテムのロケーション移動 |
| バーコード | PO受入成功 | POReceiveBarcodeHandler成功 | 購買発注のアイテム受入 |
| バーコード | SO割当成功 | SalesOrderBarcodeHandler成功 | 販売発注への在庫割当 |
| バーコード | リンク成功 | バーコードリンク成功 | カスタムバーコードの割当 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| コンテキストなし | `hasContext()`が`false`を返す場合 |
| 音声設定無効 | `INV_SOUNDS_BARCODE`が`false`の場合 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[バーコードスキャン] --> B[サーバーにPOST]
    B --> C{レスポンス成功?}
    C -->|Yes| D[onBarcodeMatched呼び出し]
    D --> E[barcodeSuccessTone呼び出し]
    E --> F{INV_SOUNDS_BARCODE?}
    F -->|true| G{hasContext?}
    F -->|false| H[音声スキップ]
    G -->|Yes| I[playAudioFile呼び出し]
    G -->|No| H
    I --> J[barcode_scan.mp3再生]
    C -->|No| K[onBarcodeUnknown呼び出し]
    J --> L[終了]
    H --> L
    K --> L
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| settings | 音声設定確認 | Sembast NoSQL DB |

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

#### settings

| 参照項目（キー名） | 用途 | 取得条件 |
|-------------------|------|---------|
| INV_SOUNDS_BARCODE | バーコード音声有効/無効 | デフォルト: true |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| なし | - | 音声再生のみで更新なし |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 音声再生失敗 | AudioPlayerが利用できない | 音声なしで処理継続 |
| ファイル不在 | 音声ファイルが見つからない | 例外をキャッチして継続 |

### リトライ仕様

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

音声通知のため、リトライは行わない。

## 配信設定

### レート制限

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

### 配信時間帯

制限なし（スキャン成功時に即座に再生）

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

- 音声ファイルに機密情報は含まれない
- 周囲に音が聞こえる可能性があるが、内容は単純な確認音のみ

## 備考

- 音声再生は`AudioPlayer`ライブラリを使用
- `AudioContext`は`AndroidUsageType.notification`に設定（他のメディア再生を中断しない）
- `AudioFocus.none`に設定（他のアプリの音声を中断しない）
- 音声設定は設定画面から変更可能（`INV_SOUNDS_BARCODE`）
- デフォルトでは音声有効

---

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

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

### 推奨読解順序

#### Step 1: 音声再生関数を理解する

まず、バーコード成功音を再生する専用関数を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | tones.dart | `lib/barcode/tones.dart` | barcodeSuccessTone関数 |

**読解のコツ**: `barcodeSuccessTone()`は設定を確認してから`playAudioFile()`を呼び出す簡潔な関数。

#### Step 2: 音声再生の実装を理解する

playAudioFile関数の実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | helpers.dart | `lib/helpers.dart` | playAudioFile関数 |

**主要処理フロー**:
1. **行7-15**: `barcodeSuccessTone()`関数 - 設定確認と音声再生
2. **行92-115**: `playAudioFile()`関数 - AudioPlayerの設定と再生
3. **行104-112**: `AudioContext`の設定 - 通知用音声として再生

#### Step 3: 呼び出し元を理解する

barcodeSuccessToneが呼び出される箇所を特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | handler.dart | `lib/barcode/handler.dart` | BarcodeHandlerクラス |
| 3-2 | stock.dart | `lib/barcode/stock.dart` | StockLocationScanHandler |
| 3-3 | purchase_order.dart | `lib/barcode/purchase_order.dart` | POReceiveBarcodeHandler |
| 3-4 | sales_order.dart | `lib/barcode/sales_order.dart` | SalesOrderBarcodeHandler |

**主要処理フロー**:
- 各Handlerクラスの成功処理で`barcodeSuccessTone()`が呼び出される

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

```
[バーコードスキャン成功]
    |
    +-- BarcodeHandler.onBarcodeMatched() [handler.dart]
    |       |
    |       +-- barcodeSuccessTone() [tones.dart:7]
    |
    +-- StockLocationScanHandler [stock.dart]
    |       |
    |       +-- barcodeSuccessTone()
    |
    +-- POReceiveBarcodeHandler [purchase_order.dart]
    |       |
    |       +-- barcodeSuccessTone()
    |
    +-- SalesOrderBarcodeHandler [sales_order.dart]
            |
            +-- barcodeSuccessTone()
                    |
                    +-- InvenTreeSettingsManager().getValue()
                    |
                    +-- playAudioFile() [helpers.dart:92]
                            |
                            +-- hasContext() [helpers.dart:55]
                            +-- AudioPlayer() [audioplayers]
                            +-- player.play(AssetSource("sounds/barcode_scan.mp3"))
```

### データフロー図

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

スキャン成功        barcodeSuccessTone()             音声再生
     |          --->       |                   --> barcode_scan.mp3
     v                     v
サーバー応答        INV_SOUNDS_BARCODE確認
success:true              |
                          v
                    playAudioFile()
                          |
                          v
                    AudioPlayer.play()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| tones.dart | `lib/barcode/tones.dart` | ソース | バーコード音声再生関数 |
| helpers.dart | `lib/helpers.dart` | ソース | 音声再生の実装 |
| handler.dart | `lib/barcode/handler.dart` | ソース | バーコードハンドラ基底クラス |
| stock.dart | `lib/barcode/stock.dart` | ソース | 在庫バーコード処理 |
| purchase_order.dart | `lib/barcode/purchase_order.dart` | ソース | PO受入バーコード処理 |
| sales_order.dart | `lib/barcode/sales_order.dart` | ソース | SO割当バーコード処理 |
| preferences.dart | `lib/preferences.dart` | ソース | INV_SOUNDS_BARCODE設定 |
| barcode_scan.mp3 | `sounds/barcode_scan.mp3` | 音声 | 成功音 |
