# 機能設計書 64-バリデーション

## 概要

本ドキュメントは、Payload CMSのバリデーション機能（フィールド値の検証機能）について、その設計仕様を詳細に記載したものである。

### 本機能の処理概要

バリデーション機能は、フィールドに入力された値の妥当性を検証し、データの整合性を保証する機能である。

**業務上の目的・背景**：データベースに保存されるデータの品質を保証することは、CMSの信頼性において極めて重要である。不正な形式のメールアドレス、範囲外の数値、必須項目の未入力などを防ぐことで、アプリケーション全体の安定性を確保する。また、ユーザーに対して入力エラーを明確にフィードバックすることで、UXの向上にも貢献する。

**機能の利用シーン**：
- ドキュメント作成・更新時のフィールド値検証
- フォーム送信時のリアルタイムバリデーション
- Admin UIでの入力値チェック
- REST API / GraphQL APIでのリクエストデータ検証

**主要な処理内容**：
1. 各フィールドタイプに対応した組み込みバリデーション関数の提供
2. 必須項目チェック（required）
3. 文字列長チェック（minLength、maxLength）
4. 数値範囲チェック（min、max）
5. 配列要素数チェック（minRows、maxRows）
6. 正規表現パターンマッチング（email等）
7. リレーションシップの妥当性検証
8. JSONスキーマによる検証
9. カスタムバリデーション関数のサポート

**関連システム・外部連携**：
- フィールドシステム（各フィールドタイプ）
- beforeChangeフック（バリデーション実行タイミング）
- Admin UI（エラー表示）

**権限による制御**：バリデーションは権限に関係なくすべてのユーザーに対して適用される。ただし、フィールドのconditionによってバリデーションをスキップすることは可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 10 | ドキュメント編集画面 | 主画面 | フィールド値の検証処理 |

## 機能種別

データ検証処理 / バリデーション

## 入力仕様

### 入力パラメータ（Validate関数共通）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| value | T | Yes | 検証対象の値 | - |
| options.required | boolean | No | 必須フラグ | - |
| options.req | PayloadRequest | Yes | リクエストオブジェクト | - |
| options.data | object | No | ドキュメント全体のデータ | - |
| options.siblingData | object | No | 兄弟フィールドのデータ | - |
| options.operation | string | No | 操作種別 | - |
| options.id | number \| string | No | ドキュメントID | - |

### フィールドタイプ別パラメータ

| フィールドタイプ | 追加パラメータ | 説明 |
|----------------|---------------|------|
| text | minLength, maxLength, hasMany, minRows, maxRows | 文字列長、複数値設定 |
| number | min, max, hasMany, minRows, maxRows | 数値範囲、複数値設定 |
| email | - | メールアドレス形式 |
| select | options, hasMany, filterOptions | 選択肢の妥当性 |
| relationship | relationTo, hasMany, minRows, maxRows, filterOptions | リレーション先の妥当性 |
| upload | relationTo, minRows, maxRows, filterOptions | アップロード先の妥当性 |
| array | minRows, maxRows | 配列要素数 |
| blocks | minRows, maxRows, filterOptions | ブロック要素数、ブロック種別 |
| json | jsonSchema | JSONスキーマ検証 |
| point | - | 座標値（経度-180~180、緯度-90~90） |
| date | timezone | 日付形式、タイムゾーン |

### 入力データソース

- フィールド定義（設定ファイル）
- ユーザー入力値（Admin UI / API）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| (返り値) | true \| string | true:検証成功、string:エラーメッセージ |

### 出力先

- beforeChangeフックへの返却
- ValidationError（エラー時）
- Admin UIのエラー表示

## 処理フロー

### 処理シーケンス

```
1. beforeChange処理内でバリデーション呼び出し
   └─ フィールドのvalidate関数を取得

2. validate関数の実行
   └─ 必須チェック
   └─ フィールドタイプ固有のチェック
   └─ カスタムチェック（定義されている場合）

3. 結果の判定
   └─ true: 検証成功、次の処理へ
   └─ string: 検証失敗、エラーメッセージを収集

4. エラー集約
   └─ すべてのフィールドのエラーを収集
   └─ ValidationErrorとしてスロー
```

### フローチャート

