# 機能設計書 47-Slateエディタ

## 概要

本ドキュメントは、Payload CMSにおけるSlateリッチテキストエディタ（richtext-slate）の設計を記載する。本パッケージは、SlateフレームワークをPayloadのリッチテキストフィールドアダプターとして統合するレガシーエディタである。

**重要**: 本パッケージはPayload 4.0で削除予定であり、Lexicalエディタへの移行が推奨されている。

### 本機能の処理概要

**業務上の目的・背景**：SlateエディタはPayload 2.x系で標準リッチテキストエディタとして使用されていた。Payload 3.x以降もLexicalへの移行期間として継続サポートされているが、新規プロジェクトではLexicalの使用を推奨。

**機能の利用シーン**：
- 既存Payload 2.xプロジェクトのアップグレード時
- Lexicalへの移行前の一時的な使用
- Slateベースのカスタマイズが大量にある既存プロジェクト

**主要な処理内容**：
1. Element（要素）とLeaf（文字装飾）のカスタマイズ
2. リンク、アップロード、リレーションシップの埋め込み
3. エディタ状態（Slate Node配列）の永続化
4. afterReadフックでのリレーションシップ解決
5. GraphQL Population Promisesによるデータ取得
6. JSON Schemaの生成

**関連システム・外部連携**：
- Slate（slate-react等）
- Admin UI（リッチテキストフィールドコンポーネント）
- GraphQL API（population promises）

**権限による制御**：
- Payloadの標準フィールドアクセス制御に従う

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 10 | ドキュメント編集画面 | 主画面 | リッチテキストフィールドの編集 |
| 9 | 一覧画面 | 参照画面 | セル表示コンポーネント |

## 機能種別

UIコンポーネント / データ変換 / CRUD操作 / レガシー

## 入力仕様

### 入力パラメータ（slateEditor設定）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| admin.elements | (string \| RichTextCustomElement)[] | No | 有効なElement | デフォルト: 全Element |
| admin.leaves | (string \| RichTextCustomLeaf)[] | No | 有効なLeaf | デフォルト: 全Leaf |
| admin.link | object | No | リンク設定 | - |
| admin.upload | object | No | アップロード設定 | - |

### 入力パラメータ（エディタ値）

Slate Node配列形式：
```typescript
[
  {
    type: 'paragraph',
    children: [
      { text: 'テキスト', bold: true }
    ]
  },
  // ...
]
```

### 入力データソース

- ドキュメント編集画面でのユーザー入力
- APIからのJSON形式データ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| value | object[] | Slate Node配列 |

### 出力先

- データベース（Slate Node配列形式）

## 処理フロー

### 処理シーケンス

```
1. slateEditorプロバイダー初期化
   └─ admin.link.fieldsとadmin.upload.*.fieldsのサニタイズ
2. フィールドコンポーネントの返却
   └─ RscEntrySlateField
3. afterReadフック
   └─ relationship/upload/link要素のpopulation
4. graphQLPopulationPromises
   └─ リレーションの解決
5. バリデーション
   └─ richTextValidate
```

### フローチャート

