# 画面設計書 29-メンテナンスページ

## 概要

本ドキュメントは、Shopware 6 Storefrontのメンテナンスページの画面設計書である。システムがメンテナンスモードの際に表示されるページについて記載する。

### 本画面の処理概要

メンテナンスページは、販売チャネルがメンテナンスモードに設定されている際に、一般ユーザーに表示されるページである。

**業務上の目的・背景**：ECサイトの運用において、システム更新、データ移行、セキュリティパッチ適用などの理由でサイトを一時的に停止する必要がある。メンテナンスページにより、ユーザーにサイトが一時的に利用できない旨を適切に伝え、再訪問を促すことができる。また、IPホワイトリスト機能により、管理者は自身のIPアドレスからメンテナンス中でもサイトにアクセスして動作確認が可能である。

**画面へのアクセス方法**：
- メンテナンスモード中に任意のURLにアクセス（自動リダイレクト）
- /maintenance への直接アクセス

**主要な操作・処理内容**：
1. メンテナンス中であることの表示
2. 30秒ごとの自動リロード（メンテナンス終了時の自動復帰）
3. 法的リンク（特商法表記、プライバシーポリシー）の表示

**画面遷移**：
- 遷移元：任意のページ（メンテナンスモード時）
- 遷移先：ホームページ（メンテナンス終了時）、特商法表記ページ、プライバシーポリシーページ

**権限による表示制御**：
- IPホワイトリストに登録されたIPアドレスからのアクセスはショップにリダイレクト
- 一般ユーザーはメンテナンスページを表示

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 68 | メンテナンスページ | 主機能 | メンテナンスモード中のページ表示（MaintenanceController::renderMaintenancePage） |

## 画面種別

エラー / メンテナンス

## URL/ルーティング

| ルート名 | URL | HTTPメソッド | 説明 |
|----------|-----|--------------|------|
| frontend.maintenance.page | /maintenance | GET | メンテナンスページ表示 |
| frontend.maintenance.singlepage | /maintenance/singlepage/{id} | GET | メンテナンス中の単独CMSページ表示 |

## 入出力項目

### 入力項目

| 項目名 | パラメータ名 | 型 | 必須 | 説明 |
|--------|-------------|-----|------|------|
| リクエスト | request | Request | 必須 | HTTPリクエスト |
| コンテキスト | context | SalesChannelContext | 必須 | 販売チャネルコンテキスト |
| CMSページID | id | string(UUID) | 条件付き | 単独CMSページ表示時のID |

### 出力項目

| 項目名 | 型 | 説明 |
|--------|-----|------|
| page | MaintenancePage | メンテナンスページオブジェクト（カスタムCMSページ設定時） |

## 表示項目

### デフォルトメンテナンスページ

| 項目名 | データソース | 説明 |
|--------|-------------|------|
| ロゴ | logo.html.twig | ショップロゴ |
| メンテナンス画像 | assets/illustration/maintenance_mode.svg | メンテナンス中イラスト |
| メンテナンスタイトル | general.maintenanceModeHeader | 「メンテナンス中」等 |
| メンテナンス説明 | general.maintenanceModeDescription | メンテナンスの説明文 |
| 特商法表記リンク | core.basicInformation.imprintPage | 特商法表記ページへのリンク |
| プライバシーポリシーリンク | core.basicInformation.privacyPage | プライバシーポリシーページへのリンク |

### カスタムメンテナンスページ

管理画面の「設定 > 基本設定 > メンテナンスページ」で設定されたCMSページを表示

## イベント仕様

### 1-メンテナンスページ表示

1. MaintenanceModeResolverでIPホワイトリストをチェック
2. ホワイトリストに含まれる場合はホームページにリダイレクト
3. core.basicInformation.maintenancePage設定を取得
4. 設定がある場合、MaintenancePageLoaderでCMSページを読み込み
5. 設定がない場合、デフォルトテンプレート（error-maintenance.html.twig）を使用

### 2-単独CMSページ表示

メンテナンスモード中でも法的ページ（特商法表記、プライバシーポリシー）にアクセスするための機能。指定されたCMSページIDでページを読み込み、single-cms-page.html.twigでレンダリング。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| なし | - | SELECT | 参照のみ（CMSページ取得） |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| general.maintenanceModeHeader | 表示 | メンテナンス中 | ページタイトル |
| general.maintenanceModeDescription | 表示 | 現在メンテナンス中です | メンテナンス説明 |
| general.imprintLink | 表示 | 特商法表記 | フッターリンク |
| general.privacyLink | 表示 | プライバシーポリシー | フッターリンク |
| general.noscriptNotice | 表示 | JavaScriptを有効にしてください | JS無効時 |

## 例外処理

| 例外 | 原因 | 処理内容 |
|------|------|----------|
| RoutingException::missingRequestParameter | CMSページIDがない | パラメータ不足エラー |
| PageNotFoundException | カスタムCMSページが存在しない | 例外スロー |

## 備考

- HTTPステータスコード503 (Service Temporarily Unavailable) を返却
- Retry-Afterヘッダーに3600秒（1時間）を設定
- 30秒ごとに自動リロードしてメンテナンス終了を検知
- IPホワイトリストヘッダー（sw-maintenance-whitelist-ips）を設定
- メンテナンスモード中でも特商法表記・プライバシーポリシーにアクセス可能
- HTTPキャッシュが有効（PlatformRequest::ATTRIBUTE_HTTP_CACHE => true）
- PlatformRequest::ATTRIBUTE_IS_ALLOWED_IN_MAINTENANCE => true でメンテナンス中も表示

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | MaintenancePage.php | `src/Storefront/Page/Maintenance/MaintenancePage.php` | cmsPageプロパティ |

