# 機能設計書 21-バリデーションファクトリ

## 概要

本ドキュメントは、Laravel Frameworkのバリデーションファクトリ機能（Validation Factory）の設計仕様を記載する。バリデーションファクトリは、入力データの検証機能を提供するコアコンポーネントである。

### 本機能の処理概要

バリデーションファクトリは、アプリケーションに対する入力データの整合性と安全性を保証するための包括的なバリデーション機能を提供する。

**業務上の目的・背景**：Webアプリケーションにおいて、ユーザーからの入力データはセキュリティリスクや業務エラーの主要な発生源となる。バリデーションファクトリは、入力データが業務要件を満たしているか（必須入力、形式、範囲等）を検証し、不正なデータがシステムに流入することを防止する。これにより、SQLインジェクションやXSS等のセキュリティ脆弱性対策、データ整合性の維持、ユーザーへの適切なエラーフィードバックを実現する。

**機能の利用シーン**：フォーム入力の検証（ユーザー登録、ログイン、問い合わせ等）、APIリクエストのパラメータ検証、CSVインポート時のデータ検証、管理画面での設定値入力検証など、あらゆるデータ入力場面で利用される。

**主要な処理内容**：
1. Validatorインスタンスの生成と初期化（makeメソッド）
2. バリデーションルールの解析とルールオブジェクトへの変換
3. 各フィールドに対するルール適用と検証処理の実行
4. エラーメッセージの生成とローカライズ対応
5. カスタムバリデーションルールの登録と実行
6. データベース存在確認（exists/unique）ルールの処理

**関連システム・外部連携**：Translatorコンポーネント（多言語エラーメッセージ）、DatabasePresenceVerifier（DB存在確認）、NotPwnedVerifier（パスワード漏洩チェック）との連携がある。

**権限による制御**：バリデーション機能自体には権限制御はないが、Canルールを使用することで認可ゲートと連携したバリデーションが可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | 全入力フォーム画面 | 主画面 | フォーム送信時の入力値検証 |

## 機能種別

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

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| data | array | Yes | 検証対象のデータ配列 | 配列であること |
| rules | array | Yes | バリデーションルールの定義配列 | 配列であること |
| messages | array | No | カスタムエラーメッセージ | 配列であること |
| attributes | array | No | フィールド名のカスタム表示名 | 配列であること |

### 入力データソース

- HTTPリクエストの入力データ（Request::all()、Request::input()）
- 手動で構築した配列データ
- APIリクエストのJSONボディ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| validated | array | 検証に成功したデータのみを含む配列 |
| errors | MessageBag | 検証エラーメッセージのコレクション |
| failed | array | 失敗したルールの情報 |

### 出力先

- 検証成功時：validated()メソッドで検証済みデータを返却
- 検証失敗時：ValidationException例外をスロー、またはerrors()でエラーメッセージを取得

## 処理フロー

### 処理シーケンス