```mermaid
flowchart TD
    A[validate関数呼び出し] --> B{required?}
    B -->|Yes| C{値が存在?}
    B -->|No| D[タイプ別検証]
    C -->|No| E[required エラー]
    C -->|Yes| D
    D --> F{タイプ別条件}
    F -->|text| G[文字列長チェック]
    F -->|number| H[数値範囲チェック]
    F -->|email| I[メール形式チェック]
    F -->|etc| J[その他のチェック]
    G --> K{検証成功?}
    H --> K
    I --> K
    J --> K
    K -->|Yes| L[trueを返却]
    K -->|No| M[エラーメッセージを返却]
    E --> M
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 必須チェック | requiredがtrueで値がない場合はエラー | 全フィールド |
| BR-02 | 文字列長チェック | minLength以上、maxLength以下 | text, textarea |
| BR-03 | 数値範囲チェック | min以上、max以下 | number |
| BR-04 | 配列要素数チェック | minRows以上、maxRows以下 | array, blocks, hasMany |
| BR-05 | メール形式チェック | RFC準拠のメールアドレス形式 | email |
| BR-06 | 選択肢妥当性 | optionsに含まれる値のみ許可 | select, radio |
| BR-07 | リレーション妥当性 | 存在するドキュメントへの参照のみ許可 | relationship, upload |
| BR-08 | JSON形式チェック | 有効なJSON形式 | json |
| BR-09 | 座標範囲チェック | 経度-180~180、緯度-90~90 | point |
| BR-10 | 重複チェック | hasMany時に重複値を検出 | select (hasMany) |

### 計算ロジック

- 文字列長：`value.length`で計算
- 配列要素数：`Array.isArray(value) ? value.length : 0`で計算
- メール正規表現：RFC準拠の正規表現パターンで検証

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| validateFilterOptions | 各コレクション | SELECT | リレーションの妥当性検証 |

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

バリデーション自体はデータベースを直接操作しない。ただし、relationship/uploadフィールドのfilterOptions検証時に、関連コレクションへのクエリが発生する。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | validation:required | 必須フィールドが未入力 | 値を入力する |
| - | validation:shorterThanMax | 最大文字数を超過 | 文字数を減らす |
| - | validation:longerThanMin | 最小文字数に不足 | 文字数を増やす |
| - | validation:greaterThanMax | 最大値を超過 | 値を減らす |
| - | validation:lessThanMin | 最小値に不足 | 値を増やす |
| - | validation:emailAddress | メール形式不正 | 正しい形式で入力 |
| - | validation:invalidSelection | 無効な選択肢 | 有効な選択肢を選ぶ |
| - | validation:requiresAtLeast | 最小要素数に不足 | 要素を追加する |
| - | validation:requiresNoMoreThan | 最大要素数を超過 | 要素を削除する |
| - | validation:invalidInput | 入力値が不正 | 正しい形式で入力 |
| - | validation:longitudeOutOfBounds | 経度が範囲外 | -180~180の範囲で入力 |
| - | validation:latitudeOutOfBounds | 緯度が範囲外 | -90~90の範囲で入力 |

### リトライ仕様

バリデーションエラーはリトライ不可。入力値の修正が必要。

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

- バリデーションはトランザクション開始前に実行
- バリデーション失敗時はトランザクションを開始しない

## パフォーマンス要件

- 各フィールドのバリデーションは数ミリ秒以内に完了すること
- relationship/uploadのfilterOptions検証はDBクエリが発生するため注意

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

- バリデーションによる不正データの防止
- JSONスキーマによる構造検証
- 正規表現によるインジェクション対策

## 備考

- すべてのバリデーション関数は`validations`オブジェクトとしてエクスポートされ、再利用可能
- カスタムバリデーション関数はasync関数として定義可能
- バリデーションエラーメッセージは国際化対応

---

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

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

### 推奨読解順序

#### Step 1: バリデーション関数群を理解する

すべての組み込みバリデーション関数が定義されているファイルを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | validations.ts | `packages/payload/src/fields/validations.ts` | すべての組み込みバリデーション関数 |

**読解のコツ**: このファイルは約1115行の大きなファイル。フィールドタイプごとにバリデーション関数が定義されている。

**主要処理フロー**:
1. **45-103行目**: text関数 - テキストフィールドのバリデーション
2. **107-141行目**: password関数 - パスワードフィールドのバリデーション
3. **150-163行目**: confirmPassword関数 - パスワード確認のバリデーション
4. **167-212行目**: email関数 - メールアドレスのバリデーション
5. **216-259行目**: username関数 - ユーザー名のバリデーション
6. **263-296行目**: textarea関数 - テキストエリアのバリデーション
7. **300-306行目**: code関数 - コードフィールドのバリデーション
8. **315-383行目**: json関数 - JSONフィールドのバリデーション
9. **387-393行目**: checkbox関数 - チェックボックスのバリデーション
10. **397-427行目**: date関数 - 日付フィールドのバリデーション
11. **431-442行目**: richText関数 - リッチテキストのバリデーション
12. **444-474行目**: validateArrayLength関数 - 配列長の共通バリデーション
13. **482-522行目**: number関数 - 数値フィールドのバリデーション
14. **526-528行目**: array関数 - 配列フィールドのバリデーション
15. **602-626行目**: blocks関数 - ブロックフィールドのバリデーション
16. **769-849行目**: upload関数 - アップロードフィールドのバリデーション
17. **872-952行目**: relationship関数 - リレーションシップフィールドのバリデーション
18. **960-1030行目**: select関数 - セレクトフィールドのバリデーション
19. **1034-1043行目**: radio関数 - ラジオボタンのバリデーション
20. **1052-1088行目**: point関数 - ポイントフィールドのバリデーション
21. **1095-1114行目**: validationsオブジェクト - 全関数のエクスポート

#### Step 2: バリデーション実行箇所を理解する

バリデーションが実行されるbeforeChange処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | promise.ts | `packages/payload/src/fields/hooks/beforeChange/promise.ts` | バリデーション実行箇所 |

**主要処理フロー（promise.ts）**:
- **165-266行目**: validate関数の呼び出しとエラー処理
- **177-182行目**: validateFn型のアサーションとオプションの構築
- **184-200行目**: validateFn呼び出し
- **202-265行目**: バリデーション結果の処理（エラー収集）

#### Step 3: filterOptions検証を理解する

relationship/uploadのfilterOptions検証を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | validations.ts | `packages/payload/src/fields/validations.ts` | validateFilterOptions関数 |

**主要処理フロー（validateFilterOptions）**:
- **628-761行目**: validateFilterOptions関数
- **637-715行目**: filterOptionsに基づくクエリ実行
- **717-757行目**: 無効なリレーションの検出

#### Step 4: blocksのfilterOptions検証を理解する

blocksフィールドのfilterOptions検証を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | validations.ts | `packages/payload/src/fields/validations.ts` | validateBlocksFilterOptions関数 |

**主要処理フロー（validateBlocksFilterOptions）**:
- **539-601行目**: validateBlocksFilterOptions関数
- **563-567行目**: 全ブロックスラグの抽出
- **572-585行目**: filterOptionsの評価
- **587-595行目**: 無効なブロックスラグの検出

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

```
[beforeChange処理]
    │
    └─ traverseFields
           │
           └─ promise (各フィールド)
                  │
                  └─ validate関数呼び出し
                         │
                         ├─ text
                         ├─ number
                         ├─ email
                         ├─ select
                         ├─ relationship
                         │      └─ validateFilterOptions
                         ├─ upload
                         │      └─ validateFilterOptions
                         ├─ array
                         │      └─ validateArrayLength
                         ├─ blocks
                         │      ├─ validateArrayLength
                         │      └─ validateBlocksFilterOptions
                         ├─ json
                         │      └─ Ajv (JSONスキーマ検証)
                         ├─ point
                         ├─ date
                         ├─ checkbox
                         ├─ radio
                         ├─ richText
                         │      └─ editor.validate
                         └─ その他
```

### データフロー図

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

フィールド値 ───▶ validate関数 ───▶ 各種チェック ───▶ true/エラーメッセージ
フィールド設定          │               │
    │                  │               │
    ├─ required        │          必須チェック
    ├─ minLength       │          文字列長チェック
    ├─ maxLength       │          文字列長チェック
    ├─ min             │          数値範囲チェック
    ├─ max             │          数値範囲チェック
    ├─ minRows         │          配列長チェック
    ├─ maxRows         │          配列長チェック
    ├─ options         │          選択肢チェック
    ├─ filterOptions   │          関連チェック
    └─ jsonSchema      │          スキーマチェック
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| validations.ts | `packages/payload/src/fields/validations.ts` | ソース | 組み込みバリデーション関数群 |
| promise.ts | `packages/payload/src/fields/hooks/beforeChange/promise.ts` | ソース | バリデーション実行箇所 |
| index.ts | `packages/payload/src/fields/hooks/beforeChange/index.ts` | ソース | ValidationError生成 |
| ValidationError.ts | `packages/payload/src/errors/ValidationError.ts` | ソース | バリデーションエラークラス |
| types.ts | `packages/payload/src/fields/config/types.ts` | ソース | Validate型の定義 |
