# 機能設計書 15-サブカテゴリ表示

## 概要

本ドキュメントは、Eコマースモバイルアプリケーションにおけるサブカテゴリ表示機能の設計仕様を定義する。本機能は、ドロワーメニューやカテゴリ画面から選択した親カテゴリの配下にあるサブカテゴリを階層的に表示し、各サブカテゴリの商品一覧へのナビゲーションを提供する。

### 本機能の処理概要

**業務上の目的・背景**：
ECサイトにおいて、商品カテゴリは階層構造を持つことが一般的である。ユーザーが大分類から小分類へと段階的にカテゴリを絞り込めるようにすることで、目的の商品カテゴリへの効率的なアクセスを実現する。

**機能の利用シーン**：
- ドロワーメニューからカテゴリを選択した際
- ホーム画面のカテゴリセクションからカテゴリを選択した際
- カテゴリ商品一覧画面から親カテゴリに戻った際

**主要な処理内容**：
1. 親カテゴリIDを基にサブカテゴリ一覧を取得
2. サブカテゴリのグリッド/リスト表示
3. 各サブカテゴリの商品数表示
4. サブカテゴリから商品一覧画面への遷移
5. サブカテゴリ内商品のカート追加、ウィッシュリスト追加

**関連システム・外部連携**：
- Bagisto GraphQL API（カテゴリ情報取得、商品取得）

**権限による制御**：
- カテゴリ閲覧：認証不要
- ウィッシュリスト追加：ログイン必須
- 比較リスト追加：ログイン必須

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 8 | カテゴリ商品一覧画面 | 関連画面 | サブカテゴリ選択時の遷移先 |
| - | ドロワーサブカテゴリ画面 | 主画面 | サブカテゴリ一覧表示 |

## 機能種別

CRUD操作（Read）/ データ連携 / ナビゲーション

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| filters | List<Map<String, dynamic>> | Yes | カテゴリIDを含むフィルター | category_idフィールド必須 |
| page | int | No | ページ番号 | 1以上 |

### 入力データソース

- ドロワーメニュー（カテゴリ選択）
- ホーム画面カテゴリセクション
- GraphQL API（カテゴリ・商品データ）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| getCategoriesData | GetDrawerCategoriesData? | サブカテゴリ一覧 |
| categoriesData | NewProductsModel? | カテゴリ内商品一覧 |

### 出力先

- 画面表示（サブカテゴリグリッド、商品リスト）

## 処理フロー

### 処理シーケンス

```
1. 画面初期化（initState）
   └─ FetchDrawerSubCategoryEvent発行
2. サブカテゴリデータ取得
   └─ DrawerSubCategoryRepo.getDrawerSubCategories()
3. サブカテゴリ表示
   └─ ExpansionTileでサブカテゴリと商品を表示
4. 商品取得（オプション）
   └─ FetchCategoryProductsEventで商品一覧取得
5. ユーザーアクション
   ├─ サブカテゴリタップ：商品一覧画面へ遷移
   ├─ カート追加：AddToCartEvent発行
   └─ ウィッシュリスト追加：AddWishlistEvent発行
```

### フローチャート

