# 機能設計書 47-コメント承認/非承認

## 概要

本ドキュメントは、LEGACY CMSのコメント管理機能における「コメント承認/非承認」機能の設計仕様を定義する。

### 本機能の処理概要

投稿されたコメントの承認ステータスを切り替えるモデレーション機能である。管理者は未承認コメントを承認して公開可能にしたり、承認済みコメントを非承認にして非公開にしたりできる。この機能により、サイトに表示されるコメントの品質を管理できる。

**業務上の目的・背景**：ユーザー投稿型のCMSでは、コメントの品質管理（モデレーション）が重要である。事前承認制を採用している場合、投稿されたコメントは管理者の承認を得てから公開される。また、承認済みのコメントでも、後から問題が発覚した場合は非承認に切り替えて非公開にできる。これにより、サイトの品質と安全性を維持できる。

**機能の利用シーン**：新規投稿コメントの承認作業、問題のあるコメントの非承認への切り替え、誤って非承認にしたコメントの再承認など、コメントの公開状態を管理する際に使用される。

**主要な処理内容**：
1. 対象コメントIDと新しいステータスの取得
2. commentsテーブルのcomment_approvedカラムを更新
3. 承認/非承認完了メッセージの表示

**関連システム・外部連携**：Dojo Toolkitを使用したAjaxダイアログで操作インターフェースを実現している。

**権限による制御**：`gcomments`（コメントモジュールアクセス権限）と`gcommentsstatus`（コメントステータス変更権限）の両方を持つユーザーのみがコメントの承認状態を変更できる。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 85 | コメント管理画面 | 遷移元画面 | 承認/非承認操作の実行 |
| 86 | コメント表示画面 | 遷移元画面 | コメントの承認ステータス切り替え |

## 機能種別

CRUD操作（Update） / Ajaxダイアログ処理 / ステータス変更

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| id | integer | Yes | 対象コメントのID | URLパラメータから取得 |
| status | string | Yes | 新しい承認ステータス（Y:承認, N:非承認） | Y または N |
| ajax | integer | No | Ajaxモードフラグ（1の場合はページリロードなし） | 0または1 |

### 入力データソース

- id: URLパラメータから取得（/admin/comments/approve/id/{id}/status/{status}/）
- status: URLパラメータから取得
- ajax: URLパラメータから取得

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 完了メッセージ | HTML | 「Comment approved」または「Comment disapproved」のメッセージと閉じるボタン |

### 出力先

- Ajaxダイアログ内にHTMLレスポンスとして出力
- commentsテーブルのcomment_approvedカラムを更新

## 処理フロー

### 処理シーケンス

