# 機能設計書 11-アカウント概要

## 概要

本ドキュメントは、Shopwareストアフロントにおける「アカウント概要」機能の設計内容を記載する。顧客がログイン後に自身のアカウント情報、最新注文、ニュースレター設定状況を確認できるマイアカウントのダッシュボードページを表示する機能である。

### 本機能の処理概要

**業務上の目的・背景**：ECサイトにおいて、顧客が自身のアカウント状態を一目で把握できるダッシュボード機能は必須である。本機能は、顧客がログイン直後に自分の基本情報、最新の注文履歴、デフォルトの請求先・配送先住所、ニュースレター購読状況を確認できるようにすることで、顧客体験を向上させ、各種設定画面への導線を提供する。

**機能の利用シーン**：
- 顧客がログイン後、最初に表示されるマイアカウントページとして利用
- 顧客が自身の登録情報を確認したい場合
- 最新の注文状況を素早く確認したい場合
- 各種設定ページ（プロフィール編集、住所管理、注文履歴等）へのハブとして利用

**主要な処理内容**：
1. ログイン認証の確認とセッションからの顧客情報取得
2. 顧客の詳細情報（デフォルト住所含む）の取得
3. 最新注文1件の取得（関連情報含む）
4. ニュースレター購読状況の取得
5. ページオブジェクトの構築とテンプレートレンダリング

**関連システム・外部連携**：Store API（AbstractCustomerRoute、AbstractOrderRoute）を経由してデータを取得。直接リポジトリアクセスは行わない。

**権限による制御**：ログイン必須（`LOGIN_REQUIRED`属性）。ゲストユーザーはアクセス不可。管理者によるなりすましログイン時も同様に表示される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 16 | アカウントホームページ | 主画面 | マイアカウントダッシュボードの表示 |
| 31 | ダッシュボード | 参照画面 | 管理者用ダッシュボードとの関連 |
| 39 | 顧客一覧 | 参照画面 | 管理画面からの顧客情報参照 |

## 機能種別

データ参照 / ページ表示

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| request | Request | Yes | HTTPリクエストオブジェクト | なし |
| context | SalesChannelContext | Yes | 販売チャネルコンテキスト | ログイン顧客情報を含む |
| customer | CustomerEntity | Yes | ログイン中の顧客エンティティ | セッションから自動取得 |

### 入力データソース

- セッション情報（ログイン顧客情報）
- SalesChannelContextから取得される販売チャネル設定

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| page | AccountOverviewPage | ページオブジェクト（顧客情報、最新注文、ニュースレター設定を含む） |
| page.customer | CustomerEntity | 顧客詳細情報（requestedGroup、defaultBillingAddress、defaultShippingAddress含む） |
| page.newestOrder | OrderEntity\|null | 最新の注文情報（存在する場合） |
| page.newsletterAccountPagelet | NewsletterAccountPagelet | ニュースレター設定状態 |
| page.metaInformation | MetaInformation | SEOメタ情報（noindex,follow） |

### 出力先

- 画面表示（Twigテンプレート `@Storefront/storefront/page/account/index.html.twig`）

## 処理フロー

### 処理シーケンス

```
1. ルーティング処理
   └─ /account パスへのGETリクエストを受信、LOGIN_REQUIRED属性により認証確認

2. コントローラー処理 (AccountProfileController::index)
   └─ AccountOverviewPageLoaderを呼び出してページオブジェクトを構築

3. ページローダー処理 (AccountOverviewPageLoader::load)
   ├─ GenericPageLoaderで基本ページ情報を取得
   ├─ 顧客詳細情報を取得（住所情報含む）
   ├─ 最新注文を取得
   ├─ ニュースレター設定を取得
   └─ イベントをディスパッチ

4. レスポンス生成
   └─ Twigテンプレートをレンダリングして返却
```

### フローチャート

