# 機能設計書 57-ホームページ表示

## 概要

本ドキュメントは、Shopware Storefrontにおける「ホームページ表示」機能の設計仕様を定義する。ECサイトのトップページ（ルートURL `/`）を表示し、CMSレイアウトで構成されたコンテンツを顧客に提供する。

### 本機能の処理概要

**業務上の目的・背景**：ECサイトのホームページは、顧客が最初にアクセスするエントリーポイントであり、ブランドイメージの訴求、主要商品の露出、各カテゴリへの誘導など、ECサイトの顔となる重要なページである。本機能は、Shopwareの柔軟なCMSシステムを活用して、管理画面で設計されたレイアウトをレンダリングし、動的なホームページを提供する。

**機能の利用シーン**：顧客がショップのルートURL（`/`）にアクセスした際に本機能が呼び出される。販売チャネルに設定されたナビゲーションカテゴリ（ルートカテゴリ）に紐付くCMSページが表示される。

**主要な処理内容**：
1. リクエストURLからホームページ表示と判定
2. 販売チャネルのナビゲーションカテゴリを取得
3. カテゴリに紐付くCMSページをロード
4. メタ情報（SEO）を設定
5. Canonicalタグを設定
6. NavigationPageLoadedEventイベント発火
7. CMSレイアウトをレンダリング

**関連システム・外部連携**：本機能は Store API の `CategoryRoute` を内部的に利用し、カテゴリとCMSページ情報を取得する。`NavigationPageLoadedEvent`イベントを発火し、プラグインによる拡張を可能にする。

**権限による制御**：本機能はログイン不要で利用可能。ただし、販売チャネルやカテゴリの公開設定、顧客グループによるアクセス制限が適用される場合がある。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | ホームページ | 主画面 | ショップトップページの表示 |

## 機能種別

ページ表示 / CMS連携 / SEO対応

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| p | int | No | ページネーション用ページ番号 | 正の整数 |

### 入力データソース

- URLパス: `/` （ルートURL）
- SalesChannelContext: 販売チャネル情報、顧客情報を含む

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| page | NavigationPage | ナビゲーションページオブジェクト（CMSPage含む） |

### 出力先

- HTTPレスポンス: Twigテンプレートによるページ表示
- HTTPキャッシュ対応

## 処理フロー

### 処理シーケンス

```
1. リクエスト受信
   └─ NavigationController::home が呼び出される

2. NavigationPageLoader::load 実行
   └─ GenericPageLoaderで共通ページ情報をロード
   └─ NavigationPageを作成

3. ナビゲーションID取得
   └─ リクエストから取得、なければ販売チャネルのナビゲーションカテゴリID

4. カテゴリ情報取得
   └─ CategoryRoute::load でカテゴリとCMSページを取得

5. アクティブ状態チェック
   └─ カテゴリが非アクティブの場合はCategoryNotFound例外

6. メタ情報設定
   └─ ホームページ用のメタ情報を設定
   └─ homeMetaDescription、homeMetaTitle、homeKeywordsを優先

7. CMSページ設定
   └─ カテゴリに紐付くCMSPageをページに設定

8. Canonical設定
   └─ ホームページはfrontend.home.pageのURLを使用
   └─ ページネーションがある場合は?p=パラメータを追加

9. イベント発火
   └─ NavigationPageLoadedEvent をディスパッチ

10. レスポンス返却
    └─ index.html.twig でCMSレイアウトをレンダリング
```

### フローチャート

