# 画面設計書 1-ホーム画面

## 概要

本ドキュメントは、InvenTree Flutterアプリケーションのホーム画面（InvenTreeHomePage）の画面設計を定義するものである。

### 本画面の処理概要

ホーム画面はアプリケーションのメインエントリーポイントであり、ユーザーが各機能にアクセスするための中心的なナビゲーションハブとして機能する。

**業務上の目的・背景**：在庫管理システムにおいて、ユーザーが日常的に必要とする機能（部品管理、在庫管理、発注管理、受注管理、会社管理）へ迅速にアクセスできる起点を提供する。サーバー未接続状態の場合は接続を促すUIを表示し、スムーズなサーバー接続を支援する。

**画面へのアクセス方法**：アプリケーション起動時に自動的に表示される。ドロワーメニューのInvenTreeロゴタップでも遷移可能。

**主要な操作・処理内容**：
1. サーバー接続状態の表示と接続操作（未接続時は接続ステータスウィジェット、接続中はスピナー、接続済みはナビゲーションタイル表示）
2. 部品カテゴリ画面への遷移（「部品」タイルタップ）
3. お気に入り部品一覧への遷移（「お気に入り部品」タイルタップ）
4. 在庫ロケーション画面への遷移（「在庫」タイルタップ）
5. 購入注文一覧への遷移（「購入注文」タイルタップ）
6. 販売注文一覧への遷移（「販売注文」タイルタップ）
7. 保留中の出荷一覧への遷移（「保留中の出荷」タイルタップ）
8. サプライヤー一覧への遷移（「サプライヤー」タイルタップ）
9. 顧客一覧への遷移（「顧客」タイルタップ）
10. サーバー選択画面への遷移（AppBarのサーバーアイコンタップ）

**画面遷移**：
- 遷移元：アプリ起動、ドロワーメニュー
- 遷移先：部品カテゴリ画面、在庫ロケーション画面、購入注文一覧画面、販売注文一覧画面、出荷一覧画面、サプライヤー一覧画面、顧客一覧画面、サーバー選択画面、検索画面、バーコードスキャン画面

**権限による表示制御**：ユーザーの権限（roles）に応じて各タイルの表示/非表示およびアクション可否が制御される。権限がない場合はタップ時に「権限が必要です」メッセージを表示。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | サーバー接続管理 | 主機能 | サーバー接続状態の表示、未接続時の接続ステータスウィジェット表示 |
| 2 | ユーザープロファイル管理 | 遷移先機能 | サーバー選択ボタン押下時にプロファイル選択画面へ遷移 |
| 4 | パーツ一覧表示 | 遷移先機能 | パーツタイル押下時にパーツカテゴリ画面へ遷移 |
| 14 | 在庫アイテム一覧表示 | 遷移先機能 | 在庫タイル押下時に在庫ロケーション画面へ遷移 |
| 23 | 発注一覧表示 | 遷移先機能 | 発注タイル押下時に発注一覧画面へ遷移 |
| 32 | 受注一覧表示 | 遷移先機能 | 受注タイル押下時に受注一覧画面へ遷移 |
| 36 | 出荷管理 | 遷移先機能 | 出荷タイル押下時に出荷一覧画面へ遷移 |
| 38 | 会社一覧表示 | 遷移先機能 | サプライヤー/顧客タイル押下時に会社一覧画面へ遷移 |

## 画面種別

ナビゲーションハブ（ダッシュボード型）

## URL/ルーティング

- Flutterルート：`/`（アプリケーションルート）
- Widgetクラス：`InvenTreeHomePage`

## 入出力項目

| 項目名 | 入力/出力 | データ型 | 必須 | 説明 |
|--------|----------|----------|------|------|
| なし | - | - | - | 本画面は入力項目を持たない |

## 表示項目