```mermaid
flowchart TD
    A[ドロワー/カテゴリ画面] --> B[カテゴリ選択]
    B --> C[DrawerSubCategories画面表示]
    C --> D[FetchDrawerSubCategoryEvent発行]
    D --> E[API呼び出し]
    E --> F{成功?}
    F -->|Yes| G[サブカテゴリ表示]
    F -->|No| H[エラー表示]
    G --> I{ユーザー操作}
    I -->|サブカテゴリタップ| J[商品一覧画面へ遷移]
    I -->|商品カート追加| K[AddToCartEvent発行]
    I -->|ウィッシュリスト| L[AddWishlistEvent発行]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | ログイン要求 | ウィッシュリスト・比較リスト追加はログイン必須 | 非ログイン時 |
| BR-02 | 階層表示 | サブカテゴリはExpansionTileで展開表示 | 常時 |
| BR-03 | 商品プレビュー | サブカテゴリ展開時に先頭3商品を表示 | limit: 3 |

### 計算ロジック

特になし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| サブカテゴリ取得 | categories | SELECT | parent_id=指定カテゴリのサブカテゴリ取得 |
| 商品取得 | products | SELECT | category_id=指定カテゴリの商品取得（limit:3） |
| カート追加 | cart_items | INSERT | 商品をカートに追加 |
| ウィッシュリスト | wishlist_items | INSERT/DELETE | ウィッシュリスト操作 |

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

#### categories（GraphQL経由）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | 全フィールド | parent_id = 指定値 | GraphQL: homeCategories |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | API失敗 | カテゴリ取得エラー | FetchDrawerSubCategoryState.failでエラーメッセージ表示 |
| - | ログイン必須 | 非ログイン時のウィッシュリスト操作 | 警告メッセージ表示 |

### リトライ仕様

- Pull-to-Refresh対応

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

カート追加、ウィッシュリスト操作はバックエンドでトランザクション制御。

## パフォーマンス要件

- サブカテゴリ取得: 2秒以内
- 商品プレビュー: limit:3で高速化

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

- ウィッシュリスト操作はログイン状態確認

## 備考

- サブカテゴリはExpansionTileで展開表示
- 商品プレビューはlimit:3で取得

---

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

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

### 推奨読解順序

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

サブカテゴリ表示で扱うデータモデルを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | categories_data_model.dart | `lib/data_model/categories_data_model/categories_data_model.dart` | GetDrawerCategoriesData, HomeCategoriesの構造 |
| 1-2 | new_product_data.dart | `lib/screens/home_page/data_model/new_product_data.dart` | NewProductsModel（商品プレビュー用） |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | drawer_sub_categories.dart | `lib/screens/drawer_sub_categories/drawer_sub_categories.dart` | DrawerSubCategoriesクラス |

**主要処理フロー**:
1. **initState()**: FetchDrawerSubCategoryEvent発行
2. **BlocConsumer**: 状態監視とUI構築
3. **ExpansionTile**: サブカテゴリの展開表示
4. **商品グリッド**: 先頭3商品のプレビュー表示

#### Step 3: BLoC層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | drawer_sub_categories_bloc.dart | `lib/screens/drawer_sub_categories/bloc/drawer_sub_categories_bloc.dart` | イベント処理ロジック |
| 3-2 | drawer_sub_categories_repository.dart | `lib/screens/drawer_sub_categories/bloc/drawer_sub_categories_repository.dart` | API呼び出し |

**主要処理フロー（drawer_sub_categories_bloc.dart）**:
- **28-38行目**: FetchDrawerSubCategoryEventの処理
- **39-47行目**: FetchCategoryProductsEventの処理
- **48-64行目**: AddToCartEventの処理
- **65-79行目**: AddWishlistEventの処理
- **80-97行目**: RemoveWishlistItemEventの処理
- **98-113行目**: AddToCompareEventの処理

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

```
DrawerSubCategories (drawer_sub_categories.dart)
    │
    ├─ DrawerSubCategoriesBloc (bloc/drawer_sub_categories_bloc.dart)
    │      │
    │      └─ DrawerSubCategoryRepo (bloc/drawer_sub_categories_repository.dart)
    │             │
    │             ├─ ApiClient.homeCategories() → サブカテゴリ取得
    │             ├─ ApiClient.getAllProducts() → 商品取得（limit:3）
    │             ├─ ApiClient.addToCart() → カート追加
    │             ├─ ApiClient.addToWishlist() → ウィッシュリスト追加
    │             ├─ ApiClient.removeFromWishlist() → ウィッシュリスト削除
    │             └─ ApiClient.addToCompare() → 比較リスト追加
    │
    └─ ExpansionTile
           └─ GridView.builder (商品プレビュー)
```

### データフロー図

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

filters ────────────────▶ FetchDrawerSubCategoryEvent
(category_id)                 │
                              ▼
                         DrawerSubCategoryRepo.getDrawerSubCategories()
                              │
                              ▼
                         ApiClient.homeCategories()
                              │
                              ▼
                         GraphQL API
                              │
                              ▼
                         GetDrawerCategoriesData ───▶ サブカテゴリ表示

サブカテゴリ展開 ────────▶ FetchCategoryProductsEvent
                              │
                              ▼
                         DrawerSubCategoryRepo.callCategoriesData()
                              │
                              ▼
                         ApiClient.getAllProducts(limit: 3)
                              │
                              ▼
                         NewProductsModel ─────────▶ 商品プレビュー表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| drawer_sub_categories.dart | `lib/screens/drawer_sub_categories/drawer_sub_categories.dart` | ソース | サブカテゴリ画面UI |
| drawer_sub_categories_bloc.dart | `lib/screens/drawer_sub_categories/bloc/drawer_sub_categories_bloc.dart` | ソース | 状態管理BLoC |
| drawer_sub_categories_event.dart | `lib/screens/drawer_sub_categories/bloc/drawer_sub_categories_event.dart` | ソース | イベント定義 |
| drawer_sub_categories_state.dart | `lib/screens/drawer_sub_categories/bloc/drawer_sub_categories_state.dart` | ソース | 状態定義 |
| drawer_sub_categories_repository.dart | `lib/screens/drawer_sub_categories/bloc/drawer_sub_categories_repository.dart` | ソース | APIリポジトリ |
| categories_data_model.dart | `lib/data_model/categories_data_model/categories_data_model.dart` | ソース | カテゴリデータモデル |
