# 機能設計書 31-Next.js統合

## 概要

本ドキュメントは、Payload CMSとNext.js App Routerの統合機能について記述する。この機能は、Payload CMSをNext.jsアプリケーション内で直接動作させ、管理画面のルーティング、認証、APIエンドポイントの処理を実現する統合レイヤーを提供する。

### 本機能の処理概要

**業務上の目的・背景**：現代のWebアプリケーションでは、CMSとフロントエンドフレームワークを密接に統合することで、開発効率とパフォーマンスを向上させることが求められている。Payload CMSはNext.js App Router内に直接インストールされることで、サーバーコンポーネント（RSC）を活用したパフォーマンス最適化と、シームレスなルーティング統合を実現する。これにより、別途CMSサーバーを立てる必要がなく、デプロイ構成が簡素化される。

**機能の利用シーン**：
- Next.jsアプリケーションにPayload CMSを組み込む際の初期設定
- 管理画面へのアクセス時のルーティング処理
- REST API/GraphQL APIエンドポイントへのリクエスト処理
- ユーザー認証（ログイン/ログアウト/トークンリフレッシュ）

**主要な処理内容**：
1. `withPayload`関数によるNext.js設定の拡張（webpack設定、外部パッケージ、ヘッダー設定）
2. RootLayoutによる管理画面全体のレイアウト提供（テーマ、言語、権限、プロバイダー）
3. RootPageによる各管理画面ビューへのルーティングと認証制御
4. REST/GraphQL APIハンドラーの提供
5. 認証関連サーバーアクション（login, logout, refresh）の提供

**関連システム・外部連携**：
- Next.js App Router（ルーティング、Server Components）
- @payloadcms/ui（管理画面UIコンポーネント）
- @payloadcms/graphql（GraphQL API）
- データベースアダプター（MongoDB、PostgreSQL、SQLiteなど）

**権限による制御**：
- `permissions.canAccessAdmin`による管理画面アクセス制御
- 認証されていないユーザーはログイン画面にリダイレクト
- 初回ユーザー作成画面は未登録時のみアクセス可能
- 各コレクション/グローバルに対するCRUD権限チェック

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | ログイン画面 | 補助機能 | リダイレクト処理、ルーティング |
| 2 | ログアウト画面 | 補助機能 | ログアウト後のリダイレクト処理 |
| 18 | 404エラー画面 | 補助機能 | Next.jsのnotFound処理との統合 |

## 機能種別

フレームワーク統合 / ルーティング / 認証処理 / API提供

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| configPromise | Promise<SanitizedConfig> | Yes | Payload設定のPromise | 有効な設定オブジェクト |
| importMap | ImportMap | Yes | コンポーネントのインポートマップ | - |
| params.segments | string[] | No | URLセグメント配列 | - |
| searchParams | Record<string, string \| string[]> | No | クエリパラメータ | - |

### 入力データソース

- Next.js App Routerからのルートパラメータ
- クライアントからのHTTPリクエスト
- Cookieに格納された認証トークン
- Payload設定ファイル（payload.config.ts）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| JSX.Element | React.ReactNode | レンダリングされた管理画面コンポーネント |
| Response | Response | APIレスポンス（REST/GraphQL） |
| redirect | never | リダイレクト処理 |
| notFound | never | 404処理 |

### 出力先

- ブラウザ（管理画面HTML）
- HTTPレスポンス（API応答）
- Cookie（認証トークン）

## 処理フロー

### 処理シーケンス

```
1. withPayload (Next.js設定拡張)
   └─ Next.js configにPayload用設定をマージ
   └─ webpack外部パッケージ設定
   └─ ヘッダー設定（テーマ、キャッシュ）

2. RootLayout (管理画面レイアウト初期化)
   └─ 依存関係チェック (checkDependencies)
   └─ リクエスト初期化 (initReq)
   └─ テーマ・言語設定取得
   └─ RootProvider設置

3. RootPage (ページルーティング)
   └─ URLセグメント解析
   └─ コレクション/グローバル判定
   └─ 認証・権限チェック
   └─ 適切なビューコンポーネント選択
   └─ テンプレート適用（Default/Minimal）

4. REST/GraphQL API
   └─ リクエスト受信
   └─ handleEndpoints呼び出し
   └─ レスポンス返却
```

### フローチャート