| 項目名 | データ型 | 説明 | 取得元 |
|--------|----------|------|--------|
| アプリタイトル | String | AppBarに表示されるアプリケーション名 | L10().appTitle |
| サーバー接続状態インジケーター | Widget | 接続済み（緑）、接続中（黄）、未接続（赤）の色付き円形アイコン | InvenTreeAPI().isConnected(), isConnecting() |
| 部品タイル | Widget | 部品カテゴリへのナビゲーションタイル | InvenTreePart().canView |
| お気に入り部品タイル | Widget | お気に入り部品一覧へのナビゲーションタイル | homeShowSubscribed設定 |
| 在庫タイル | Widget | 在庫ロケーションへのナビゲーションタイル | InvenTreeStockItem().canView |
| 購入注文タイル | Widget | 購入注文一覧へのナビゲーションタイル | homeShowPo設定 && InvenTreePurchaseOrder().canView |
| 販売注文タイル | Widget | 販売注文一覧へのナビゲーションタイル | homeShowSo設定 && InvenTreeSalesOrder().canView |
| 出荷タイル | Widget | 保留中出荷一覧へのナビゲーションタイル | homeShowShipments設定 && InvenTreeSalesOrderShipment().canView |
| サプライヤータイル | Widget | サプライヤー一覧へのナビゲーションタイル | homeShowSuppliers設定 && InvenTreePurchaseOrder().canView |
| 顧客タイル | Widget | 顧客一覧へのナビゲーションタイル | homeShowCustomers設定 |
| 接続ステータスウィジェット | Widget | サーバー未接続時に表示される接続促進UI | InvenTreeAPI().isConnected() == false |

## イベント仕様

### 1-サーバーアイコン押下

AppBarのサーバーアイコンをタップした際にサーバー選択画面へ遷移する。

**処理フロー**：
1. ユーザーがサーバーアイコンをタップ
2. `_selectProfile()`メソッドが呼び出される
3. `Navigator.push()`で`InvenTreeSelectServerWidget`へ遷移
4. サーバー選択画面から戻った際に`_loadProfile()`を実行してプロファイルを再読み込み

### 2-部品タイル押下

部品タイルをタップした際に部品カテゴリ画面へ遷移する。

**処理フロー**：
1. ユーザーが部品タイルをタップ
2. `InvenTreeAPI().checkConnection()`で接続確認
3. 接続済みの場合、`Navigator.push()`で`CategoryDisplayWidget(null)`へ遷移

### 3-在庫タイル押下

在庫タイルをタップした際に在庫ロケーション画面へ遷移する。

**処理フロー**：
1. ユーザーが在庫タイルをタップ
2. `InvenTreeAPI().checkConnection()`で接続確認
3. 接続済みの場合、`Navigator.push()`で`LocationDisplayWidget(null)`へ遷移

### 4-購入注文タイル押下

購入注文タイルをタップした際に購入注文一覧画面へ遷移する。

**処理フロー**：
1. ユーザーが購入注文タイルをタップ
2. `InvenTreeAPI().checkConnection()`で接続確認
3. 接続済みの場合、`Navigator.push()`で`PurchaseOrderListWidget(filters: {})`へ遷移

### 5-販売注文タイル押下

販売注文タイルをタップした際に販売注文一覧画面へ遷移する。

**処理フロー**：
1. ユーザーが販売注文タイルをタップ
2. `InvenTreeAPI().checkConnection()`で接続確認
3. 接続済みの場合、`Navigator.push()`で`SalesOrderListWidget(filters: {})`へ遷移

### 6-サプライヤータイル押下

サプライヤータイルをタップした際にサプライヤー一覧画面へ遷移する。

**処理フロー**：
1. ユーザーがサプライヤータイルをタップ
2. `InvenTreeAPI().checkConnection()`で接続確認
3. 接続済みの場合、`Navigator.push()`で`CompanyListWidget(L10().suppliers, {"is_supplier": "true"})`へ遷移

### 7-顧客タイル押下

顧客タイルをタップした際に顧客一覧画面へ遷移する。

**処理フロー**：
1. ユーザーが顧客タイルをタップ
2. `InvenTreeAPI().checkConnection()`で接続確認
3. 接続済みの場合、`Navigator.push()`で`CompanyListWidget(L10().customers, {"is_customer": "true"})`へ遷移

### 8-接続ステータスウィジェット押下

