# 機能設計書：バージョン管理

## 1. 機能概要

### 1.1 機能の目的
バージョン管理機能は、コレクションおよびグローバルのドキュメント変更履歴を保持し、過去のバージョンへの復元を可能にする機能である。下書き（Draft）機能との連携により、公開前のコンテンツ管理もサポートする。

### 1.2 機能の範囲
- ドキュメント変更時のバージョン自動保存
- バージョン履歴の取得
- 特定バージョンへの復元
- 最大バージョン数の制御
- 下書き（Draft）機能との連携
- 自動保存（Autosave）機能
- スナップショット機能

### 1.3 関連画面
| 画面ID | 画面名 | 関連操作 |
|--------|--------|----------|
| ADM-020 | バージョン履歴 | findVersions |
| ADM-021 | バージョン詳細 | findVersionByID |
| ADM-022 | バージョン比較 | compare |
| ADM-004 | ドキュメント編集 | restoreVersion |

---

## 2. 機能仕様

### 2.1 入力仕様

#### 2.1.1 バージョン設定
```typescript
interface VersionsConfig {
  drafts?: boolean | {
    autosave?: boolean | {
      interval?: number;  // 自動保存間隔（ms）
    };
    validate?: boolean;   // 下書き時もバリデーション
  };
  maxPerDoc?: number;     // ドキュメントあたりの最大バージョン数
}
```

#### 2.1.2 FindVersions操作
| パラメータ | 型 | 必須 | 説明 |
|-----------|-----|------|------|
| collection | string | Yes | コレクションのslug |
| where | Where | No | 検索条件 |
| limit | number | No | 取得件数上限 |
| page | number | No | ページ番号 |
| sort | string | No | ソート条件 |
| depth | number | No | リレーション展開の深さ |

#### 2.1.3 RestoreVersion操作
| パラメータ | 型 | 必須 | 説明 |
|-----------|-----|------|------|
| collection | string | Yes | コレクションのslug |
| id | string/number | Yes | 復元するバージョンID |
| depth | number | No | リレーション展開の深さ |
| overrideAccess | boolean | No | アクセス制御のオーバーライド |

### 2.2 出力仕様

#### 2.2.1 バージョンドキュメント構造
```typescript
interface Version {
  id: string | number;
  parent: string | number;     // 親ドキュメントのID
  version: Document;           // バージョン時点のドキュメント内容
  autosave?: boolean;          // 自動保存フラグ
  latest?: boolean;            // 最新バージョンフラグ
  publishedLocale?: string;    // 公開ロケール
  createdAt: string;           // バージョン作成日時
  updatedAt: string;           // バージョン更新日時
}
```

#### 2.2.2 FindVersionsの戻り値
```typescript
{
  docs: Version[];
  totalDocs: number;
  limit: number;
  totalPages: number;
  page: number;
  hasPrevPage: boolean;
  hasNextPage: boolean;
}
```

### 2.3 処理フロー

```
[バージョン保存フロー（saveVersion）]
1. 自動保存の場合、既存の自動保存バージョンを確認
2. 既存の自動保存があれば更新、なければ新規作成
3. バージョンデータの構築
   - 親ドキュメントID
   - ドキュメント内容のディープコピー
   - 作成/更新日時
4. データベースにバージョンを保存
5. スナップショットがあれば保存
6. 最大バージョン数の制御（enforceMaxVersions）
7. 古いバージョンの削除
```

```
[バージョン復元フロー（restoreVersion）]
1. バージョンドキュメントの取得
2. アクセス制御チェック
3. バージョン内容を親ドキュメントに適用
4. 親ドキュメントの更新
5. 新しいバージョンとして保存
6. 復元後のドキュメントを返却
```

```
[最大バージョン数制御フロー（enforceMaxVersions）]
1. 設定されたmax値を取得
2. max + 1番目のバージョンを検索
3. 存在すれば、それ以前のバージョンを削除
```

### 2.4 バリデーションルール
- 下書きモードでバリデーションを実行するかは設定により制御
- 復元時は通常のドキュメント更新と同様のバリデーションを実行

### 2.5 エラーハンドリング
| エラーコード | 説明 | HTTPステータス |
|-------------|------|---------------|
| NotFound | バージョンが見つからない | 404 |
| Forbidden | アクセス権限がない | 403 |

---

## 3. データ設計

