# 通知設計書 15-在庫スキャン失敗

## 概要

本ドキュメントは、InvenTreeモバイルアプリにおける「在庫スキャン失敗」通知の設計仕様を定義する。この通知は、在庫アイテムをバーコードスキャンによってロケーションに移動させる操作が失敗した際に表示されるエラー通知である。

### 本通知の処理概要

この通知は、バーコードスキャン機能を使用して在庫アイテムを新しいロケーションに移動しようとした際に、何らかの理由で失敗した場合のフィードバックとして機能する。

**業務上の目的・背景**：在庫管理において、スキャン操作の失敗は作業効率に直接影響する。ネットワークエラー、サーバー側の処理エラー、権限不足など、様々な理由でスキャン移動が失敗する可能性がある。この通知により、ユーザーは操作が完了しなかったことを即座に把握し、原因の特定や再試行に取り組むことができる。

**通知の送信タイミング**：`StockItemScanIntoLocationHandler` を使用して在庫アイテムをスキャンし、`transferStock()` メソッドがfalseを返した時点で通知が生成される。また、`StockLocationScanInItemsHandler` での在庫移動が失敗した場合にも同様の通知が表示される。

**通知の受信者**：バーコードスキャン操作を実行した現在のアプリユーザー。通知はアプリ内スナックバーとして即座に表示される。

**通知内容の概要**：「Item not scanned in」というメッセージが表示され、在庫アイテムのスキャン移動が失敗したことをユーザーに伝える。失敗音声フィードバックも再生される。

**期待されるアクション**：ユーザーはエラーの原因を確認し、ネットワーク接続の確認、再スキャン、または管理者への連絡などの対処を行う。

## 通知種別

アプリ内通知（スナックバー）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期 |
| 優先度 | 中 |
| リトライ | 無し |

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

現在の操作を実行しているアプリユーザーに対して即座に表示される。サーバーへの通知送信は行わず、クライアントサイドのみで処理される。

## 通知テンプレート

### スナックバー通知

| 項目 | 内容 |
|-----|------|
| 表示位置 | 画面下部 |
| 背景色 | deepOrange（エラー時） |
| アイコン | exclamation_circle |
| 表示時間 | 5秒 |

### 本文テンプレート

```
Item not scanned in
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| なし | 固定メッセージ | L10().barcodeScanIntoLocationFailure | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| バーコード操作 | ロケーションスキャン失敗 | transferStock()がfalseを返却 | 在庫アイテムのロケーションスキャンが失敗した場合 |
| バーコード操作 | アイテムスキャン失敗 | transferStock()がfalseを返却 | ロケーションへのアイテムスキャンが失敗した場合 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| スキャン成功時 | transferStockがtrueを返却した場合は成功通知が表示される |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[バーコードスキャン操作] --> B{ハンドラー種別}
    B -->|StockItemScanIntoLocationHandler| C[ロケーションスキャン]
    B -->|StockLocationScanInItemsHandler| D[アイテムスキャン]
    C --> E[transferStock API呼び出し]
    D --> E
    E --> F{API結果}
    F -->|成功| G[成功通知表示]
    F -->|失敗| H[barcodeFailureTone再生]
    H --> I[showSnackIcon success=false]
    I --> J[エラースナックバー表示]
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| なし（クライアント側のみ） | - | 失敗時は更新なし |

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

クライアントアプリ側では直接データベースを参照しない。失敗通知のため更新処理も発生しない。

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| なし | - | 失敗時は更新なし |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| API通信失敗 | ネットワークエラーまたはサーバーエラー | エラー通知を表示、ユーザーに再試行を促す |
| 権限エラー | ユーザーに在庫移動権限がない | 権限エラー通知を表示 |
| データ整合性エラー | 在庫アイテムまたはロケーションが無効 | 該当するエラー通知を表示 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0回（ユーザーによる手動再試行） |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

## 配信設定

### レート制限

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

### 配信時間帯

24時間365日（アプリ使用時のみ）

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

- エラー通知には詳細なエラー情報は含まれず、単純な失敗メッセージのみ
- セキュリティ上の理由により、失敗の詳細原因は通知に含まれない

## 備考

- 音声フィードバックが有効な場合、barcodeFailureTone()による失敗音が再生される
- 国際化対応済み（L10()による多言語サポート）
- この通知は複数のスキャンハンドラーで共通して使用される

---

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

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

### 推奨読解順序

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

在庫スキャン失敗通知に関連するデータ構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | app_en.arb | `lib/l10n/app_en.arb` | barcodeScanIntoLocationFailure の定義（193行目） |

**読解のコツ**: このメッセージはバーコードスキャンによるロケーション移動失敗時に使用される。

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

失敗通知が発生するスキャンハンドラーを特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | stock.dart | `lib/barcode/stock.dart` | StockItemScanIntoLocationHandler（111-157行目） |
| 2-2 | stock.dart | `lib/barcode/stock.dart` | StockLocationScanInItemsHandler（166-227行目） |

**主要処理フロー**:
1. **150-153行目**: StockItemScanIntoLocationHandler での失敗処理
2. **214-219行目**: StockLocationScanInItemsHandler での失敗処理

#### Step 3: 失敗通知表示層を理解する

失敗通知の表示メカニズムを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | stock.dart | `lib/barcode/stock.dart` | 失敗時のshowSnackIcon呼び出し |

**主要処理フロー**:
- **151行目**: barcodeFailureTone() - 失敗音再生
- **152行目**: showSnackIcon(L10().barcodeScanIntoLocationFailure, success: false)
- **217-219行目**: showSnackIcon呼び出し（成功/失敗に応じたメッセージ）

#### Step 4: 音声フィードバック層を理解する

失敗音の再生メカニズムを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | tones.dart | `lib/barcode/tones.dart` | barcodeFailureTone関数（17-25行目） |

**主要処理フロー**:
- **17-25行目**: barcodeFailureTone - 設定に応じて失敗音を再生

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

```
StockItemScanIntoLocationHandler (stock.dart:111)
    │
    └─ onLocationScanned (stock.dart:117)
           │
           └─ item.transferStock(locationId) (stock.dart:145)
                  │
                  └─ [失敗時] (stock.dart:150-153)
                         │
                         ├─ barcodeFailureTone (tones.dart:17)
                         └─ showSnackIcon(barcodeScanIntoLocationFailure, success: false)

StockLocationScanInItemsHandler (stock.dart:166)
    │
    └─ onItemScanned (stock.dart:175)
           │
           └─ item.transferStock(location.pk) (stock.dart:212)
                  │
                  └─ [失敗時] (stock.dart:214-219)
                         └─ showSnackIcon(barcodeScanIntoLocationFailure, success: false)
```

### データフロー図

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

バーコード          ───▶ スキャンハンドラー        ───▶ サーバーAPI
スキャン                      │                          │
                              │                          ▼
                              │                    transferStock()
                              │                          │
                              │                          ▼
                              │                     失敗応答
                              │                          │
                              ▼                          ▼
                         result=false            barcodeFailureTone()
                              │                          │
                              │                          ▼
                              └──────────────────▶ showSnackIcon
                                                  "Item not scanned in"
                                                  (オレンジ色背景)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| stock.dart | `lib/barcode/stock.dart` | ソース | 在庫スキャンハンドラー |
| tones.dart | `lib/barcode/tones.dart` | ソース | 音声フィードバック |
| snacks.dart | `lib/widget/snacks.dart` | ソース | スナックバー表示 |
| app_en.arb | `lib/l10n/app_en.arb` | リソース | 英語ローカライゼーション |