サーバー未接続時に表示される接続ステータスウィジェットをタップした際にサーバー選択画面へ遷移する。

**処理フロー**：
1. ユーザーが接続ステータスウィジェットをタップ
2. `_selectProfile()`メソッドが呼び出される
3. サーバー選択画面へ遷移

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 画面表示時 | settings | SELECT | ホーム画面表示設定の読み込み |
| 画面表示時 | profiles | SELECT | 選択中プロファイルの読み込み |

### テーブル別更新項目詳細

#### settings（ローカルDB）

| 操作 | 項目（キー名） | 取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | homeShowSubscribed | INV_HOME_SHOW_SUBSCRIBED | お気に入り部品タイル表示設定 |
| SELECT | homeShowPo | INV_HOME_SHOW_PO | 購入注文タイル表示設定 |
| SELECT | homeShowSo | INV_HOME_SHOW_SO | 販売注文タイル表示設定 |
| SELECT | homeShowShipments | INV_HOME_SHOW_SHIPMENTS | 出荷タイル表示設定 |
| SELECT | homeShowManufacturers | INV_HOME_SHOW_MANUFACTURERS | 製造業者タイル表示設定 |
| SELECT | homeShowCustomers | INV_HOME_SHOW_CUSTOMERS | 顧客タイル表示設定 |
| SELECT | homeShowSuppliers | INV_HOME_SHOW_SUPPLIERS | サプライヤータイル表示設定 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|--------------|---------|
| MSG-001 | 情報 | L10().serverNotConnected | サーバー未接続時 |
| MSG-002 | 情報 | L10().serverNotSelected | サーバーアドレス未設定時 |
| MSG-003 | 情報 | L10().serverConnecting | サーバー接続中 |
| MSG-004 | 情報 | L10().profileSelectOrCreate | プロファイル選択を促す |
| MSG-005 | 警告 | L10().permissionRequired | 権限不足でタイルをタップした時 |

## 例外処理

| 例外種別 | 発生条件 | 対応処理 |
|---------|---------|---------|
| サーバー未接続 | InvenTreeAPI().isConnected() == false | 接続ステータスウィジェットを表示し、タイルナビゲーションを無効化 |
| 権限不足 | InvenTreeAPI().checkRole()がfalse | SnackBarで「権限が必要です」メッセージを表示 |
| プロファイル未選択 | _profile == null | サーバー選択画面への遷移を促す |

## 備考

- 画面サイズに応じてタイルのレイアウトが動的に変更される（smallScreen判定）
- サーバー接続状態はAPIのコールバック機構により自動的に更新される
- BottomAppBarはサーバー接続時のみ表示される

---

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

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

### 推奨読解順序

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

まず、画面で使用されるデータ構造を理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | user_profile.dart | `lib/user_profile.dart` | UserProfileクラスの構造（name, server, token, selected）を理解する |
| 1-2 | preferences.dart | `lib/preferences.dart` | 設定キー定数（INV_HOME_SHOW_*）とInvenTreeSettingsManagerの使い方を理解する |

**読解のコツ**: FlutterのSembastデータベースを使用しているため、StoreRefとDatabaseの関係を把握しておくとよい。

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

処理の起点となるファイル・関数を特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | home.dart | `lib/widget/home.dart` | InvenTreeHomePageとその状態クラス_InvenTreeHomePageStateを理解する |

**主要処理フロー**:
1. **行39-53**: コンストラクタで`_loadSettings()`と`_loadProfile()`を呼び出し、APIコールバックを登録
2. **行173-205**: `_loadSettings()`でホーム画面表示設定を非同期で読み込み
3. **行207-223**: `_loadProfile()`で選択中プロファイルを読み込み、サーバー接続を試行
4. **行277-407**: `getListTiles()`でユーザー権限と設定に基づいてナビゲーションタイルを構築
5. **行458-483**: `getBody()`でサーバー接続状態に応じたUI（接続ステータスまたはタイルグリッド）を返す
6. **行485-538**: `build()`でScaffold全体を構築

#### Step 3: API連携層を理解する