```mermaid
flowchart TD
    A[リクエスト受信] --> B{APIリクエスト?}
    B -->|Yes| C[REST/GraphQL Handler]
    C --> D[handleEndpoints]
    D --> E[Response返却]

    B -->|No| F[RootPage]
    F --> G[URLセグメント解析]
    G --> H{認証済み?}
    H -->|No| I{公開ルート?}
    I -->|Yes| J[ビュー表示]
    I -->|No| K[ログインリダイレクト]

    H -->|Yes| L{権限あり?}
    L -->|No| M[権限エラー画面]
    L -->|Yes| N{ルート判定}

    N -->|collections| O[コレクションビュー]
    N -->|globals| P[グローバルビュー]
    N -->|custom| Q[カスタムビュー]
    N -->|default| R[ダッシュボード]

    O --> S[テンプレート適用]
    P --> S
    Q --> S
    R --> S
    S --> T[HTML返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 初回ユーザーリダイレクト | DBにユーザーが存在しない場合、初回ユーザー作成画面にリダイレクト | ユーザーコレクションが空 |
| BR-02 | 認証リダイレクト | 認証されていない場合、ログイン画面にリダイレクト | 非公開ルートへのアクセス |
| BR-03 | ロケールフィルタリング | ユーザー権限に応じてアクセス可能なロケールをフィルタリング | 多言語設定有効時 |
| BR-04 | テーマ継承 | ブラウザ設定またはCookieからテーマを継承 | 管理画面表示時 |

### 計算ロジック

特になし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| ユーザー存在確認 | {userSlug}コレクション | SELECT | 初回ユーザー作成判定 |
| プリファレンス取得 | payload-preferences | SELECT | コレクション表示設定 |

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

#### {userSlug}コレクション（users等）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | - | LIMIT 1 | ユーザー存在確認のみ |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 404 | Not Found | 存在しないルートへのアクセス | notFound()呼び出し |
| - | Redirect | 権限なしでのアクセス | ログイン画面へリダイレクト |
| - | Redirect | 無効なロケール指定 | 有効なロケールへリダイレクト |

### リトライ仕様

特になし（リアルタイム処理のため）

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

- ページ表示処理はトランザクション不要（読み取り専用）
- API処理はPayload本体のトランザクション管理に委譲

## パフォーマンス要件

- 開発モードでのサーバーパッケージ外部化によるコンパイル高速化
- React Server Componentsの活用によるクライアントバンドルサイズ削減
- 適切なキャッシュヘッダー設定

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

- JWT認証トークンのCookie管理
- 権限チェックによるアクセス制御
- CSRFトークン検証（該当時）
- X-Powered-Byヘッダーの制御

## 備考

- Turbopackビルドのサポート（Next.js 15以降の特定バージョン）
- Sass deprecation警告の抑制処理

---

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

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

### 推奨読解順序

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

まず、設定とリクエストの型定義を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | exports/utilities.ts | `packages/next/src/exports/utilities.ts` | エクスポートされるユーティリティ関数の一覧 |
| 1-2 | types (payload) | `packages/payload/src/config/types.ts` | SanitizedConfig型の構造 |

**読解のコツ**: Next.js統合では、Payload本体の`SanitizedConfig`型が中心となる。この型がどのようにNext.js側で利用されるかを把握する。

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

withPayload関数がNext.js設定を拡張する起点。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | withPayload.js | `packages/next/src/withPayload/withPayload.js` | Next.js config拡張の仕組み |

**主要処理フロー**:
1. **23行目**: withPayload関数の定義開始
2. **24-26行目**: Next.jsバージョン取得とTurbopack対応判定
3. **57-249行目**: baseConfig構築（sassOptions、webpack、headers等）
4. **256-273行目**: Turbopack対応/非対応での分岐

#### Step 3: レイアウト層を理解する

RootLayoutが管理画面全体のコンテキストを提供。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Root/index.tsx (layouts) | `packages/next/src/layouts/Root/index.tsx` | RootLayoutの実装 |
| 3-2 | initReq.ts | `packages/next/src/utilities/initReq.ts` | リクエスト初期化処理 |

**主要処理フロー**:
- **24-36行目**: RootLayoutのprops定義
- **39-48行目**: initReqによる認証・言語・権限の初期化
- **50-58行目**: テーマと言語方向（RTL/LTR）の決定
- **94-144行目**: HTMLレンダリングとRootProvider設置

#### Step 4: ページルーティングを理解する

RootPageがURLに基づいて適切なビューを選択。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Root/index.tsx (views) | `packages/next/src/views/Root/index.tsx` | RootPageの実装 |
| 4-2 | getRouteData.ts | `packages/next/src/views/Root/getRouteData.ts` | ルートデータ取得 |

**主要処理フロー**:
- **39-53行目**: RootPageのprops定義
- **65-96行目**: URLセグメント解析とコレクション/グローバル判定
- **146-159行目**: 認証・権限チェックとリダイレクト処理
- **178-196行目**: getRouteDataによるビュー情報取得
- **281-328行目**: RenderServerComponentによるビュー描画

#### Step 5: APIハンドラーを理解する

REST/GraphQL APIのエントリーポイント。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | routes/rest/index.ts | `packages/next/src/routes/rest/index.ts` | REST APIハンドラー |
| 5-2 | routes/graphql/index.ts | `packages/next/src/routes/graphql/index.ts` | GraphQL APIハンドラー |

**主要処理フロー**:
- **8-46行目** (rest): handlerBuilder関数によるHTTPメソッドハンドラー生成
- **36-43行目** (rest): handleEndpointsへの委譲

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

```
withPayload (next.config.js)
    │
    └─ Next.js Buildプロセス
           │
           ├─ RootLayout (layouts/Root/index.tsx)
           │      ├─ checkDependencies
           │      ├─ initReq
           │      ├─ getRequestTheme
           │      ├─ getNavPrefs
           │      └─ RootProvider
           │
           ├─ RootPage (views/Root/index.tsx)
           │      ├─ getCustomViewByRoute
           │      ├─ initReq
           │      ├─ handleAuthRedirect
           │      ├─ getPreferences
           │      ├─ getRouteData
           │      └─ RenderServerComponent
           │             └─ 各種ビューコンポーネント
           │
           └─ API Routes
                  ├─ REST Handler (routes/rest/index.ts)
                  │      └─ handleEndpoints (payload)
                  │
                  └─ GraphQL Handler (routes/graphql/index.ts)
                         └─ graphql-http