**読解のコツ**: MaintenancePageはCMSページを持つことができ、カスタムメンテナンスページとして表示される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | MaintenanceController.php | `src/Storefront/Controller/MaintenanceController.php` | renderMaintenancePage(), renderSinglePage() |

**主要処理フロー**:
1. **38-46行**: ルート定義（/maintenance, GET, メンテナンス中アクセス許可、HTTPキャッシュ有効）
2. **49行**: MaintenanceModeResolverでリダイレクト判定
3. **54行**: ホワイトリストIPの場合、ホームページへリダイレクト
4. **58行**: カスタムメンテナンスページ設定の取得
5. **60-71行**: 設定がない場合、デフォルトテンプレートを使用
6. **73行**: MaintenancePageLoaderでCMSページを読み込み
7. **75行**: MaintenancePageLoadedHook実行
8. **77-80行**: テンプレートレンダリング
9. **82-83行**: 503ステータスコード、Retry-Afterヘッダー設定

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | MaintenancePageLoader.php | `src/Storefront/Page/Maintenance/MaintenancePageLoader.php` | load()メソッド |

**主要処理フロー**:
- **33-54行**: load() - CMSページを読み込み、MaintenancePageを作成
- **36行**: GenericPageLoaderで基本ページ情報を取得
- **39行**: SalesChannelCmsPageLoaderでCMSページを読み込み
- **48行**: MaintenancePageLoadedEventを発行

#### Step 4: テンプレートを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | error-maintenance.html.twig | `src/Storefront/Resources/views/storefront/page/error/error-maintenance.html.twig` | メンテナンスページテンプレート |
| 4-2 | single-cms-page.html.twig | `src/Storefront/Resources/views/storefront/page/content/single-cms-page.html.twig` | 単独CMSページ用 |

**テンプレート構造**:
- **1-14行**: DOCTYPE、HTML、meta情報
- **33-45行**: ヘッダー（ロゴのみ）
- **47-73行**: メインコンテンツ（カスタムCMSまたはフォールバック）
- **75-97行**: フッター（特商法表記、プライバシーポリシーリンク）
- **128-134行**: 30秒自動リロードスクリプト

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

```
MaintenanceController::renderMaintenancePage()
    │
    ├─ MaintenanceModeResolver::shouldRedirectToShop()
    │      │
    │      └─ [IPホワイトリスト判定]
    │
    ├─ [リダイレクト判定]
    │      │
    │      └─ redirectToRoute('frontend.home.page')
    │
    ├─ systemConfigService.getString('core.basicInformation.maintenancePage')
    │
    ├─ [カスタムメンテナンスページ設定あり]
    │      │
    │      ├─ MaintenancePageLoader::load()
    │      │      ├─ GenericPageLoader::load()
    │      │      ├─ SalesChannelCmsPageLoader::load()
    │      │      └─ MaintenancePageLoadedEvent dispatch
    │      │
    │      └─ MaintenancePageLoadedHook dispatch
    │
    ├─ renderStorefront('error-maintenance.html.twig')
    │
    ├─ setStatusCode(503)
    │
    └─ addWhitelistIpHeader()
```

### データフロー図

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

Request
         │
         ▼
 MaintenanceController::renderMaintenancePage()
         │
         ├─► MaintenanceModeResolver
         │         │
         │         └─► shouldRedirectToShop = true/false
         │                   │
         │                   ├─► [true] → redirect to frontend.home.page
         │                   │
         │                   └─► [false] → continue
         │
         ├─► systemConfigService.getString('core.basicInformation.maintenancePage')
         │         │
         │         └─► maintenanceLayoutId
         │
         ├─► [maintenanceLayoutId あり]
         │         │
         │         ▼
         │    MaintenancePageLoader::load()
         │         │
         │         ├─► GenericPageLoader
         │         │
         │         └─► CmsPageLoader
         │                   │
         │                   └─► MaintenancePage + CmsPage
         │                            │
         │                            ▼
         │                       error-maintenance.html.twig
         │                            (with CMSコンテンツ)
         │
         └─► [maintenanceLayoutId なし]
                   │
                   ▼
              error-maintenance.html.twig
                   (with フォールバックコンテンツ)
                            │
                            ▼
                       Response (status=503)
                       Retry-After: 3600
                       sw-maintenance-whitelist-ips: xxx
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| MaintenanceController.php | `src/Storefront/Controller/MaintenanceController.php` | コントローラー | メンテナンスページ処理 |
| MaintenancePageLoader.php | `src/Storefront/Page/Maintenance/MaintenancePageLoader.php` | ページローダー | CMSページ読み込み |
| MaintenancePage.php | `src/Storefront/Page/Maintenance/MaintenancePage.php` | ページエンティティ | メンテナンスページデータ |
| MaintenanceModeResolver.php | `src/Storefront/Framework/Routing/MaintenanceModeResolver.php` | サービス | メンテナンスモード判定 |
| error-maintenance.html.twig | `src/Storefront/Resources/views/storefront/page/error/error-maintenance.html.twig` | テンプレート | メンテナンスページ |
| single-cms-page.html.twig | `src/Storefront/Resources/views/storefront/page/content/single-cms-page.html.twig` | テンプレート | 単独CMSページ |
| logo.html.twig | `src/Storefront/Resources/views/storefront/layout/header/logo.html.twig` | テンプレート | ロゴ表示 |