サーバーとの通信を担当するファイルを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | api.dart | `lib/api.dart` | InvenTreeAPIクラスのシングルトンパターン、接続管理（isConnected, isConnecting）、権限チェック（checkRole）を理解する |

**主要処理フロー**:
- **行171-179**: シングルトンパターンの実装
- **行391-397**: isConnected(), isConnecting()による接続状態判定
- **行763-807**: checkRole()による権限チェックロジック

#### Step 4: 画面遷移先を理解する

ホーム画面から遷移する各画面のWidgetを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | category_display.dart | `lib/widget/part/category_display.dart` | 部品カテゴリ画面の構造 |
| 4-2 | location_display.dart | `lib/widget/stock/location_display.dart` | 在庫ロケーション画面の構造 |
| 4-3 | purchase_order_list.dart | `lib/widget/order/purchase_order_list.dart` | 購入注文一覧画面の構造 |
| 4-4 | sales_order_list.dart | `lib/widget/order/sales_order_list.dart` | 販売注文一覧画面の構造 |
| 4-5 | company_list.dart | `lib/widget/company/company_list.dart` | 会社一覧画面の構造 |
| 4-6 | select_server.dart | `lib/settings/select_server.dart` | サーバー選択画面の構造 |

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

```
InvenTreeHomePage (home.dart)
    |
    +-- _InvenTreeHomePageState
            |
            +-- _loadSettings() --> InvenTreeSettingsManager.getValue()
            |                            |
            |                            +-- InvenTreePreferencesDB.database
            |
            +-- _loadProfile() --> UserProfileDBManager.getSelectedProfile()
            |                           |
            |                           +-- InvenTreeAPI().connectToServer()
            |
            +-- build()
                    |
                    +-- getBody()
                    |       |
                    |       +-- _connectionStatusWidget() [未接続時]
                    |       |
                    |       +-- getListTiles() [接続時]
                    |               |
                    |               +-- _listTile() x N
                    |
                    +-- InvenTreeDrawer()
                    |
                    +-- buildBottomAppBar()
```

### データフロー図

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

UserProfile (DB)       -->  _loadProfile()                  -->  _profile変数
                                |
                                v
                        InvenTreeAPI.connectToServer()      -->  接続状態更新
                                |
                                v
Settings (DB)          -->  _loadSettings()                 -->  homeShow*変数
                                |
                                v
User Roles (API)       -->  InvenTreeAPI.checkRole()        -->  タイル表示可否
                                |
                                v
                        build() / getBody()                 -->  UI描画
                                |
                                v
                        [タイルタップ]                       -->  Navigator.push()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| home.dart | `lib/widget/home.dart` | ソース | ホーム画面のメインWidget |
| drawer.dart | `lib/widget/drawer.dart` | ソース | ドロワーメニューWidget |
| api.dart | `lib/api.dart` | ソース | API通信・接続管理 |
| user_profile.dart | `lib/user_profile.dart` | ソース | ユーザープロファイル管理 |
| preferences.dart | `lib/preferences.dart` | ソース | 設定管理 |
| refreshable_state.dart | `lib/widget/refreshable_state.dart` | ソース | BaseWidgetPropertiesミックスイン |
| app_colors.dart | `lib/app_colors.dart` | ソース | アプリカラー定義 |
| l10.dart | `lib/l10.dart` | ソース | 多言語対応 |
| category_display.dart | `lib/widget/part/category_display.dart` | ソース | 部品カテゴリ画面（遷移先） |
| location_display.dart | `lib/widget/stock/location_display.dart` | ソース | 在庫ロケーション画面（遷移先） |
| purchase_order_list.dart | `lib/widget/order/purchase_order_list.dart` | ソース | 購入注文一覧画面（遷移先） |
| sales_order_list.dart | `lib/widget/order/sales_order_list.dart` | ソース | 販売注文一覧画面（遷移先） |
| company_list.dart | `lib/widget/company/company_list.dart` | ソース | 会社一覧画面（遷移先） |
| select_server.dart | `lib/settings/select_server.dart` | ソース | サーバー選択画面（遷移先） |