```mermaid
flowchart TD
    A[slateEditor呼び出し] --> B[リンクフィールドのサニタイズ]
    B --> C[アップロードフィールドのサニタイズ]
    C --> D[RichTextAdapterオブジェクト返却]
    D --> E[FieldComponent: RscEntrySlateField]
    D --> F[generateImportMap]
    D --> G[generateSchemaMap]
    D --> H[graphQLPopulationPromises]
    D --> I[hooks.afterRead]
    D --> J[validate: richTextValidate]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 非推奨警告 | 4.0で削除予定の警告をコンソール出力 | 常時 |
| BR-02 | デフォルトElement | elements未指定時は全Elementが有効 | admin.elements未指定時 |
| BR-03 | デフォルトLeaf | leaves未指定時は全Leafが有効 | admin.leaves未指定時 |
| BR-04 | リレーション解決 | relationship/upload/link要素を自動的にpopulate | afterRead/graphQL時 |

### 計算ロジック

特になし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| ドキュメント保存 | リッチテキスト含むコレクション | INSERT/UPDATE | Slate Node配列保存 |
| ドキュメント読み取り | リッチテキスト含むコレクション | SELECT | Slate Node配列取得 |
| Population | リレーション先コレクション | SELECT | 埋め込みリレーションの解決 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ValidationError | 不正なエディタ状態 | richTextValidateで検証 |

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

Payloadの標準トランザクション挙動に従う。

## パフォーマンス要件

特になし

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

- リレーション解決時のアクセス制御適用
- HTML出力時のサニタイズは利用者責任

## 備考

- **非推奨**: Payload 4.0で削除予定
- Lexicalへの移行ガイド: https://payloadcms.com/docs/rich-text/migration#migrating-from-slate
- SlateからLexicalへのデータ移行ユーティリティあり

---

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

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

### 推奨読解順序

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

Slate固有の型定義を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | types.ts | `packages/richtext-slate/src/types.ts` | AdapterArguments、RichTextCustomElement、RichTextCustomLeaf |

**読解のコツ**: `RichTextCustomElement`がElement（ブロック要素）の定義、`RichTextCustomLeaf`がLeaf（文字装飾）の定義。SlateFieldPropsがフィールドコンポーネントのprops型。

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

slateEditor関数の全体フローを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.tsx | `packages/richtext-slate/src/index.tsx` | slateEditor関数 |

**主要処理フロー**:
1. **17行目**: @deprecated警告（JSDoc）
2. **21行目**: validRelationshipsの取得
3. **23-37行目**: admin.link.fieldsのサニタイズ
4. **39-50行目**: admin.upload.*.fieldsのサニタイズ
5. **52-58行目**: コンポーネント登録
6. **60-113行目**: generateImportMap
7. **114行目**: generateSchemaMap
8. **115-154行目**: graphQLPopulationPromises
9. **155-202行目**: hooks.afterRead
10. **203-210行目**: outputSchema
11. **211行目**: validate

#### Step 3: Element/Leafを理解する

組み込みのElement/Leafを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | elements/index.ts | `packages/richtext-slate/src/field/elements/index.ts` | 組み込みElement一覧 |
| 3-2 | leaves/index.ts | `packages/richtext-slate/src/field/leaves/index.ts` | 組み込みLeaf一覧 |

#### Step 4: リレーションシップ解決を理解する

埋め込みリレーションの処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | richTextRelationshipPromise.ts | `packages/richtext-slate/src/data/richTextRelationshipPromise.ts` | リレーション解決 |

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

```
slateEditor (index.tsx)
    │
    ├─ sanitizeFields (payload)
    │      ├─ link.fieldsのサニタイズ
    │      └─ upload.*.fieldsのサニタイズ
    │
    ├─ generateImportMap
    │      ├─ leafTypes（組み込みLeaf）
    │      ├─ elementTypes（組み込みElement）
    │      └─ カスタムleaves/elements
    │
    ├─ generateSchemaMap
    │      └─ getGenerateSchemaMap
    │
    ├─ graphQLPopulationPromises
    │      └─ richTextRelationshipPromise
    │
    └─ hooks.afterRead
           └─ richTextRelationshipPromise
```

### データフロー図

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

ユーザー入力 ─────────────▶ Slateエディタ ──────────────▶ Slate Node配列
                                 │
                                 ▼
                          データベース保存

[読み取り時]
データベース ─────────────▶ afterRead ─────────────────▶ Slate Node配列
                                 │
                                 ▼
                          richTextRelationshipPromise
                                 │
                                 ▼
                          population済みデータ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.tsx | `packages/richtext-slate/src/index.tsx` | ソース | エントリーポイント |
| types.ts | `packages/richtext-slate/src/types.ts` | ソース | 型定義 |
| elements/index.ts | `packages/richtext-slate/src/field/elements/index.ts` | ソース | 組み込みElement |
| leaves/index.ts | `packages/richtext-slate/src/field/leaves/index.ts` | ソース | 組み込みLeaf |
| richTextRelationshipPromise.ts | `packages/richtext-slate/src/data/richTextRelationshipPromise.ts` | ソース | リレーション解決 |
| validation.ts | `packages/richtext-slate/src/data/validation.ts` | ソース | バリデーション |
| generateSchemaMap.ts | `packages/richtext-slate/src/generateSchemaMap.ts` | ソース | スキーママップ生成 |