```
1. Factory::make()でValidatorインスタンスを生成
   └─ Translatorインスタンスを注入
   └─ PresenceVerifierを設定（DB検証用）
   └─ カスタム拡張ルールを追加

2. Validator::passes()でバリデーション実行
   └─ 各属性に対してルールを順次適用
   └─ implicitルール（required等）は値の有無に関係なく実行
   └─ ルール違反時はMessageBagにエラーを追加

3. Validator::validate()で結果を取得
   └─ 失敗時はValidationExceptionをスロー
   └─ 成功時は検証済みデータを返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[Factory::make呼び出し]
    B --> C[Validatorインスタンス生成]
    C --> D[PresenceVerifier設定]
    D --> E[カスタム拡張追加]
    E --> F[validate/passes呼び出し]
    F --> G{全ルール検証}
    G -->|各属性| H[ルール解析]
    H --> I[バリデーション実行]
    I --> J{検証成功?}
    J -->|No| K[エラーメッセージ追加]
    K --> G
    J -->|Yes| G
    G -->|完了| L{エラーあり?}
    L -->|Yes| M[ValidationException]
    L -->|No| N[検証済みデータ返却]
    M --> O[終了]
    N --> O
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 必須チェック | requiredルールは空文字、null、空配列を不可とする | requiredルール指定時 |
| BR-02 | Implicitルール | required系ルールは値が存在しなくても実行される | implicitRules配列に含まれるルール |
| BR-03 | Bailルール | bailが指定された属性は最初のエラーで検証を中断 | bailルール指定時 |
| BR-04 | Sometimesルール | 属性が存在する場合のみルールを適用 | sometimesルール指定時 |

### 計算ロジック

- ファイルサイズはキロバイト単位で計算
- 数値の比較はBCMath（任意精度演算）を使用
- 文字列長はmb_strlen()でマルチバイト対応

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| exists | 任意 | SELECT | 指定カラムに値が存在するか確認 |
| unique | 任意 | SELECT | 指定カラムに値が重複していないか確認 |

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

#### 任意テーブル（exists/uniqueルール使用時）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | 指定カラム | WHERE column = value | DatabasePresenceVerifierで実行 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ValidationException | バリデーションエラー | いずれかのルールに違反 | エラーメッセージをユーザーに表示 |
| RuntimeException | 設定エラー | PresenceVerifierが未設定でDB検証実行 | 設定の確認 |
| BadMethodCallException | メソッドエラー | 存在しないバリデーションルール呼び出し | ルール名の確認 |

### リトライ仕様

バリデーション処理自体にリトライ機能はなし。ユーザーは入力を修正して再送信する。

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

バリデーション処理はトランザクションを使用しない（読み取り専用）。exists/uniqueルールでのDB問い合わせはWritePdoを使用してレプリケーション遅延に対応。

## パフォーマンス要件

- 大量のルール適用でも線形時間で処理
- ワイルドカード（*）を使用した配列バリデーションは展開後のルール数に比例
- DB検証は必要最小限のクエリで実行

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

- 入力データのサニタイズはバリデーションとは別途実施が必要
- パスワード漏洩チェック（NotPwnedVerifier）でHIBP APIと連携
- データベースクエリはパラメータバインディングを使用
- クロージャルールは信頼できるソースからのみ使用

## 備考

- ValidationServiceProviderで自動登録される
- 'validator'エイリアスでコンテナから解決可能
- FormRequestクラスとの連携でコントローラの責務を分離可能

---

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

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

### 推奨読解順序

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

まず、バリデーションで使用されるインターフェースと基本データ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Factory.php | `src/Illuminate/Contracts/Validation/Factory.php` | バリデーションファクトリの契約インターフェース |
| 1-2 | Validator.php | `src/Illuminate/Contracts/Validation/Validator.php` | バリデータの契約インターフェース |

**読解のコツ**: Laravelではインターフェース（Contracts）を先に理解することで、実装クラスの役割が明確になる。

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

処理の起点となるファクトリクラスを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Factory.php | `src/Illuminate/Validation/Factory.php` | Validatorインスタンスの生成ロジック |
| 2-2 | ValidationServiceProvider.php | `src/Illuminate/Validation/ValidationServiceProvider.php` | サービスプロバイダでの登録処理 |

**主要処理フロー**:
- **89-93行目**: コンストラクタでTranslatorとContainerを受け取る
- **104-129行目**: make()メソッドでValidatorを生成、PresenceVerifierと拡張を設定
- **142-145行目**: validate()メソッドで直接バリデーション実行

#### Step 3: バリデータコアを理解する

実際のバリデーション処理を行うValidatorクラスを詳細に確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Validator.php | `src/Illuminate/Validation/Validator.php` | メインのバリデーション処理 |
| 3-2 | ValidatesAttributes.php | `src/Illuminate/Validation/Concerns/ValidatesAttributes.php` | 各バリデーションルールの実装 |
| 3-3 | FormatsMessages.php | `src/Illuminate/Validation/Concerns/FormatsMessages.php` | エラーメッセージのフォーマット処理 |

**主要処理フロー**:
- **340-358行目**: コンストラクタで初期化、ルールをセット
- **460-507行目**: passes()メソッドで全ルールを検証
- **596-601行目**: validate()メソッドで失敗時に例外をスロー
- **679-729行目**: validateAttribute()で個別属性の検証を実行

#### Step 4: ルール解析を理解する

ルール文字列の解析処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | ValidationRuleParser.php | `src/Illuminate/Validation/ValidationRuleParser.php` | ルール文字列のパース処理 |
| 4-2 | Rule.php | `src/Illuminate/Validation/Rule.php` | ルールビルダー（Fluent API） |

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

```
ValidationServiceProvider::register()
    │
    ├─ Factory::__construct()
    │
    └─ Factory::make()
           │
           ├─ Factory::resolve()
           │      └─ new Validator()
           │
           ├─ Validator::setPresenceVerifier()
           │
           └─ Factory::addExtensions()
                  │
                  ├─ Validator::addExtensions()
                  ├─ Validator::addImplicitExtensions()
                  └─ Validator::addReplacers()

Validator::validate()
    │
    └─ Validator::passes()
           │
           ├─ Validator::validateAttribute()
           │      │
           │      ├─ ValidationRuleParser::parse()
           │      │
           │      └─ Validator::validate{Rule}()
           │             └─ ValidatesAttributes::validate{Rule}()
           │
           └─ Validator::addFailure()
                  └─ FormatsMessages::makeReplacements()
```

### データフロー図

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

data配列 ───────▶ Factory::make() ───────▶ Validatorインスタンス
rules配列                │
messages配列             │
                         ▼
                   Validator::passes()
                         │
                         ▼
                   validateAttribute()
                         │
                 ┌───────┴───────┐
                 ▼               ▼
            [成功]           [失敗]
                 │               │
                 ▼               ▼
          validated() ──▶ エラーメッセージ
          検証済み配列     MessageBag
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Factory.php | `src/Illuminate/Validation/Factory.php` | ソース | Validatorファクトリ |
| Validator.php | `src/Illuminate/Validation/Validator.php` | ソース | コアバリデーション処理 |
| ValidationServiceProvider.php | `src/Illuminate/Validation/ValidationServiceProvider.php` | ソース | サービス登録 |
| ValidationRuleParser.php | `src/Illuminate/Validation/ValidationRuleParser.php` | ソース | ルール解析 |
| Rule.php | `src/Illuminate/Validation/Rule.php` | ソース | Fluentルールビルダー |
| ValidatesAttributes.php | `src/Illuminate/Validation/Concerns/ValidatesAttributes.php` | ソース | 各ルール実装 |
| FormatsMessages.php | `src/Illuminate/Validation/Concerns/FormatsMessages.php` | ソース | メッセージ処理 |
| ValidationException.php | `src/Illuminate/Validation/ValidationException.php` | ソース | 例外クラス |
| Factory.php | `src/Illuminate/Contracts/Validation/Factory.php` | インターフェース | 契約定義 |
| Validator.php | `src/Illuminate/Contracts/Validation/Validator.php` | インターフェース | 契約定義 |
