# 機能設計書 12-全パッド一覧取得

## 概要

本ドキュメントは、Etherpadにおける全パッド一覧取得機能（listAllPads）の設計仕様を定義する。この機能は、システム内に存在するすべてのパッドIDを一覧として取得するためのAPIを提供する。

### 本機能の処理概要

全パッド一覧取得機能は、Etherpadインスタンスに存在するすべてのパッドのIDをアルファベット順でソートして返却する機能である。内部でキャッシュ機構を使用し、効率的にパッド一覧を管理している。

**業務上の目的・背景**：
システム管理者がEtherpadインスタンス内のパッドを把握し、管理するために必要な機能である。パッドの棚卸し、不要パッドの特定、統計情報の取得、バックアップ対象の確認など、運用管理において基盤となる情報を提供する。また、外部システムとの連携時にパッド一覧を同期するためにも使用される。

**機能の利用シーン**：
- 管理画面でのパッド一覧表示
- パッドの棚卸し・クリーンアップ作業
- 外部システムへのパッド情報エクスポート
- 統計情報（総パッド数）の取得
- バックアップスクリプトでの対象パッド特定

**主要な処理内容**：
1. 認証情報の検証
2. キャッシュされたパッド一覧の取得
3. キャッシュがない場合はデータベースから一覧を構築
4. アルファベット順にソートして返却

**関連システム・外部連携**：
- REST API（GET /api/2/pads）を通じて外部システムから呼び出し可能
- 管理画面のパッド管理機能から内部的に利用

**権限による制御**：
- APIキーまたはOAuth2トークンによる認証が必要
- 認証されたユーザーはすべてのパッドIDを参照可能（パッド単位のアクセス制御はこの機能では行わない）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 10 | パッド管理画面 | 主画面 | すべてのパッドIDを一覧で取得して表示 |

## 機能種別

データ参照（Read操作）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| なし | - | - | 本APIはパラメータを必要としない | - |

### 入力データソース

REST API経由でのHTTPリクエスト（GET /api/2/pads）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| code | number | 結果コード（0: 成功、4: 認証エラー） |
| message | string | 結果メッセージ（"ok" または エラーメッセージ） |
| data | object | パッドID一覧を含むオブジェクト |
| data.padIDs | string[] | パッドIDの配列（アルファベット順） |

### 出力先

HTTPレスポンス（JSON形式）

## 処理フロー

### 処理シーケンス

```
1. APIリクエスト受信
   └─ GET /api/2/pads
2. 認証チェック
   └─ APIキーまたはOAuth2トークンの検証
3. パッド一覧取得
   └─ padList.getPads()を呼び出し
4. キャッシュ確認
   ├─ キャッシュあり: キャッシュから返却
   └─ キャッシュなし: DBから構築してキャッシュ
5. ソート処理
   └─ アルファベット順にソート
6. レスポンス返却
   └─ {code: 0, message: "ok", data: {padIDs: [...]}}
```

### フローチャート

