# 画面設計書 93-コメント一覧

## 概要

本ドキュメントは、Ghost公開画面における「コメント一覧」（Comments UI）の画面設計書です。投稿記事に対するコメントを表示し、会員によるコメント投稿・返信機能を提供するウィジェットです。

### 本画面の処理概要

コメント一覧は、Ghost公開サイトの投稿ページに埋め込まれるコメントウィジェットのメインコンテンツ領域です。

**業務上の目的・背景**：投稿記事に対する読者のエンゲージメントを促進し、コミュニティ形成を支援します。会員限定または有料会員限定でコメント機能を提供することで、会員登録・購読の動機付けとしても機能します。

**画面へのアクセス方法**：
- Ghostテーマの投稿テンプレートに `{{comments}}` ヘルパーを追加
- URLハッシュ `#ghost-comments` で自動スクロール
- コメントパーマリンク機能（Labs有効時）による特定コメントへの直接リンク

**主要な操作・処理内容**：
1. 投稿に対するコメント一覧の表示（ページネーション付き）
2. コメントのソート順変更（Best / Newest / Oldest）
3. メインコメント投稿フォームの表示
4. 各コメントへの返信・編集・削除・いいね
5. コメントの報告（通報）機能
6. CTA（Call To Action）ボックスによる会員登録促進

**画面遷移**：
- 画面内遷移: コメント投稿フォーム、返信フォーム、各種ポップアップ
- 外部遷移: サインインページ（未ログイン時のCTAクリック）

**権限による表示制御**：
- ログイン済み会員: コメント投稿フォームを表示
- 未ログインユーザー: CTAボックス（サインイン/サインアップ促進）を表示
- 有料会員限定投稿: 該当ティアの会員のみコメント可能
- コメント無効設定時: CommentingDisabledBoxを表示

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 25 | 記事コメント | 主機能 | 投稿へのコメント一覧表示 |
| 72 | Comments UI | 補助機能 | コメントUIウィジェットの表示 |

## 画面種別

一覧

## URL/ルーティング

- URLハッシュ: `#ghost-comments` （コメントセクションへのスクロール）
- コメントパーマリンク: `#comment-{commentId}` （Labs有効時）

## 入出力項目

| 項目名 | 入出力 | データ型 | 必須 | 説明 |
|--------|--------|----------|------|------|
| postId | 入力 | string | 必須 | 対象投稿のID |
| comments | 出力 | Comment[] | - | コメントリスト |
| pagination | 出力 | Pagination | - | ページネーション情報 |
| commentCount | 出力 | number | - | 総コメント数 |
| order | 入出力 | string | - | ソート順（best/newest/oldest） |

## 表示項目

| 項目名 | データ型 | 説明 |
|--------|----------|------|
| title | string | コメントセクションのタイトル |
| showCount | boolean | コメント数を表示するかどうか |
| commentCount | number | 総コメント数 |
| comments | Comment[] | コメントの配列 |
| comment.id | string | コメントID |
| comment.html | string | コメント本文（HTML） |
| comment.member | Member | コメント投稿者情報 |
| comment.created_at | string | 作成日時 |
| comment.edited_at | string | 編集日時 |
| comment.count.likes | number | いいね数 |
| comment.count.replies | number | 返信数 |
| comment.liked | boolean | 現在のユーザーがいいねしたか |
| comment.replies | Comment[] | 返信コメント配列 |

## イベント仕様

### 1-ソート順変更（setOrder）

ソートフォームでの選択変更時にコメントの並び順を変更します。

- 処理: `dispatchAction('setOrder', {order})` を実行
- 選択肢: 'best'（人気順）, 'newest'（新しい順）, 'oldest'（古い順）
- 再取得: ソート順変更後、APIから再取得

### 2-ページネーション

さらにコメントを読み込む際にページネーションを実行します。

- 処理: `dispatchAction('loadMoreComments')` を実行
- 条件: pagination.page < pagination.pages の場合に「Load more」ボタン表示

### 3-コメントハイライト・スクロール

特定コメントへのスクロールとハイライト表示を行います。

- 処理: `scrollToComment(element, commentId)` → `dispatchAction('highlightComment', {commentId})`
- トリガー: URLハッシュ変更、commentIdToScrollTo状態の変更

### 4-CTAボックスクリック

未ログインユーザー向けのCTAボタンクリック時の処理です。

- 処理: Portalの`data-portal`属性によるサインインページ表示

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| コメント表示 | comments | SELECT | コメント一覧の取得 |
| ソート変更 | comments | SELECT | ソート順を変更して再取得 |
| ページネーション | comments | SELECT | 追加コメントの取得 |

### テーブル別更新項目詳細

#### comments（SELECT）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | post_id | 対象投稿のID | フィルタ条件 |
| SELECT | status | 'published' | 公開済みのみ取得 |
| SELECT | * | ORDER BY order | ソート順に従う |

## メッセージ仕様

| メッセージID | 種別 | 表示条件 | メッセージ内容 |
|-------------|------|---------|--------------|
| MSG001 | 情報 | タイトル | 設定されたタイトルまたはデフォルト |
| MSG002 | ラベル | ソートフォーム | "Sort by:" |
| MSG003 | ラベル | コメント0件時 | "Start the conversation" |
| MSG004 | ラベル | コメントあり時 | "Join the discussion" |

