# 画面設計書 10-ドキュメント編集画面

## 概要

本ドキュメントは、Payload CMSの管理画面におけるドキュメント編集画面の設計について記載する。コレクションのドキュメントを作成・編集するための画面であり、ライブプレビュー、ドラフト、オートセーブなどの高度な機能に対応している。

### 本画面の処理概要

本画面は、コレクションドキュメントの作成および編集を行う画面である。フォームベースのUIでフィールドを編集し、バージョン管理、ドラフト保存、ライブプレビュー、オートセーブなど、コンテンツ管理に必要な高度な機能を提供する。

**業務上の目的・背景**：コンテンツ編集者がドキュメントを効率的に作成・編集・管理できるインターフェースを提供する。ドラフト機能により、公開前のコンテンツを安全に編集でき、バージョン管理により変更履歴の追跡と復元が可能。ライブプレビュー機能により、編集中のコンテンツをリアルタイムで確認できる。オートセーブにより、編集内容の自動保存で作業の損失を防止する。複数ユーザーによる同時編集時のロック機能も提供。

**画面へのアクセス方法**：一覧画面からドキュメントをクリックする。または新規作成ボタンを押下する。URLパターンは `/admin/collections/{collectionSlug}/{docId}` または `/admin/collections/{collectionSlug}/create` となる。

**主要な操作・処理内容**：
1. 各フィールドに値を入力・編集
2. 保存ボタンでドキュメントを保存
3. 下書き保存でドラフトとして保存
4. 公開ボタンで本番公開
5. 削除ボタンでドキュメントを削除
6. 複製ボタンでドキュメントをコピー
7. ライブプレビューでリアルタイム確認
8. バージョン履歴で過去のバージョンを確認・復元

**画面遷移**：
- 遷移元：コレクション一覧画面、ダッシュボード画面
- 遷移先：バージョン一覧画面、APIビュー画面、コレクション一覧画面（削除後）

**権限による表示制御**：ユーザーの権限に基づいて、保存・公開・削除ボタンの表示が制御される。フィールドレベルの読み取り・書き込み権限により、各フィールドの表示・編集可否が決定される。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | コレクション管理 | 主機能 | ドキュメントの作成・更新・削除処理 |
| 3 | フィールドシステム | 主機能 | 各種フィールドタイプのレンダリングと入力処理 |
| 4 | バージョン管理 | 補助機能 | ドラフト保存、オートセーブ、バージョン履歴 |
| 32 | ライブプレビュー | 補助機能 | リアルタイムプレビュー機能（有効時） |
| 11 | REST API | API連携 | ドキュメント保存時のAPI呼び出し |
| 63 | アクセス制御 | API連携 | フィールドレベルの読み書き権限チェック |
| 64 | バリデーション | API連携 | フィールド値の検証処理 |
| 62 | フック機能 | API連携 | beforeChange、afterReadなどのフック実行 |
| 61 | プリファレンス | API連携 | ドキュメント編集プリファレンスの保存・読込 |

## 画面種別

編集（作成・更新）

## URL/ルーティング

- **URL（編集）**: `/admin/collections/{collectionSlug}/{docId}`
- **URL（新規）**: `/admin/collections/{collectionSlug}/create`
- **ルーティング定義**: `packages/next/src/routes/collections/document`
- **パスパラメータ**:
  - `collectionSlug` - コレクションのスラッグ
  - `docId` - ドキュメントID（編集時）

## 入出力項目

| 項目名 | 項目ID | 入出力区分 | データ型 | 必須 | 最大長 | 説明 |
|--------|--------|------------|----------|------|--------|------|
| フィールド群 | (動的) | 入力 | (設定依存) | 設定依存 | - | コレクション定義に基づくフィールド |
| ロケール | locale | 入力 | string | 任意 | - | 編集対象のロケール |

## 表示項目

| 項目名 | 表示位置 | データソース | 説明 |
|--------|----------|--------------|------|
| ドキュメントヘッダー | 上部 | DocumentHeader | タイトル、ステータス、アクション |
| 編集フォーム | メインエリア | RenderFields | フィールド編集UI |
| サイドバー | 右側 | - | メタ情報、アクション、ステータス |
| 保存ボタン | ヘッダー/サイドバー | - | ドキュメント保存 |
| 公開ボタン | ヘッダー/サイドバー | - | ドキュメント公開（drafts有効時） |
| 削除ボタン | ヘッダー/サイドバー | - | ドキュメント削除 |
| 複製ボタン | ヘッダー/サイドバー | - | ドキュメント複製 |
| バージョン履歴リンク | サイドバー | - | バージョン一覧へ |
| APIビューリンク | ヘッダー | - | APIレスポンス表示へ |
| ライブプレビュー | 右パネル/新規タブ | - | リアルタイムプレビュー |
| ロック状態表示 | ヘッダー | - | 他ユーザーによる編集中表示 |

## イベント仕様

### 1-保存ボタン押下

