# 機能設計書 61-在庫設定

## 概要

本ドキュメントは、InvenTreeモバイルアプリにおける在庫設定機能の設計を記述するものである。在庫アイテムの表示や操作に関するユーザー設定を管理する画面の仕様を定義する。

### 本機能の処理概要

本機能は、在庫アイテムに関する表示設定やバーコードスキャン時の挙動を制御するためのユーザー設定画面を提供する。設定値はローカルデータベースに永続化され、アプリ全体の在庫関連機能に反映される。

**業務上の目的・背景**：在庫管理業務において、ユーザーごとに必要な情報や操作確認の要否が異なる。例えば、頻繁に在庫を扱う倉庫作業者はスキャン確認を省略して効率化したい一方、管理者は履歴やテスト結果を常に確認したい場合がある。本機能により、各ユーザーが自身の業務スタイルに合わせて在庫表示をカスタマイズできる。

**機能の利用シーン**：
- 在庫詳細画面で履歴タブやテスト結果タブを表示/非表示にしたい場合
- バーコードスキャン時に確認ダイアログの表示有無を切り替えたい場合
- 初期セットアップ時にユーザーの業務に合わせた設定を行う場合

**主要な処理内容**：
1. 設定値（在庫履歴表示、テスト結果表示、スキャン確認）のローカルデータベースからの読み込み
2. 各設定項目のスイッチによるON/OFF切り替え
3. 設定変更時のローカルデータベースへの即座の永続化
4. UI状態の即時更新による視覚的フィードバック

**関連システム・外部連携**：本機能はローカル設定のみを管理し、InvenTreeサーバーとの通信は発生しない。

**権限による制御**：本機能に特別な権限制御はなく、すべてのユーザーが利用可能である。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 6 | 設定画面 | 遷移元画面 | 在庫設定メニュー押下時に本画面へ遷移 |
| 14 | 在庫設定画面 | 主画面 | 履歴、テスト結果、スキャン確認の設定変更 |

## 機能種別

設定管理 / CRUD操作（Read/Update）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| stockShowHistory | bool | No | 在庫履歴を表示するか | true/false |
| stockShowTests | bool | No | テスト結果を表示するか | true/false |
| stockConfirmScan | bool | No | スキャン時に確認を表示するか | true/false |

### 入力データソース

- 画面入力：各設定項目のSwitchウィジェットからのタップ操作
- ローカルDB：`InvenTreeSettings.db`のsettingsストアから初期値を読み込み

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| stockShowHistory | bool | 在庫履歴表示設定（デフォルト: false） |
| stockShowTests | bool | テスト結果表示設定（デフォルト: true） |
| stockConfirmScan | bool | スキャン確認表示設定（デフォルト: false） |

### 出力先

- ローカルDB：`InvenTreeSettings.db`のsettingsストア
- 画面表示：Switchウィジェットの状態更新

## 処理フロー

### 処理シーケンス

```
1. 画面初期化（initState）
   └─ loadSettings()を呼び出し
2. 設定読み込み（loadSettings）
   └─ InvenTreeSettingsManager経由で各設定値を取得
   └─ 状態変数に反映（setState）
3. ユーザー操作（Switch切替）
   └─ onChangedコールバック発火
   └─ InvenTreeSettingsManager.setValue()で永続化
   └─ setStateでUI更新
```

### フローチャート