## 例外処理

| 例外種別 | 発生条件 | 対応処理 |
|---------|---------|---------|
| コメント取得エラー | APIエラー | エラーメッセージ表示 |
| 権限なし | 有料会員限定投稿へのアクセス | CTAボックス表示 |
| コメント無効 | 投稿のコメント設定が無効 | CommentingDisabledBox表示 |

## 備考

- iframeとして埋め込まれるため、ResizeObserverで高さ変更を監視
- コメントパーマリンク機能はLabs機能（commentPermalinks）として提供
- ダークモード対応（colorScheme設定）

---

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

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

### 推奨読解順序

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

まず、コメントデータの型定義とアプリケーションコンテキストを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | app-context.ts | `apps/comments-ui/src/app-context.ts` | Comment型、Member型、AppContextType（1-133行目） |
| 1-2 | actions.ts | `apps/comments-ui/src/actions.ts` | アクションの種類と処理内容 |

**読解のコツ**: TypeScriptの型定義を先に読むことで、データ構造を正確に把握できる。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | app.tsx | `apps/comments-ui/src/app.tsx` | アプリケーションのルートコンポーネント |
| 2-2 | pages.ts | `apps/comments-ui/src/pages.ts` | ページ定義 |

**主要処理フロー**:
1. App.tsx: AppContextProviderでコンテキストを提供
2. 初期化時にコメントを取得（initStatus: 'loading' → 'success'）

#### Step 3: メインコンテンツを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | content.tsx | `apps/comments-ui/src/components/content/content.tsx` | メインコンテンツコンポーネント（74-189行目） |
| 3-2 | content-title.tsx | `apps/comments-ui/src/components/content/content-title.tsx` | タイトル表示 |
| 3-3 | sorting-form.tsx | `apps/comments-ui/src/components/content/forms/sorting-form.tsx` | ソートフォーム |
| 3-4 | pagination.tsx | `apps/comments-ui/src/components/content/pagination.tsx` | ページネーション |

**主要処理フロー**:
- **74-76行目**: useLabs, useAppContextでコンテキスト取得
- **144-150行目**: 表示条件の判定（canComment, showDisabledBox, showCtaBox）
- **152行目**: comments.mapでコメントコンポーネントを生成
- **154-185行目**: JSXレンダリング

#### Step 4: コメントコンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | comment.tsx | `apps/comments-ui/src/components/content/comment.tsx` | 個別コメントコンポーネント |
| 4-2 | cta-box.tsx | `apps/comments-ui/src/components/content/cta-box.tsx` | CTAボックス |
| 4-3 | commenting-disabled-box.tsx | `apps/comments-ui/src/components/content/commenting-disabled-box.tsx` | コメント無効時の表示 |

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

```
App.tsx (AppContextProvider)
    │
    └─ Frame (iframe wrapper)
           │
           └─ Pages (page routing)
                  │
                  └─ Content
                         │
                         ├─ ContentTitle (タイトル + コメント数)
                         │
                         ├─ MainForm (ログイン時) / CTABox (未ログイン時) / CommentingDisabledBox
                         │
                         ├─ SortingForm (ソート選択)
                         │
                         ├─ Comment[] (コメント一覧)
                         │      │
                         │      ├─ Avatar
                         │      ├─ CommentHeader
                         │      ├─ CommentBody
                         │      ├─ CommentMenu (編集/削除/報告)
                         │      ├─ LikeButton
                         │      └─ ReplyForm / EditForm (展開時)
                         │
                         └─ Pagination
```

### データフロー図

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

postId ────────────────▶ API: GET /comments ────────▶ comments[]
                                                      │
order (sort) ──────────▶ dispatchAction('setOrder') ──│
                                                      │
pagination.page ───────▶ dispatchAction('loadMore') ──│
                                                      ▼
                        Content Component ──────────▶ UI表示
                        │                            (コメント一覧)
                        │
member/isMember ───────▶ 権限判定 ─────────────────▶ MainForm / CTABox
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| content.tsx | `apps/comments-ui/src/components/content/content.tsx` | ソース | メインコンテンツコンポーネント |
| app-context.ts | `apps/comments-ui/src/app-context.ts` | ソース | コンテキスト定義、型定義 |
| app.tsx | `apps/comments-ui/src/app.tsx` | ソース | アプリケーションルート |
| comment.tsx | `apps/comments-ui/src/components/content/comment.tsx` | ソース | 個別コメントコンポーネント |
| content-title.tsx | `apps/comments-ui/src/components/content/content-title.tsx` | ソース | タイトル表示 |
| sorting-form.tsx | `apps/comments-ui/src/components/content/forms/sorting-form.tsx` | ソース | ソートフォーム |
| pagination.tsx | `apps/comments-ui/src/components/content/pagination.tsx` | ソース | ページネーション |
| cta-box.tsx | `apps/comments-ui/src/components/content/cta-box.tsx` | ソース | CTAボックス |
| commenting-disabled-box.tsx | `apps/comments-ui/src/components/content/commenting-disabled-box.tsx` | ソース | コメント無効時表示 |
| actions.ts | `apps/comments-ui/src/actions.ts` | ソース | アクション定義 |
| helpers.ts | `apps/comments-ui/src/utils/helpers.ts` | ソース | ユーティリティ関数 |