### 3.1 バージョンコレクションスキーマ
```typescript
// コレクションバージョン: _<collectionSlug>_versions
// グローバルバージョン: _<globalSlug>_versions

interface VersionDocument {
  id: string | number;
  parent?: string | number;    // コレクションの場合のみ
  version: {
    // 親ドキュメントの全フィールド
    [fieldName: string]: any;
  };
  autosave?: boolean;
  latest?: boolean;
  publishedLocale?: string;
  createdAt: string;
  updatedAt: string;
}
```

### 3.2 インデックス設計
| フィールド | 用途 |
|-----------|------|
| parent | 親ドキュメントでの検索 |
| updatedAt | 時系列ソート |
| latest | 最新バージョンの高速取得 |

---

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

### 4.1 推奨読解順序

1. **バージョン保存の理解**
   - `/packages/payload/src/versions/saveVersion.ts`
   - **1-30行目**: 型定義とインポート
   - **38-52行目**: saveVersion関数の引数定義
   - **53-70行目**: versionDataの構築
   - **70-100行目**: autosave時の既存バージョン確認・更新
   - **101-135行目**: 新規バージョンの作成
   - **137-160行目**: スナップショット保存
   - **189-200行目**: 最大バージョン数の制御呼び出し

2. **最大バージョン数制御**
   - `/packages/payload/src/versions/enforceMaxVersions.ts`
   - **15-22行目**: 引数定義
   - **26-58行目**: 削除対象バージョンの検索
   - **60-82行目**: 古いバージョンの削除

3. **バージョン復元**
   - `/packages/payload/src/versions/operations/restoreVersion.ts`
   - 復元処理の全体フロー

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

```
payload.update() / payload.updateGlobal()
  |
  +-- [ドキュメント更新処理]
  |
  +-- saveVersion()
        |
        +-- [autosaveの場合]
        |     +-- findVersions() / findGlobalVersions()
        |     +-- updateVersion() / updateGlobalVersion()
        |
        +-- [新規バージョン作成]
        |     +-- createVersion() / createGlobalVersion()
        |
        +-- saveSnapshot() [スナップショット有効時]
        |
        +-- enforceMaxVersions()
              |
              +-- findVersions() / findGlobalVersions()
              +-- deleteVersions()
```

```
payload.restoreVersion()
  |
  +-- findVersionByID()
  |
  +-- executeAccess()
  |
  +-- payload.update() [復元データで更新]
  |
  +-- [結果返却]
```

### 4.3 データフロー図

```
[ドキュメント更新]
       |
       v
+------------------+
| ドキュメント保存  |
+------------------+
       |
       v
+------------------+
| saveVersion()    |
+------------------+
       |
       +-- autosave?
       |      |
       |      +-- Yes --> 既存更新 or 新規作成
       |      |
       |      +-- No  --> 新規バージョン作成
       |
       v
+------------------+
| enforceMaxVersions|
+------------------+
       |
       v
+------------------+
| 古いバージョン削除|
+------------------+
```

### 4.4 関連ファイル一覧

| ファイルパス | 種別 | 役割 |
|-------------|------|------|
| `/packages/payload/src/versions/saveVersion.ts` | 処理 | バージョン保存処理 |
| `/packages/payload/src/versions/enforceMaxVersions.ts` | 処理 | 最大バージョン数制御 |
| `/packages/payload/src/versions/saveSnapshot.ts` | 処理 | スナップショット保存 |
| `/packages/payload/src/versions/drafts/getQueryDraftsSelect.ts` | ユーティリティ | 下書きクエリ構築 |
| `/packages/payload/src/utilities/getVersionsConfig.js` | ユーティリティ | バージョン設定取得 |

---

## 5. 設計上の考慮事項

### 5.1 パフォーマンス考慮
- maxPerDocによるバージョン数制限でストレージ効率化
- autosaveの間隔設定による書き込み頻度制御
- 適切なインデックスによる検索最適化

### 5.2 セキュリティ考慮
- バージョン読み取り権限（readVersions）の独立制御
- 復元操作にはupdate権限が必要

### 5.3 拡張性考慮
- コレクション/グローバル両方に対応
- スナップショット機能による追加データ保存
- 公開ロケール管理によるマルチ言語対応

---

## 6. 変更履歴

| 日付 | バージョン | 変更内容 | 担当者 |
|------|-----------|----------|--------|
| 2026-03-01 | 1.0.0 | 初版作成 | AI |