```mermaid
flowchart TD
    A[画面表示] --> B[initState]
    B --> C[loadSettings]
    C --> D[設定値読み込み]
    D --> E[UI状態更新]
    E --> F{ユーザー操作}
    F -->|Switch切替| G[設定値保存]
    G --> H[UI状態更新]
    H --> F
    F -->|戻る| I[画面終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-61-01 | デフォルト値適用 | 未設定の項目はデフォルト値を適用 | 初回起動時または設定未保存時 |
| BR-61-02 | 即時永続化 | 設定変更は即座にローカルDBに保存 | Switch切替時 |
| BR-61-03 | 履歴表示デフォルト | 在庫履歴はデフォルトで非表示 | 初期状態 |
| BR-61-04 | テスト結果デフォルト | テスト結果はデフォルトで表示 | 初期状態 |
| BR-61-05 | スキャン確認デフォルト | スキャン確認はデフォルトで非表示 | 初期状態 |

### 計算ロジック

該当なし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 設定読み込み | settings（sembast store） | SELECT | 各設定キーに対応する値を取得 |
| 設定保存 | settings（sembast store） | UPDATE/INSERT | キーと値のペアを保存（upsert） |

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

#### settings（sembast store）

| 操作 | 項目（キー） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT/UPDATE | stockShowHistory | bool値 | 在庫履歴表示フラグ |
| SELECT/UPDATE | stockShowTests | bool値 | テスト結果表示フラグ |
| SELECT/UPDATE | stockConfirmScan | bool値 | スキャン確認フラグ |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | データベース読み込みエラー | ローカルDB破損時 | デフォルト値を使用 |
| - | データベース書き込みエラー | ストレージ容量不足等 | エラーログ出力、ユーザー操作は継続可能 |

### リトライ仕様

リトライは実装されていない。エラー発生時はデフォルト値で動作を継続する。

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

sembastデータベースの単一キー操作のため、明示的なトランザクション管理は不要。各setValue操作は原子的に実行される。

## パフォーマンス要件

- 設定読み込み：100ms以内
- 設定保存：50ms以内
- UI更新：即座（16ms以内）

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

- 設定データはローカルデバイスにのみ保存
- 機密情報は含まれないため、暗号化は不要
- 他アプリからのアクセスは標準のサンドボックス機構で保護

## 備考

- 設定キーは`preferences.dart`で定数として定義されている
- mounted チェックにより、画面破棄後の setState エラーを防止している

---

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

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

### 推奨読解順序

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

設定キーの定義と設定管理クラスの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | preferences.dart | `lib/preferences.dart` | 設定キー定数（INV_STOCK_SHOW_HISTORY等）とInvenTreeSettingsManagerクラス |

**読解のコツ**:
- **39-42行目**: 在庫関連の設定キー定数（`INV_STOCK_SHOW_HISTORY`, `INV_STOCK_SHOW_TESTS`, `INV_STOCK_CONFIRM_SCAN`）が定義されている
- **110-185行目**: `InvenTreeSettingsManager`クラスはシングルトンパターンで実装され、`getValue`/`setValue`メソッドで設定の読み書きを行う
- **162-172行目**: `getBool`メソッドはbool型への変換処理を含む

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

在庫設定画面のウィジェット構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | stock_settings.dart | `lib/settings/stock_settings.dart` | StatefulWidgetの構造とStateクラス |

**主要処理フロー**:
1. **7-10行目**: `InvenTreeStockSettingsWidget`がStatefulWidgetとして定義
2. **12-13行目**: `_InvenTreeStockSettingsState`がStateクラスとして定義
3. **15-17行目**: 3つの設定値を保持する状態変数の宣言

#### Step 3: 初期化処理を理解する

画面初期化時の設定読み込み処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | stock_settings.dart | `lib/settings/stock_settings.dart` | initStateとloadSettingsメソッド |

**主要処理フロー**:
- **19-23行目**: `initState`で`loadSettings()`を呼び出し
- **25-42行目**: `loadSettings`メソッドで3つの設定値を非同期で読み込み
- **39-41行目**: `mounted`チェック後に`setState`でUI更新

#### Step 4: UI構築と操作処理を理解する

buildメソッドでのUI構築とSwitch操作時の処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | stock_settings.dart | `lib/settings/stock_settings.dart` | buildメソッドとonChangedコールバック |

**主要処理フロー**:
- **44-109行目**: Scaffoldウィジェットによる画面構築
- **54-69行目**: 在庫履歴表示設定のListTile（Switch付き）
- **60-68行目**: `onChanged`コールバックで設定保存とUI更新を実行
- **71-86行目**: テスト結果表示設定のListTile
- **88-103行目**: スキャン確認設定のListTile

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

```
InvenTreeStockSettingsWidget
    │
    └─ _InvenTreeStockSettingsState
           │
           ├─ initState()
           │      └─ loadSettings()
           │             └─ InvenTreeSettingsManager.getBool() x 3
           │
           └─ build()
                  └─ ListView
                         ├─ ListTile (履歴設定)
                         │      └─ Switch.onChanged
                         │             └─ InvenTreeSettingsManager.setValue()
                         ├─ ListTile (テスト結果設定)
                         │      └─ Switch.onChanged
                         │             └─ InvenTreeSettingsManager.setValue()
                         └─ ListTile (スキャン確認設定)
                                └─ Switch.onChanged
                                       └─ InvenTreeSettingsManager.setValue()
```

### データフロー図

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

                    ┌─────────────────────┐
ローカルDB ─────────▶│ loadSettings()      │
(sembast store)     │ - getBool() x 3     │
                    └──────────┬──────────┘
                               │
                               ▼
                    ┌─────────────────────┐
                    │ 状態変数            │──────▶ Switch表示状態
                    │ - stockShowHistory  │
                    │ - stockShowTests    │
                    │ - stockConfirmScan  │
                    └──────────┬──────────┘
                               │
                               ▼
                    ┌─────────────────────┐
Switchタップ ───────▶│ onChanged()         │
                    │ - setValue()        │──────▶ ローカルDB
                    │ - setState()        │        (sembast store)
                    └─────────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| stock_settings.dart | `lib/settings/stock_settings.dart` | ソース | 在庫設定画面のUI・ロジック |
| preferences.dart | `lib/preferences.dart` | ソース | 設定キー定数・設定管理クラス |
| l10.dart | `lib/l10.dart` | ソース | 多言語テキスト取得ヘルパー |
| app_colors.dart | `lib/app_colors.dart` | ソース | アプリ共通カラー定義 |
| settings.dart | `lib/settings/settings.dart` | ソース | 設定画面（遷移元） |