- **トリガー**: 保存ボタン押下
- **処理内容**:
  1. クライアントサイドバリデーション実行
  2. `POST /api/{collectionSlug}` または `PATCH /api/{collectionSlug}/{docId}` 送信
  3. サーバーサイドバリデーション実行
  4. beforeChangeフック実行
  5. データベースに保存
  6. afterChangeフック実行
  7. フォーム状態を更新
- **結果**: 保存成功メッセージを表示

### 2-公開ボタン押下

- **トリガー**: 公開ボタン押下（drafts有効時）
- **処理内容**:
  1. draft=falseでドキュメントを保存
  2. バージョンを作成（versions有効時）
- **結果**: 公開成功メッセージを表示

### 3-削除ボタン押下

- **トリガー**: 削除ボタン押下
- **処理内容**:
  1. 確認ダイアログを表示
  2. `DELETE /api/{collectionSlug}/{docId}` 送信
  3. beforeDeleteフック実行
  4. データベースから削除（またはソフトデリート）
  5. afterDeleteフック実行
  6. 一覧画面へリダイレクト
- **結果**: 一覧画面へ遷移

### 4-複製ボタン押下

- **トリガー**: 複製ボタン押下
- **処理内容**:
  1. 現在のドキュメントデータをコピー
  2. 新規作成画面へ遷移（データをプリフィル）
- **遷移先**: 新規作成画面（プリフィルあり）

### 5-フィールド変更（オートセーブ有効時）

- **トリガー**: フィールド値の変更
- **処理内容**:
  1. デバウンス後にオートセーブ実行
  2. ドラフトとして自動保存
- **結果**: オートセーブ完了の表示

### 6-バージョン履歴リンク押下

- **トリガー**: バージョン履歴リンク押下
- **処理内容**: バージョン一覧画面へ遷移
- **遷移先**: バージョン一覧画面

### 7-APIビューリンク押下

- **トリガー**: APIビューリンク押下
- **処理内容**: APIビュー画面へ遷移
- **遷移先**: APIビュー画面

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 画面表示 | {collectionSlug} | SELECT | ドキュメントデータ取得 |
| 保存ボタン押下（新規） | {collectionSlug} | INSERT | 新規ドキュメント作成 |
| 保存ボタン押下（更新） | {collectionSlug} | UPDATE | ドキュメント更新 |
| 公開ボタン押下 | {collectionSlug} | UPDATE | ステータス更新 |
| 公開ボタン押下 | {collectionSlug}_versions | INSERT | バージョン作成 |
| 削除ボタン押下 | {collectionSlug} | DELETE/UPDATE | 削除またはソフトデリート |
| オートセーブ | {collectionSlug} | UPDATE | ドラフト更新 |
| プリファレンス保存 | payload-preferences | UPDATE/INSERT | 編集設定保存 |

### テーブル別更新項目詳細

#### {collectionSlug}

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | * | IDで検索 | ドキュメント取得 |
| INSERT | * | フォーム入力値 | 新規作成 |
| UPDATE | * | フォーム入力値 | 更新 |
| UPDATE | _status | 'published' | 公開時 |
| UPDATE | updatedAt | 現在時刻 | 更新日時 |
| DELETE | - | IDで削除 | 削除 |

#### {collectionSlug}_versions

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | parent | ドキュメントID | 親ドキュメント参照 |
| INSERT | version | スナップショット | バージョンデータ |
| INSERT | createdAt | 現在時刻 | 作成日時 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| - | 成功 | ドキュメントを保存しました | 保存成功時 |
| - | 成功 | ドキュメントを公開しました | 公開成功時 |
| - | 成功 | ドキュメントを削除しました | 削除成功時 |
| - | 成功 | ドキュメントを複製しました | 複製成功時 |
| - | 確認 | ドキュメントを削除しますか？ | 削除確認 |
| - | 警告 | 未保存の変更があります | 離脱時 |
| - | 情報 | 他のユーザーが編集中です | ロック時 |
| - | 情報 | オートセーブしました | オートセーブ完了時 |
| - | エラー | バリデーションエラー | バリデーション失敗時 |

## 例外処理

| 例外状況 | 処理内容 |
|----------|---------|
| ドキュメントが存在しない | 一覧画面へリダイレクト（notFoundパラメータ付き） |
| 編集権限なし | 読み取り専用で表示 |
| ロック中 | 読み取り専用で表示、ロック情報を表示 |
| バリデーションエラー | エラーフィールドをハイライト、エラーメッセージ表示 |
| 保存失敗 | エラーメッセージを表示、フォーム状態を維持 |
| ネットワークエラー | エラーメッセージを表示 |
| ゴミ箱のドキュメント | 読み取り専用で表示、復元オプションを表示 |

## 備考

- `hasDraftsEnabled`でドラフト機能の有効/無効を判定
- `hasAutosaveEnabled`でオートセーブ機能の有効/無効を判定
- `isLocked`でドキュメントのロック状態を判定
- `isTrashed`で削除済みドキュメントを判定
- ライブプレビューはcollectionConfigまたはglobalConfigで設定
- Drawerモードでの表示にも対応
- isolateObjectPropertyでトランザクション競合を防止

