# 機能設計書 35-チャットヘッド取得

## 概要

本ドキュメントは、Etherpadのチャットヘッド取得機能（getChatHead）の設計仕様を記載する。

### 本機能の処理概要

本機能は、指定されたパッドの最新チャットメッセージのID（chatHead）を取得するAPI機能である。これにより、チャット履歴の総数や最新メッセージの位置を把握できる。

**業務上の目的・背景**：パッドのチャット機能において、最新のメッセージ位置を知ることは重要である。この機能は、クライアントがチャット履歴を取得する際の範囲指定や、新着メッセージの有無確認に使用される。特にパッド参加時に直近100件のチャットを取得する際のパラメータ計算に利用される。

**機能の利用シーン**：パッド編集画面でのチャット初期化時、新着チャットの確認時、チャット履歴取得のパラメータ計算時など。

**主要な処理内容**：
1. パッドIDの検証
2. パッドオブジェクトの取得
3. chatHeadプロパティの取得
4. 結果を返却

**関連システム・外部連携**：REST API経由でHTTPリクエストを受け付け、JSON形式でレスポンスを返す。

**権限による制御**：APIキー認証またはSSO認証により、API呼び出しの認可を行う。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | パッド編集画面 | 主画面 | チャット初期化時に最新メッセージID取得 |

## 機能種別

データ取得（SELECT操作）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| padID | string | Yes | 対象パッドのID | 文字列型であること、パッドが存在すること |

### 入力データソース

REST API GETリクエストのクエリパラメータとしてpadIDを受け取る。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| code | integer | 結果コード（0: 成功） |
| message | string | 結果メッセージ（"ok"） |
| data.chatHead | integer | 最新チャットメッセージのID（-1: メッセージなし） |

### 出力先

HTTPレスポンスとしてJSON形式で返却

## 処理フロー

### 処理シーケンス

```
1. APIリクエスト受信
   └─ GET /api/2/pads/chatHead?padID=xxx
2. 認証・認可チェック
   └─ APIキーまたはSSOトークンの検証
3. パラメータ検証
   └─ padIDが文字列であることを確認
4. パッド存在確認・取得
   └─ padManager.getPadを呼び出し
5. chatHead取得
   └─ pad.chatHeadプロパティを参照
6. レスポンス生成・返却
   └─ {chatHead: number}形式で返却
```

### フローチャート

```mermaid
flowchart TD
    A[APIリクエスト受信] --> B{認証チェック}
    B -->|失敗| C[401 Unauthorized]
    B -->|成功| D{padID検証}
    D -->|不正| E[400 Bad Request]
    D -->|正常| F{パッド存在確認}
    F -->|存在しない| G[padID does not exist]
    F -->|存在する| H[chatHead取得]
    H --> I[JSONレスポンス返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-35-01 | パッド存在必須 | 指定されたパッドIDが存在しない場合はエラー | 常時 |
| BR-35-02 | 初期値 | チャットメッセージがない場合、chatHeadは-1 | メッセージなし時 |
| BR-35-03 | インクリメント | 新しいメッセージ追加ごとにchatHeadは1増加 | メッセージ追加時 |

### 計算ロジック

chatHeadはパッドのプロパティとして保存されており、チャットメッセージが追加されるたびにインクリメントされる。総メッセージ数は chatHead + 1 で計算できる。

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| パッド情報取得 | pad:{padID} | SELECT | パッドのメタ情報（chatHead含む）を取得 |

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

#### pad:{padID}

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | chatHead | キー: pad:{padID} | パッド全体のデータからchatHeadを取得 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 1 | apierror | padIDが文字列でない | 正しい形式のpadIDを指定 |
| 1 | apierror | パッドが存在しない | 存在するパッドIDを指定 |
| 4 | 認証エラー | APIキーが無効 | 正しいAPIキーを使用 |

### リトライ仕様

リトライは不要（冪等な読み取り操作のため）

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

読み取り専用操作のため、トランザクション管理は不要。

## パフォーマンス要件

- レスポンス時間: 100ms以内（通常条件下）
- パッド情報はメモリキャッシュされるため、高速なアクセスが可能

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

- APIキー認証またはSSO認証が必須
- パッドIDのバリデーションにより不正なアクセスを防止
- 読み取り専用操作のためデータ改ざんリスクなし

## 備考

API Version 1.2.7で追加された機能。クライアント接続時にclientVarsとしてchatHeadが送信されるため、通常はAPI呼び出しは不要。

---

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

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

### 推奨読解順序

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

まず、PadクラスのchatHeadプロパティを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Pad.ts | `src/node/db/Pad.ts` | chatHeadプロパティの定義（46行目）と初期値（63行目） |

**読解のコツ**: chatHeadは-1で初期化され、メッセージ追加ごとにインクリメントされる。

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

REST APIのエンドポイント定義を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RestAPI.ts | `src/node/handler/RestAPI.ts` | GET /pads/chatHeadのマッピング定義（957-992行目） |

**主要処理フロー**:
1. **957-992行目**: エンドポイント定義とgetChatHead関数へのマッピング

#### Step 3: API関数の実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | API.ts | `src/node/db/API.ts` | getChatHead関数の実装（804-808行目） |

**主要処理フロー**:
- **805-806行目**: パッド取得
- **807行目**: chatHeadを返却

#### Step 4: chatHeadの更新タイミングを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Pad.ts | `src/node/db/Pad.ts` | appendChatMessage()メソッド（334-345行目） |

**主要処理フロー**:
- **337行目**: chatHeadのインクリメント（this.chatHead++）

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

```
RestAPI.expressCreateServer
    │
    ├─ app.use('/api/2', ...)
    │      └─ apiHandler.handle('1.2.7', 'getChatHead', fields)
    │              └─ API.getChatHead(padID)
    │                      ├─ getPadSafe(padID, true)
    │                      └─ return {chatHead: pad.chatHead}
    │
    └─ res.json({chatHead})
```

### データフロー図

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

padID ───────────▶ getPadSafe() ───────────▶ Padオブジェクト
                           │
                           ▼
                   pad.chatHead ───────────▶ {chatHead: number}
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| API.ts | `src/node/db/API.ts` | ソース | getChatHead関数の実装 |
| Pad.ts | `src/node/db/Pad.ts` | ソース | PadクラスとchatHeadプロパティ |
| RestAPI.ts | `src/node/handler/RestAPI.ts` | ソース | REST APIエンドポイント定義 |
| PadMessageHandler.ts | `src/node/handler/PadMessageHandler.ts` | ソース | clientVarsでのchatHead送信 |