```mermaid
flowchart TD
    A[開始: home呼び出し] --> B[NavigationPageLoader::load]
    B --> C[GenericPageLoader::load]
    C --> D[ナビゲーションIDを取得]
    D --> E[CategoryRoute::load]
    E --> F{カテゴリはアクティブ?}
    F -->|No| G[CategoryNotFound例外]
    F -->|Yes| H[メタ情報設定]
    H --> I{ホームページ?}
    I -->|Yes| J[homeMetaTitle/Description使用]
    I -->|No| K[カテゴリのメタ情報使用]
    J --> L[CMSページを設定]
    K --> L
    L --> M[Canonical URL設定]
    M --> N[NavigationPageLoadedEvent発火]
    N --> O[index.html.twigレンダリング]
    O --> P[終了]
    G --> Q[エラーページ表示]
    Q --> P
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-57-01 | ログイン不要 | ログインなしでアクセス可能 | 全リクエスト |
| BR-57-02 | HTTPキャッシュ有効 | HTTPキャッシュ属性が設定される | 全リクエスト |
| BR-57-03 | SEO有効 | SEOフレンドリーURLが適用される | 全リクエスト |
| BR-57-04 | ホームメタ情報優先 | 販売チャネルのhomeMetaTitle/Descriptionを優先使用 | ホームページ表示時 |
| BR-57-05 | アクティブカテゴリのみ | 非アクティブカテゴリはエラー | カテゴリ取得時 |

### 計算ロジック

- Canonical URL: `frontend.home.page` のSEO URL + ページネーションパラメータ

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| カテゴリ取得 | category | SELECT | ナビゲーションカテゴリを取得 |
| CMSページ取得 | cms_page | SELECT | カテゴリに紐付くCMSページを取得 |
| 翻訳取得 | category_translation, sales_channel_translation | SELECT | 翻訳情報取得 |

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

#### category

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | id, active, cms_page_id, meta_title, meta_description, keywords | id = ? | ナビゲーションカテゴリ取得 |

#### sales_channel

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | navigation_category_id, home_meta_title, home_meta_description, home_keywords | id = context.salesChannelId | ホームページ設定取得 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| CATEGORY_NOT_FOUND | カテゴリ未存在 | ナビゲーションカテゴリが存在しないまたは非アクティブ | 販売チャネル設定を確認 |

### リトライ仕様

特になし

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

- 読み取り専用のため、トランザクション管理は不要
- SELECTクエリのみ実行

## パフォーマンス要件

- レスポンス時間: 500ms以内（キャッシュヒット時は100ms以内）
- HTTPキャッシュ有効

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

- HTTPキャッシュが有効のため、ユーザー固有情報は含めない
- CSRFトークンはフォーム送信時のみ必要

## 備考

- CMSページはShopwareの管理画面で作成・編集可能
- ホームページのレイアウトは販売チャネルのナビゲーションカテゴリに紐付くCMSページで定義
- ESI（Edge Side Includes）対応により、ヘッダー/フッターは別途キャッシュ可能

---

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

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

### 推奨読解順序

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

まず、ナビゲーションページのデータ構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | NavigationPage.php | `src/Storefront/Page/Navigation/NavigationPage.php` | ページ構造。category、cmsPage、navigationIdプロパティを確認 |

**読解のコツ**: NavigationPageはPage基底クラスを継承し、header、footer、metaInformation等の共通プロパティを持つ。

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

処理の起点となるコントローラーを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | NavigationController.php | `src/Storefront/Controller/NavigationController.php` | Storefront側のエントリーポイント。homeメソッドがホームページ表示の入口 |

**主要処理フロー**:
1. **49-55行目**: homeメソッドのルート定義。GET `/`、SEO有効、HTTPキャッシュ有効
2. **56-63行目**: homeメソッドの実装
3. **58行目**: NavigationPageLoaderでページをロード
4. **60行目**: NavigationPageLoadedHookを発火
5. **62行目**: index.html.twigでレンダリング

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

実際のビジネスロジックはページローダーに実装されている。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | NavigationPageLoader.php | `src/Storefront/Page/Navigation/NavigationPageLoader.php` | ページ生成の核心ロジック |

**主要処理フロー**:
- **34-74行目**: loadメソッドの実装
- **36-37行目**: GenericPageLoaderで共通ページ情報をロード、NavigationPageに変換
- **39行目**: ナビゲーションIDを取得（リクエストから、なければ販売チャネル設定から）
- **41-43行目**: CategoryRouteでカテゴリとCMSページを取得
- **45-47行目**: カテゴリが非アクティブなら例外
- **49-50行目**: メタ情報を設定（loadMetaData）
- **51-55行目**: CMSページがあれば設定
- **57-67行目**: Canonical URLを設定
- **69-72行目**: イベント発火

#### Step 4: メタ情報設定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | NavigationPageLoader.php | `src/Storefront/Page/Navigation/NavigationPageLoader.php` | loadMetaDataメソッド |

**主要処理フロー**:
- **76-102行目**: loadMetaDataメソッド
- **84行目**: ホームページ判定（販売チャネルのナビゲーションカテゴリID == カテゴリID）
- **86-90行目**: ホームページの場合は販売チャネルのhomeMetaDescriptionを優先、なければカテゴリのメタ情報
- **92-96行目**: homeMetaTitleの処理も同様
- **98-101行目**: homeKeywordsの処理

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

```
NavigationController::home (Storefront)
    │
    └─ NavigationPageLoader::load
           │
           ├─ GenericPageLoader::load (共通ページ情報)
           │
           ├─ CategoryRoute::load (Store API)
           │      └─ CategoryEntity + CmsPage
           │
           ├─ loadMetaData (メタ情報設定)
           │
           ├─ SeoUrlReplacer::generate (Canonical URL生成)
           │
           └─ EventDispatcher::dispatch
                  └─ NavigationPageLoadedEvent
```

### データフロー図

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

Request (/') ──────────▶ NavigationController::home
                              │
SalesChannelContext ───────▶ │
                              ▼
                         NavigationPageLoader::load
                              │
                              ├─▶ category テーブル (SELECT)
                              │
                              ├─▶ cms_page テーブル (SELECT)
                              │
                              └─▶ sales_channel テーブル (SELECT - ホームメタ情報)
                                          │
                                          ▼
                                   Twigテンプレート ──────▶ ホームページHTML
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| NavigationController.php | `src/Storefront/Controller/NavigationController.php` | ソース | Storefrontコントローラー、エントリーポイント |
| NavigationPageLoader.php | `src/Storefront/Page/Navigation/NavigationPageLoader.php` | ソース | ページローダー、ビジネスロジック |
| NavigationPage.php | `src/Storefront/Page/Navigation/NavigationPage.php` | ソース | ページクラス |
| GenericPageLoader.php | `src/Storefront/Page/GenericPageLoader.php` | ソース | 共通ページローダー |
| CategoryRoute.php | `src/Core/Content/Category/SalesChannel/CategoryRoute.php` | ソース | カテゴリ取得ルート |
| NavigationPageLoadedEvent.php | `src/Storefront/Page/Navigation/NavigationPageLoadedEvent.php` | ソース | ページロードイベント |
| index.html.twig | `src/Storefront/Resources/views/storefront/page/content/index.html.twig` | テンプレート | コンテンツページテンプレート |