---

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

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

### 推奨読解順序

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

まず、ドキュメント編集で使用されるデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | FormState | `packages/payload/src/admin/forms/Form.ts` | フォーム状態の構造 |
| 1-2 | DocumentViewServerProps | `packages/payload/src/admin/types.ts` | サーバーpropsの構造 |
| 1-3 | SanitizedDocumentPermissions | `packages/payload/src/types.ts` | ドキュメント権限の構造 |

**読解のコツ**: FormStateは各フィールドの状態（value, initialValue, valid, errors）を持つ。

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

処理の起点となる関数を特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | renderDocument | `packages/next/src/views/Document/index.tsx` | ドキュメントレンダリングの中核関数 |

**主要処理フロー**:
1. **行84-103**: initPageResultから設定と権限を取得
2. **行110-137**: ドキュメントデータの取得、存在確認
3. **行140-209**: 並列でプリファレンス、権限、ロック状態、エンティティ設定を取得
4. **行213-243**: バージョン情報とフォーム状態を構築
5. **行260-314**: ビューコンポーネントの決定
6. **行324-358**: オートセーブ処理（新規作成時）
7. **行360-368**: ドキュメントスロットのレンダリング
8. **行380-397**: ライブプレビューとプレビュー設定
9. **行400-461**: DocumentInfoProvider等でラップしてレンダリング

#### Step 3: プロバイダーを理解する

ドキュメント編集で使用されるコンテキストプロバイダーを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | DocumentInfoProvider | `packages/ui/src/providers/DocumentInfo/index.tsx` | ドキュメント情報コンテキスト |
| 3-2 | LivePreviewProvider | `packages/ui/src/providers/LivePreview/index.tsx` | ライブプレビューコンテキスト |

#### Step 4: フォームコンポーネントを理解する

フォームのレンダリングと状態管理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Form | `packages/ui/src/forms/Form/index.tsx` | フォームコンポーネント |
| 4-2 | RenderFields | `packages/ui/src/fields/RenderFields/index.tsx` | フィールドレンダリング |

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

```
DocumentView (Server Component)
    |
    +-- renderDocument()
            |
            +-- getDocumentData()
            |
            +-- [並列処理]
            |     +-- getDocPreferences()
            |     +-- getDocumentPermissions()
            |     +-- getIsLocked()
            |     +-- getPreferences()
            |
            +-- getVersions()
            |
            +-- buildFormState()
            |
            +-- getDocumentView()
            |
            +-- renderDocumentSlots()
            |
            +-- handleLivePreview()
            |
            +-- handlePreview()
            |
            +-- DocumentInfoProvider
                  +-- LivePreviewProvider
                        +-- DocumentHeader
                        +-- HydrateAuthProvider
                        +-- EditDepthProvider
                              +-- RenderServerComponent
                                    +-- View (EditView / カスタム)
```

### データフロー図

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

URL params --------> renderDocument
        |                 |
        v                 v
  collectionSlug    getDocumentData()
  docId                   |
                          v
                    doc (ドキュメントデータ)
                          |
                    +-----+-----+
                    |     |     |
                    v     v     v
              権限取得  ロック  プリファレンス
                    |     |     |
                    +-----+-----+
                          |
                          v
                    buildFormState()
                          |
                          v
                    formState
                          |
                          v
                    DocumentInfoProvider
                          |
                          v
                    EditView (Form + RenderFields)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.tsx | `packages/next/src/views/Document/index.tsx` | ソース | サーバーコンポーネント |
| getDocumentData.ts | `packages/next/src/views/Document/getDocumentData.ts` | ソース | ドキュメントデータ取得 |
| getDocumentPermissions.ts | `packages/next/src/views/Document/getDocumentPermissions.ts` | ソース | 権限取得 |
| getDocPreferences.ts | `packages/next/src/views/Document/getDocPreferences.ts` | ソース | プリファレンス取得 |
| getIsLocked.ts | `packages/next/src/views/Document/getIsLocked.ts` | ソース | ロック状態取得 |
| getVersions.ts | `packages/next/src/views/Document/getVersions.ts` | ソース | バージョン情報取得 |
| getDocumentView.ts | `packages/next/src/views/Document/getDocumentView.ts` | ソース | ビューコンポーネント決定 |
| renderDocumentSlots.ts | `packages/next/src/views/Document/renderDocumentSlots.ts` | ソース | スロットレンダリング |
| DocumentHeader | `packages/next/src/elements/DocumentHeader/index.tsx` | ソース | ドキュメントヘッダー |
| DocumentInfoProvider | `packages/ui/src/providers/DocumentInfo/index.tsx` | ソース | ドキュメント情報プロバイダー |
| LivePreviewProvider | `packages/ui/src/providers/LivePreview/index.tsx` | ソース | ライブプレビュープロバイダー |
| Form | `packages/ui/src/forms/Form/index.tsx` | ソース | フォームコンポーネント |
| buildFormState.ts | `packages/ui/src/utilities/buildFormState/index.tsx` | ソース | フォーム状態構築 |
