# 機能設計書 50-RedisKVアダプター

## 概要

本ドキュメントは、Payload CMSにおけるRedisキーバリューストアアダプター（kv-redis）の設計を記載する。本パッケージは、PayloadのKVAdapter（キーバリューストア）インターフェースをRedisで実装し、セッション管理、キャッシュ、一時データ保存などに使用される。

### 本機能の処理概要

**業務上の目的・背景**：Payloadはキーバリューストアを抽象化するKVAdapterインターフェースを提供している。本アダプターは、Redisを使用して高速で永続性のあるKVストアを実装し、スケールアウト環境での状態管理を可能にする。

**機能の利用シーン**：
- セッションストレージ
- キャッシュストレージ
- 一時データの保存
- 分散環境での状態共有
- レート制限のカウンター

**主要な処理内容**：
1. Redisへの接続管理（ioredis使用）
2. キープレフィックスによる名前空間分離
3. CRUD操作（get/set/delete/has/keys/clear）
4. JSON形式でのデータシリアライズ

**関連システム・外部連携**：
- Redis（ioredisクライアント）
- PayloadのKVAdapterインターフェース

**権限による制御**：
- 特になし（KVストア自体に権限制御なし）

## 関連画面

本機能は管理画面との直接的な関連はない（バックエンド処理）。

## 機能種別

データストア / キャッシュ / 外部連携

## 入力仕様

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

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| keyPrefix | string | No | キーのプレフィックス | デフォルト: 'payload-kv:' |
| redisURL | string | No | Redis接続URL | デフォルト: process.env.REDIS_URL |

### 入力パラメータ（KVAdapter操作）

| 操作 | パラメータ | 型 | 説明 |
|------|----------|-----|------|
| get | key | string | 取得するキー |
| set | key, data | string, KVStoreValue | 設定するキーと値 |
| delete | key | string | 削除するキー |
| has | key | string | 存在確認するキー |
| keys | - | - | 全キー取得 |
| clear | - | - | 全データ削除 |

### 入力データソース

- Payload設定ファイルでのアダプター設定
- REDIS_URL環境変数
- PayloadからのKV操作リクエスト

## 出力仕様

### 出力データ

| 操作 | 戻り値 | 型 | 説明 |
|------|--------|-----|------|
| get | value | T \| null | 取得した値（null: 未存在） |
| set | - | void | - |
| delete | - | void | - |
| has | exists | boolean | キーの存在有無 |
| keys | keys | string[] | プレフィックス除去後のキー一覧 |
| clear | - | void | - |

### 出力先

- Redis（データ保存）

## 処理フロー

### 処理シーケンス

```
1. redisKVAdapter呼び出し
   ├─ keyPrefixのデフォルト設定（'payload-kv:'）
   └─ redisURLの取得（引数 or 環境変数）
2. KVAdapterResultオブジェクトの返却
3. init呼び出し時
   └─ RedisKVAdapterインスタンス生成
       └─ new Redis(redisURL)
4. 各操作の実行
   ├─ get: redisClient.get → JSON.parse
   ├─ set: JSON.stringify → redisClient.set
   ├─ delete: redisClient.del
   ├─ has: redisClient.exists
   ├─ keys: redisClient.keys → prefix除去
   └─ clear: redisClient.keys → redisClient.del
```

### フローチャート