```

### データフロー図

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

HTTPリクエスト ─────▶ withPayload (設定拡張)
                            │
                            ▼
URLパラメータ ─────▶ RootPage (ルーティング)
Cookies ───────────▶       │
                            ├─▶ 認証チェック ────▶ リダイレクト
                            │
                            ├─▶ 権限チェック ────▶ 403/リダイレクト
                            │
                            └─▶ ビュー選択
                                   │
                                   ▼
                            テンプレート適用 ────▶ HTML Response


APIリクエスト ─────▶ REST/GraphQL Handler
                            │
                            ▼
                     handleEndpoints ─────▶ JSON Response
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.js | `packages/next/src/index.js` | ソース | パッケージエントリーポイント |
| withPayload.js | `packages/next/src/withPayload/withPayload.js` | ソース | Next.js設定拡張 |
| withPayloadLegacy.js | `packages/next/src/withPayload/withPayloadLegacy.js` | ソース | レガシーNext.js対応 |
| Root/index.tsx (layouts) | `packages/next/src/layouts/Root/index.tsx` | ソース | ルートレイアウト |
| Root/index.tsx (views) | `packages/next/src/views/Root/index.tsx` | ソース | ルートページ |
| initReq.ts | `packages/next/src/utilities/initReq.ts` | ソース | リクエスト初期化 |
| handleAuthRedirect.ts | `packages/next/src/utilities/handleAuthRedirect.ts` | ソース | 認証リダイレクト |
| getRouteData.ts | `packages/next/src/views/Root/getRouteData.ts` | ソース | ルートデータ取得 |
| rest/index.ts | `packages/next/src/routes/rest/index.ts` | ソース | REST APIハンドラー |
| graphql/index.ts | `packages/next/src/routes/graphql/index.ts` | ソース | GraphQL APIハンドラー |
| login.ts | `packages/next/src/auth/login.ts` | ソース | ログインサーバーアクション |
| logout.ts | `packages/next/src/auth/logout.ts` | ソース | ログアウトサーバーアクション |
| refresh.ts | `packages/next/src/auth/refresh.ts` | ソース | トークンリフレッシュ |
| package.json | `packages/next/package.json` | 設定 | パッケージ定義 |
