# 機能設計書 5-ログアウト

## 概要

本ドキュメントは、ECモバイルアプリケーションにおけるログアウト機能の設計仕様を定義する。ログイン中のユーザーがセッションを終了し、未ログイン状態に戻る機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：ユーザーが共有デバイスを使用する場合や、セキュリティ上の理由でセッションを終了したい場合に、明示的にログアウトできる手段を提供する。ログアウト後は個人情報へのアクセスが制限され、アカウントのセキュリティが確保される。

**機能の利用シーン**：ドロワーメニューの「ログアウト」ボタンをタップした際に利用される。ログアウト確認ダイアログで「OK」を選択すると、ログアウト処理が実行される。

**主要な処理内容**：
1. ログアウト確認ダイアログの表示
2. GraphQL APIを通じたログアウトリクエスト（バックエンドでトークン無効化）
3. SharedPreferencesからの顧客情報クリア
4. アプリ状態のリセット
5. サインイン画面への遷移

**関連システム・外部連携**：Bagisto（Laravel製ECプラットフォーム）のGraphQL APIと連携し、customerLogout mutationを呼び出す。

**権限による制御**：本機能はログイン済みユーザーのみ利用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 3 | ドロワー | 主画面 | ログアウトボタンの配置、ログアウト確認ダイアログ |
| 4 | サインイン画面 | 遷移先画面 | ログアウト成功後の遷移先 |

## 機能種別

認証処理 / API連携 / データ削除 / セッション管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| - | - | - | 入力パラメータなし（認証トークンはヘッダーで送信） | - |

### 入力データソース

- 認証トークン：SharedPreferencesに保存されたcustomerTokenをAPIリクエストヘッダーに自動付与

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| success | bool | ログアウト成功フラグ |
| message | String | 処理結果メッセージ |

### 出力先

- SharedPreferences：顧客情報のクリア
- 画面遷移：サインイン画面へ遷移

## 処理フロー

### 処理シーケンス

```
1. ユーザーがドロワーメニューの「ログアウト」をタップ
   └─ ログアウト確認ダイアログ表示

2. ユーザーが「OK」を選択
   └─ OnClickLogoutEventをHomePageBlocへ送信

3. HomePageBlocがHomePageRepositoryを通じてAPI呼び出し
   └─ repository!.callLogoutApi()

4. ApiClientがGraphQL mutationを実行
   └─ mutation.customerLogout()

5. レスポンス処理
   └─ 成功/失敗に関わらず次のステップへ

6. SharedPreferencesのクリア
   └─ appStoragePref.setCustomerLoggedIn(false)
   └─ appStoragePref.clearCustomerData()

7. カートカウントのリセット
   └─ GlobalData.cartCountController.sink.add(0)

8. サインイン画面への遷移
   └─ Navigator.of(context).pushNamed(signIn)

9. ドロワーを閉じる
   └─ Navigator.pop()
```

### フローチャート