```mermaid
flowchart TD
    A[redisKVAdapter呼び出し] --> B{redisURL設定?}
    B -->|No| C{REDIS_URL環境変数?}
    C -->|No| D[Error: redisURL required]
    C -->|Yes| E[REDIS_URLを使用]
    B -->|Yes| E
    E --> F[KVAdapterResult返却]
    F --> G[init呼び出し]
    G --> H[RedisKVAdapterインスタンス生成]
    H --> I[new Redis接続]
    I --> J[KV操作が可能]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | デフォルトプレフィックス | keyPrefixのデフォルトは'payload-kv:' | keyPrefix未指定時 |
| BR-02 | 環境変数フォールバック | redisURL未指定時はREDIS_URL環境変数を使用 | redisURL未指定時 |
| BR-03 | URL必須 | redisURLまたはREDIS_URLのいずれかは必須 | 必須チェック |
| BR-04 | JSONシリアライズ | データはJSON形式で保存 | set操作時 |
| BR-05 | プレフィックス付与 | 全キーにkeyPrefixを付与 | 全操作 |
| BR-06 | プレフィックス除去 | keys()の結果からはプレフィックスを除去 | keys操作時 |

### 計算ロジック

Redisキーの構成:
```typescript
`${keyPrefix}${key}`
// 例: 'payload-kv:session:abc123'
```

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

### 操作別Redis影響一覧

| 操作 | Redisコマンド | 概要 |
|------|--------------|------|
| get | GET | キーの値を取得 |
| set | SET | キーと値を設定 |
| delete | DEL | キーを削除 |
| has | EXISTS | キーの存在確認 |
| keys | KEYS | パターンマッチでキー一覧取得 |
| clear | KEYS + DEL | パターンマッチでキー一覧取得後、一括削除 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Error | redisURL未設定 | redisURLまたはREDIS_URL環境変数を設定 |
| - | Error | Redis接続失敗 | Redisサーバーの起動を確認 |
| - | Error | 認証失敗 | Redis認証情報を確認 |

### リトライ仕様

ioredisの内蔵リトライ機能に依存。

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

KVAdapter操作は個別に実行され、トランザクションは使用しない。

## パフォーマンス要件

- ioredisの接続プール機能を活用
- KEYS操作は大量キー時にパフォーマンス影響の可能性あり
- clear()も同様にKEYS + DELのため大量キー時は注意

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

- Redis認証の使用推奨（AUTH）
- TLS/SSL接続の使用推奨（本番環境）
- redisURLに認証情報を含める場合は環境変数で管理

## 備考

- ioredis（Node.js Redis client）を使用
- Redis 6.x以降を推奨
- Sentinel/Cluster構成もioredisの機能でサポート

---

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

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

### 推奨読解順序

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

アダプターの全体構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | index.ts | `packages/kv-redis/src/index.ts` | RedisKVAdapter、redisKVAdapter |

**主要処理フロー**:
1. **5-6行目**: RedisKVAdapterクラス定義
2. **8-12行目**: コンストラクタ（Redis接続）
3. **14-21行目**: clear()メソッド
4. **23-25行目**: delete()メソッド
5. **27-35行目**: get()メソッド
6. **37-40行目**: has()メソッド
7. **42-50行目**: keys()メソッド
8. **52-54行目**: set()メソッド
9. **57-66行目**: RedisKVAdapterOptions型
10. **68-79行目**: redisKVAdapter関数

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

```
redisKVAdapter (index.ts)
    │
    └─ init
           │
           └─ new RedisKVAdapter
                  │
                  ├─ new Redis(redisURL)
                  │
                  ├─ get → redisClient.get → JSON.parse
                  │
                  ├─ set → JSON.stringify → redisClient.set
                  │
                  ├─ delete → redisClient.del
                  │
                  ├─ has → redisClient.exists
                  │
                  ├─ keys → redisClient.keys → prefix除去
                  │
                  └─ clear → redisClient.keys → redisClient.del
```

### データフロー図

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

KV操作リクエスト ──────▶ RedisKVAdapter ─────────────▶ Redis操作
                              │
                    ┌─────────┼─────────┐
                    ▼         ▼         ▼
                  get       set      delete
                    │         │         │
                    ▼         ▼         ▼
              JSON.parse  JSON.stringify  -
                    │         │         │
                    ▼         ▼         ▼
              redis.get  redis.set  redis.del
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.ts | `packages/kv-redis/src/index.ts` | ソース | エントリーポイント |