```mermaid
flowchart TD
    A[開始: listAllPads API呼び出し] --> B{認証チェック}
    B -->|失敗| C[401 Unauthorized]
    B -->|成功| D[padList.getPads呼び出し]
    D --> E{キャッシュ存在?}
    E -->|Yes| F[キャッシュから一覧取得]
    E -->|No| G[DBから一覧構築]
    G --> H[pad:*キーを検索]
    H --> I[Setに追加]
    I --> J[キャッシュに保存]
    J --> K[ソート処理]
    F --> K
    K --> L[200 OK: padIDs返却]
    L --> M[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-012-01 | 全パッド返却 | グループパッドを含むすべてのパッドIDを返却 | 常時 |
| BR-012-02 | ソート順序 | アルファベット順（昇順）でソート | 常時 |
| BR-012-03 | キャッシュ利用 | 一度構築したリストはキャッシュし、パッド追加/削除時に更新 | 常時 |
| BR-012-04 | 空配列対応 | パッドが存在しない場合は空配列を返却 | パッドが0件の場合 |

### 計算ロジック

該当なし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 一覧取得 | pad:* | SELECT | pad:で始まるキーを検索（初回のみ） |

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

#### pad:{padID}（キャッシュミス時のみ）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | key | パターン `pad:*`、除外パターン `*:*:*` | revs:やchat:を除外 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 4 | authError | 認証情報が無効 | 正しいAPIキーまたはトークンを使用 |

### リトライ仕様

データベース操作に関してはueberDB2のリトライ機構に依存。通常、読み取り専用操作のためリトライは不要。

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

読み取り専用操作のため、トランザクション管理は不要。ただし、一覧取得中にパッドが追加/削除された場合、タイミングによっては古い情報が返却される可能性がある（結果整合性）。

## パフォーマンス要件

- キャッシュ利用により、2回目以降の呼び出しは高速
- 初回呼び出し時のDB検索は、パッド数に比例した時間がかかる
- 大量のパッドが存在する場合（数万件以上）、レスポンスサイズに注意

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

- APIキーまたはOAuth2認証が必須
- パッドの内容は返却しない（IDのみ）
- グループパッドのIDも返却されるため、グループ構造が推測可能

## 備考

- キャッシュはpadListオブジェクトで管理される
- パッド作成時にaddPad()、削除時にremovePad()でキャッシュが更新される
- グループパッドは `g.{groupID}${padName}` 形式で返却される

---

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

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

### 推奨読解順序

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

パッド一覧のキャッシュ構造を把握することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | PadManager.ts | `src/node/db/PadManager.ts` | padListクラスの定義（60-98行目） |

**読解のコツ**: padListはクラス式で即座にインスタンス化されるパターン。_list（Set）、_cachedList（ソート済み配列）、_loaded（初期化Promise）の3つの状態を持つ。

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

REST APIからの呼び出しフローを追跡する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RestAPI.ts | `src/node/handler/RestAPI.ts` | API定義（877-891行目でlistAllPadsのマッピング） |
| 2-2 | APIHandler.ts | `src/node/handler/APIHandler.ts` | パラメータ定義（79行目で引数なし） |

**主要処理フロー**:
1. **877-891行目**: GET /pads のルート定義
2. **79行目**: listAllPadsの引数定義（空配列）

#### Step 3: ビジネスロジックを理解する

実際の一覧取得ロジックを読み解く。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | API.ts | `src/node/db/API.ts` | listAllPadsのエクスポート（55行目） |
| 3-2 | PadManager.ts | `src/node/db/PadManager.ts` | listAllPads関数（146-150行目） |
| 3-3 | PadManager.ts | `src/node/db/PadManager.ts` | getPads関数（74-85行目） |

**主要処理フロー**:
- **PadManager.ts 74-85行目**: getPads関数 - キャッシュまたはDBから取得
- **PadManager.ts 77行目**: db.findKeys('pad:*', '*:*:*')でDBから検索
- **PadManager.ts 83行目**: ソートして返却

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

```
GET /api/2/pads (RestAPI.ts)
    │
    └─ apiHandler.handle() (APIHandler.ts)
           │
           └─ api.listAllPads() (API.ts:55)
                  │
                  └─ padManager.listAllPads() (PadManager.ts:146-150)
                         │
                         └─ padList.getPads() (PadManager.ts:74-85)
                                │
                                ├─ [キャッシュあり] this._cachedList返却
                                │
                                └─ [キャッシュなし]
                                       │
                                       ├─ db.findKeys('pad:*', '*:*:*')
                                       ├─ this.addPad() で Setに追加
                                       ├─ [...this._list].sort()
                                       └─ this._cachedList に保存
```

### データフロー図

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

(なし)        ───────▶ padList.getPads() ──────────▶ string[]
                              │
                              ├─▶ _loaded (Promise)
                              │       │
                              │       └─▶ db.findKeys()
                              │              │
                              │              └─▶ pad:* キー検索
                              │
                              ├─▶ _list (Set<string>)
                              │       └─▶ パッドID保持
                              │
                              └─▶ _cachedList (string[])
                                      └─▶ ソート済み配列
                              │
                              ▼
                       {padIDs: [...]} ───────▶ JSON Response
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| API.ts | `src/node/db/API.ts` | ソース | listAllPadsのエクスポート |
| PadManager.ts | `src/node/db/PadManager.ts` | ソース | padListクラス、listAllPads実装 |
| RestAPI.ts | `src/node/handler/RestAPI.ts` | ソース | REST APIエンドポイント定義 |
| APIHandler.ts | `src/node/handler/APIHandler.ts` | ソース | API呼び出しハンドリング |
| DB.ts | `src/node/db/DB.ts` | ソース | データベースアクセス層（findKeys） |