```mermaid
flowchart TD
    A[ドロワーメニュー] --> B[ログアウトボタンタップ]
    B --> C[確認ダイアログ表示]
    C --> D{ユーザー選択}
    D -->|キャンセル| E[ドロワーに戻る]
    D -->|OK| F[GraphQL API呼び出し]
    F --> G[SharedPreferencesクリア]
    G --> H[カートカウントリセット]
    H --> I[サインイン画面へ遷移]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | ログアウト確認 | ログアウト前に確認ダイアログを表示 | ログアウトボタンタップ時 |
| BR-002 | トークン無効化 | バックエンド側でアクセストークンを無効化 | API呼び出し成功時 |
| BR-003 | ローカルデータクリア | SharedPreferencesから顧客情報をクリア | ログアウト処理時 |
| BR-004 | カートリセット | カートカウントを0にリセット | ログアウト処理時 |
| BR-005 | 画面遷移 | ログアウト後はサインイン画面へ遷移 | ログアウト処理完了後 |

### 計算ロジック

本機能に計算ロジックは存在しない。

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| トークン無効化 | oauth_access_tokens | DELETE/UPDATE | アクセストークンの削除または無効化 |

※上記はバックエンド側（Bagisto）での操作。

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

#### SharedPreferences（ローカルストレージ）

| 操作 | 項目（キー名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| WRITE | customerLoggedIn | false | ログイン状態フラグをfalseに |
| DELETE | customerName | クリア | 顧客名削除 |
| DELETE | customerEmail | クリア | 顧客メール削除 |
| DELETE | customerToken | クリア | 認証トークン削除 |
| DELETE | customerId | クリア | 顧客ID削除 |
| DELETE | customerImage | クリア | プロフィール画像URL削除 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | APIエラー | ログアウトAPI呼び出し失敗 | エラーを無視してローカルログアウト処理を続行 |
| - | ネットワークエラー | API通信失敗 | エラーを無視してローカルログアウト処理を続行 |

### リトライ仕様

本機能にリトライ処理は実装されていない。API呼び出しが失敗してもローカルのログアウト処理は続行される。

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

モバイルアプリ側ではトランザクション管理は行わない。ローカルデータのクリアは順次実行される。

## パフォーマンス要件

- API応答時間：3秒以内
- ローカル処理：即時完了

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

- バックエンドでアクセストークンを無効化し、再利用を防止
- ローカルに保存された認証情報（トークン、パスワード等）を確実にクリア
- ログアウト確認ダイアログで誤操作を防止

## 備考

- API呼び出しが失敗してもローカルのログアウト処理は実行される（オフライン対応）
- 指紋認証用に保存されたパスワードはログアウト時にクリアされない場合がある（要確認）

---

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

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

### 推奨読解順序

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

ドロワーメニューからのログアウト操作を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | drawer_list_view.dart | `lib/screens/drawer/view/drawer_list_view.dart` | ログアウトボタンとダイアログ表示 |

#### Step 2: リポジトリ層を理解する

API呼び出しの実装を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | home_page_repository.dart | `lib/screens/home_page/bloc/home_page_repository.dart` | callLogoutApiメソッド（72-82行目）でApiClientを呼び出し |

**主要処理フロー**:
- **73-81行目**: ApiClient().customerLogout()呼び出し、try-catchでエラーハンドリング

#### Step 3: API通信層を理解する

GraphQL通信の実装を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | api_client.dart | `lib/services/api_client.dart` | customerLogoutメソッド（719-737行目）でmutationを実行 |
| 3-2 | mutation_query.dart | `lib/services/mutation_query.dart` | customerLogoutメソッド（232-240行目）でGraphQL mutation文字列を生成 |

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

```
DrawerListView (View)
    │
    ├─ AlertDialog (確認ダイアログ)
    │
    ├─ HomePageRepository (Repository)
    │      │
    │      └─ ApiClient.customerLogout() (API Layer)
    │             │
    │             └─ GraphQlApiCalling (GraphQL Client)
    │                    │
    │                    └─ MutationsData.customerLogout() (Query Builder)
    │
    ├─ appStoragePref (Local Storage)
    │      └─ SharedPreferences.clear()
    │
    └─ Navigator (画面遷移)
```

### データフロー図

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

ログアウトボタン ───▶ DrawerListView
タップ                │
                     ▼
              確認ダイアログ ───▶ ユーザー確認
                     │
                     ▼
             HomePageRepository
                     │
                     ▼
                 ApiClient ───▶ GraphQL API
                     │                │
                     │                ▼
                     │         トークン無効化
                     │
                     ▼
              SharedPreferences ───▶ データクリア
                     │
                     ▼
              GlobalData.cartCount ───▶ 0にリセット
                     │
                     ▼
              Navigator.pushNamed(signIn)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| drawer_list_view.dart | `lib/screens/drawer/view/drawer_list_view.dart` | ソース | ドロワーメニューUI |
| home_page_repository.dart | `lib/screens/home_page/bloc/home_page_repository.dart` | ソース | リポジトリ層（ログアウトAPI呼び出し） |
| graphql_base_model.dart | `lib/data_model/graphql_base_model.dart` | ソース | 基本レスポンスモデル |
| api_client.dart | `lib/services/api_client.dart` | ソース | API通信クライアント |
| mutation_query.dart | `lib/services/mutation_query.dart` | ソース | GraphQLクエリ定義 |
| app_storage_pref.dart | `lib/utils/app_storage_pref.dart` | ソース | SharedPreferences管理 |