```
1. リクエスト受信
   └─ approveActionがコールされる
2. 権限チェック
   └─ gcomments AND gcommentsstatus権限を確認
3. レイアウト・ビュー無効化
   └─ Ajaxレスポンス用に無効化
4. パラメータ取得
   └─ id, status, ajaxパラメータを取得
5. ステータス判定
   └─ status='Y'の場合: 承認処理
   └─ status='N'の場合: 非承認処理
6. データベース更新
   └─ comment_approvedカラムを更新
7. 完了レスポンス出力
   └─ ajaxフラグに応じたCloseボタンを表示
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{権限チェック}
    B -->|NG| C[権限エラー画面へ]
    B -->|OK| D[レイアウト・ビュー無効化]
    D --> E{id AND status設定?}
    E -->|No| F[終了]
    E -->|Yes| G{status='Y'?}
    G -->|Yes| H[comment_approved='Y'に更新]
    H --> I[「Comment approved」表示]
    G -->|No| J{status='N'?}
    J -->|Yes| K[comment_approved='N'に更新]
    K --> L[「Comment disapproved」表示]
    J -->|No| F
    I --> M{ajax=1?}
    L --> M
    M -->|Yes| N[リロードなしCloseボタン]
    M -->|No| O[リロードありCloseボタン]
    N --> F
    O --> F
    C --> F
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-47-01 | 権限チェック | gcommentsとgcommentsstatus権限が必要 | 常時 |
| BR-47-02 | 承認値 | comment_approved='Y'で承認状態 | 承認時 |
| BR-47-03 | 非承認値 | comment_approved='N'で非承認状態 | 非承認時 |
| BR-47-04 | 公開制御 | 承認状態のコメントのみサイトに表示 | フロントエンド表示時 |

### 計算ロジック

特になし。

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 承認/非承認 | comments | UPDATE | 承認ステータスを更新 |

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

#### comments

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | comment_approved | 'Y' または 'N' | 承認ステータス |
| WHERE | comment_id | = {id} | 更新対象の条件 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 権限エラー | gcomments/gcommentsstatus権限なし | privileges画面へフォワード |

### リトライ仕様

特になし。ステータス変更は冪等性を持つため、同じリクエストを複数回実行しても結果は同じ。

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

単一のUPDATE操作のため、明示的なトランザクション制御は行っていない。

## パフォーマンス要件

- Ajaxレスポンス時間: 1秒以内
- レイアウトとビューを無効化することでレスポンスサイズを最小化

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

- ACLによるアクセス制御（gcomments, gcommentsstatus権限の確認）
- statusパラメータは'Y'または'N'のみを受け付ける

## 備考

- フロントエンドのコメント取得時にcomment_approved='Y'でフィルタリングすることで、承認済みコメントのみが表示される
- 非承認コメントは削除されるわけではなく、データベースに残る
- ajax=1の場合はダイアログを閉じてもページリロードしない（タブ内での操作想定）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | database.sql | `database.sql` | commentsテーブルのcomment_approvedカラム（94行目） |

**読解のコツ**: comment_approvedはvarchar(1)で、デフォルト値は'N'（非承認）。'Y'で承認状態を表す。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | CommentsController.php | `application/modules/admin/controllers/CommentsController.php` | approveActionメソッド（210-287行目） |

**主要処理フロー**:
1. **212行目**: ACL権限チェック（gcomments AND gcommentsstatus）
2. **214-215行目**: レイアウト・ビューレンダラー無効化
3. **217-219行目**: id, status, ajaxパラメータ取得
4. **221行目**: id AND statusの存在チェック
5. **223-248行目**: status='Y'の場合の承認処理
6. **250-276行目**: status='N'の場合の非承認処理

#### Step 3: フロントエンドとの連携を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | CommentsController.php (default) | `application/modules/default/controllers/CommentsController.php` | commentsAction（18-31行目） |

**読解のコツ**: フロントエンド側のコメント取得では、24行目で`status='Y'`パラメータを設定し、承認済みコメントのみを取得している。

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

```
Admin_CommentsController::approveAction()
    │
    ├─ $this->view->acl->isAllowed()
    │      └─ 権限チェック（gcomments AND gcommentsstatus）
    │
    ├─ $this->_helper->layout()->disableLayout()
    │      └─ レイアウト無効化
    │
    ├─ $this->_helper->viewRenderer->setNoRender(true)
    │      └─ ビューレンダラー無効化
    │
    └─ $registry->db->update('comments', $data, 'comment_id = '.$id)
           └─ MySQLへのUPDATE実行
                  └─ comment_approved = 'Y' または 'N'
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| CommentsController.php | `application/modules/admin/controllers/CommentsController.php` | コントローラー | 承認/非承認アクションの定義 |
| CommentsController.php | `application/modules/default/controllers/CommentsController.php` | コントローラー | フロントエンド側のコメント表示 |
| Comments.php | `application/models/Comments.php` | モデル | コメント取得（statusフィルター） |
| database.sql | `database.sql` | スキーマ | commentsテーブル定義 |
| comments.js | `public/_scripts/admin/comments.js` | JavaScript | approveComment関数 |