```mermaid
flowchart TD
    A[リクエスト受信 /account] --> B{ログイン済み?}
    B -->|No| C[ログイン画面へリダイレクト]
    B -->|Yes| D[AccountOverviewPageLoader::load]
    D --> E[GenericPageLoader::load]
    E --> F[loadCustomer - 顧客詳細取得]
    F --> G[loadNewestOrder - 最新注文取得]
    G --> H[newsletterAccountPageletLoader - NL設定取得]
    H --> I[AccountOverviewPageLoadedEvent発火]
    I --> J[AccountOverviewPageLoadedHook実行]
    J --> K[Twigテンプレートレンダリング]
    K --> L[レスポンス返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-11-01 | ログイン必須 | 未ログインユーザーはアクセス不可 | 全リクエスト |
| BR-11-02 | 最新注文表示 | 最新1件のみ表示 | 注文履歴がある場合 |
| BR-11-03 | キャッシュ無効 | NO_STORE属性によりキャッシュ対象外 | 全リクエスト |
| BR-11-04 | SEOインデックス除外 | robots: noindex,follow | 全ページ |

### 計算ロジック

特になし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 顧客情報取得 | customer | SELECT | 顧客詳細情報の取得 |
| 住所情報取得 | customer_address | SELECT | デフォルト請求先・配送先住所取得 |
| 注文情報取得 | order | SELECT | 最新注文1件の取得 |
| 注文明細取得 | order_line_item | SELECT | 注文に紐づく商品明細取得 |

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

#### customer

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | id, email, first_name, last_name, salutation_id, default_billing_address_id, default_shipping_address_id など | ログインユーザーのIDで検索 | requestedGroupアソシエーション含む |

#### order

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | 全フィールド | customer_idでフィルタ、order_date_time降順、LIMIT 1 | 多数のアソシエーション含む |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | CustomerNotLoggedInException | 未ログイン状態でアクセス | ログイン画面へリダイレクト |
| - | RoutingException | ルーティングエラー | エラーページ表示 |
| - | CategoryNotFoundException | カテゴリ情報取得失敗 | エラーページ表示 |

### リトライ仕様

特になし（読み取り専用処理）

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

読み取り専用のため、トランザクション制御なし

## パフォーマンス要件

- 最新注文は1件のみ取得（LIMIT 1）によるクエリ最適化
- 必要なアソシエーションのみ明示的に指定して取得

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

- LOGIN_REQUIRED属性によりログイン必須を強制
- NO_STORE属性によりブラウザキャッシュ無効化（機密情報保護）
- robots: noindex により検索エンジンからのインデックス除外

## 備考

- ゲストユーザー（guest=true）はアカウント概要にアクセスできない
- 管理者による顧客なりすましログイン時も同様の画面が表示される

---

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

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

### 推奨読解順序

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

ページオブジェクトの構造を理解することが最初のステップである。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | AccountOverviewPage.php | `src/Storefront/Page/Account/Overview/AccountOverviewPage.php` | ページオブジェクトのプロパティ（customer, newestOrder, newsletterAccountPagelet）を確認 |

**読解のコツ**: Shopwareのページクラスは`Page`基底クラスを継承し、各機能固有のデータをプロパティとして保持する。

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

コントローラーがリクエストを受け取り、ページローダーに処理を委譲する流れを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AccountProfileController.php | `src/Storefront/Controller/AccountProfileController.php` | indexメソッド（58-65行目）がエントリーポイント |

**主要処理フロー**:
1. **60行目**: `$this->overviewPageLoader->load($request, $context, $customer)` でページローダーを呼び出し
2. **62行目**: `$this->hook(new AccountOverviewPageLoadedHook($page, $context))` でフック実行
3. **64行目**: Twigテンプレートをレンダリングして返却

#### Step 3: ページローダーを理解する

データ取得とページ構築のロジックを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | AccountOverviewPageLoader.php | `src/Storefront/Page/Account/Overview/AccountOverviewPageLoader.php` | loadメソッド（51-73行目）の処理フローを確認 |

**主要処理フロー**:
- **53行目**: GenericPageLoaderで基本ページ情報取得
- **55-56行目**: AccountOverviewPageに変換し、顧客情報をセット
- **59-63行目**: 最新注文を取得してセット
- **65-67行目**: ニュースレター設定を取得
- **69-71行目**: ページロードイベントをディスパッチ

#### Step 4: Store APIルートを理解する

データ取得に使用されるStore APIルートを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | AbstractOrderRoute.php | `src/Core/Checkout/Order/SalesChannel/AbstractOrderRoute.php` | 注文取得APIの抽象定義 |
| 4-2 | AbstractCustomerRoute.php | `src/Core/Checkout/Customer/SalesChannel/AbstractCustomerRoute.php` | 顧客情報取得APIの抽象定義 |

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

```
AccountProfileController::index
    │
    ├─ AccountOverviewPageLoader::load
    │      ├─ GenericPageLoaderInterface::load
    │      ├─ loadCustomer (private)
    │      │      └─ AbstractCustomerRoute::load
    │      ├─ loadNewestOrder (private)
    │      │      └─ AbstractOrderRoute::load
    │      └─ NewsletterAccountPageletLoader::load
    │
    └─ AccountOverviewPageLoadedHook (フック実行)
```

### データフロー図

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

Request (GET /account)
        │
        ▼
SalesChannelContext ───▶ AccountProfileController::index
        │                         │
        ▼                         ▼
CustomerEntity ─────────▶ AccountOverviewPageLoader::load
                                  │
                    ┌─────────────┼─────────────┐
                    ▼             ▼             ▼
            CustomerRoute   OrderRoute   NewsletterPageletLoader
                    │             │             │
                    └─────────────┴─────────────┘
                                  │
                                  ▼
                         AccountOverviewPage
                                  │
                                  ▼
                         Twigテンプレート
                                  │
                                  ▼
                         HTMLレスポンス
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AccountProfileController.php | `src/Storefront/Controller/AccountProfileController.php` | コントローラー | HTTPリクエスト処理のエントリーポイント |
| AccountOverviewPageLoader.php | `src/Storefront/Page/Account/Overview/AccountOverviewPageLoader.php` | ページローダー | ページデータの構築ロジック |
| AccountOverviewPage.php | `src/Storefront/Page/Account/Overview/AccountOverviewPage.php` | ページモデル | ページデータを保持するオブジェクト |
| AccountOverviewPageLoadedEvent.php | `src/Storefront/Page/Account/Overview/AccountOverviewPageLoadedEvent.php` | イベント | ページロード完了イベント |
| AccountOverviewPageLoadedHook.php | `src/Storefront/Page/Account/Overview/AccountOverviewPageLoadedHook.php` | フック | アプリ/プラグイン用フック |
| index.html.twig | `src/Storefront/Resources/views/storefront/page/account/index.html.twig` | テンプレート | 画面表示用Twigテンプレート |
| AbstractCustomerRoute.php | `src/Core/Checkout/Customer/SalesChannel/AbstractCustomerRoute.php` | Store API | 顧客情報取得API |
| AbstractOrderRoute.php | `src/Core/Checkout/Order/SalesChannel/AbstractOrderRoute.php` | Store API | 注文情報取得API |
| NewsletterAccountPageletLoader.php | `src/Storefront/Pagelet/Newsletter/Account/NewsletterAccountPageletLoader.php` | ページレットローダー | ニュースレター設定取得 |
