# 画面設計書 31-カードコメント編集画面

## 概要

本ドキュメントは、Fizzyアプリケーションにおけるカードコメント編集画面の設計仕様を記述したものです。

### 本画面の処理概要

カードコメント編集画面は、ユーザーが自分自身で投稿したコメントを編集または削除するための画面です。Turbo Frameを活用したインライン編集形式で提供され、コメント詳細表示からシームレスに編集モードへ移行できます。

**業務上の目的・背景**：カンバンボード上のカードに対するコメントは、チームコミュニケーションの重要な手段です。誤字脱字の修正や、情報のアップデートなど、投稿後にコメントを編集したいケースは頻繁に発生します。また、不要になったコメントを削除する機能も必要です。本画面は、コメント作成者に限定して編集・削除機能を提供し、コミュニケーションの質を維持しつつ、誤操作による重要情報の消失を防ぎます。

**画面へのアクセス方法**：カード詳細画面のコメント一覧から、自分が投稿したコメントの編集ボタン（鉛筆アイコン）をクリックすることでアクセスできます。

**主要な操作・処理内容**：
1. コメント本文をリッチテキストエディタで編集
2. 「Save」ボタンで編集内容を保存
3. 「Cancel」ボタンまたはEscキーで編集をキャンセル
4. 「Delete」ボタン（ゴミ箱アイコン）でコメントを削除

**画面遷移**：
- 遷移元：カード詳細画面、カードコメント詳細画面
- 遷移先：カード詳細画面（保存/キャンセル/削除後）

**権限による表示制御**：コメントの作成者（creator）のみが編集画面にアクセス可能です。他のユーザーがアクセスしようとした場合は403 Forbiddenが返されます。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 47 | コメント編集 | 主機能 | 自分のコメントを編集 |
| 48 | コメント削除 | 補助機能 | 自分のコメントを削除 |

## 画面種別

編集

## URL/ルーティング

- **パス**: `/cards/:card_id/comments/:id/edit`
- **HTTPメソッド**: GET
- **コントローラ**: `Cards::CommentsController#edit`

## 入出力項目

| 項目名 | 項目ID | 入出力 | データ型 | 必須 | 最大長 | 説明 |
|--------|--------|--------|----------|------|--------|------|
| コメント本文 | body | 入力 | rich_text | 必須 | - | ActionTextによるリッチテキスト |
| カードID | card_id | パラメータ | UUID | 必須 | - | 対象カードのID |
| コメントID | id | パラメータ | UUID | 必須 | - | 編集対象コメントのID |

## 表示項目

| 項目名 | 説明 | データ取得元 |
|--------|------|-------------|
| コメント作成者アバター | コメント作成者のプロフィール画像 | @comment.creator |
| コメント本文入力欄 | リッチテキストエディタ | @comment.body |
| Saveボタン | 編集内容保存用ボタン | - |
| Cancelボタン | 編集キャンセル用リンク | - |
| Deleteボタン | コメント削除用ボタン | - |

## イベント仕様

### 1-Save（保存）

コメントの編集内容を保存します。

- **トリガー**: Saveボタンクリック、Ctrl+Enter、Cmd+Enter
- **処理フロー**:
  1. フォームデータをPATCH `/cards/:card_id/comments/:id` に送信
  2. `Cards::CommentsController#update` でバリデーション・保存
  3. Turbo Streamでコメント表示を更新
- **成功時**: コメント詳細表示に戻り、更新内容が反映される
- **失敗時**: バリデーションエラーを表示

### 2-Cancel（キャンセル）

編集をキャンセルし、元の表示に戻ります。

- **トリガー**: Cancelボタンクリック、Escキー
- **処理フロー**:
  1. 編集フレームを閉じる
  2. コメント詳細画面に戻る
- **データ更新**: なし

### 3-Delete（削除）

コメントを削除します。

- **トリガー**: Deleteボタン（ゴミ箱アイコン）クリック
- **処理フロー**:
  1. 確認ダイアログ「Are you sure you want to delete this comment?」を表示
  2. 確認後、DELETE `/cards/:card_id/comments/:id` に送信
  3. `Cards::CommentsController#destroy` でコメントを削除
  4. Turbo Streamでコメント要素を削除
- **成功時**: コメントがリストから削除される
- **失敗時**: 権限エラー（403）

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| Save（保存） | comments | UPDATE | コメントの更新日時を更新 |
| Save（保存） | action_text_rich_texts | UPDATE | コメント本文を更新 |
| Save（保存） | cards | UPDATE | touch によりupdated_atを更新 |
| Delete（削除） | comments | DELETE | コメントレコードを削除 |
| Delete（削除） | action_text_rich_texts | DELETE | コメント本文を削除 |
| Delete（削除） | reactions | DELETE | コメントに紐づくリアクションを削除 |

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

#### comments

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | updated_at | 現在時刻 | 自動更新 |
| DELETE | - | id = params[:id] | カスケード削除あり |

#### action_text_rich_texts

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | body | フォーム入力値 | リッチテキスト本文 |
| UPDATE | updated_at | 現在時刻 | 自動更新 |

#### cards

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | updated_at | 現在時刻 | touch: trueによる自動更新 |

## メッセージ仕様

| 種別 | メッセージID | メッセージ内容 | 表示条件 |
|------|------------|---------------|---------|
| 確認 | confirm_delete | Are you sure you want to delete this comment? | 削除ボタン押下時 |
| エラー | forbidden | 403 Forbidden | 作成者以外がアクセス時 |

## 例外処理

| 例外 | 発生条件 | 処理内容 |
|-----|---------|---------|
| RecordNotFound | コメントが存在しない | 404エラーページを表示 |
| Forbidden | 作成者以外がアクセス | 403ステータスを返却 |
| ValidationError | 本文が空 | フォームにエラーを表示 |

## 備考

- リッチテキストエディタはAction Textを使用
- キーボードショートカット対応（Ctrl/Cmd+Enter: 保存、Esc: キャンセル）
- 削除時は確認ダイアログ（turbo_confirm）を表示
- Turbo Frameを使用したインライン編集形式

---

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

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

### 推奨読解順序

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

コメントのデータモデルと関連するリッチテキストの構造を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | comment.rb | `app/models/comment.rb` | コメントモデルの定義、リレーション、バリデーション |
| 1-2 | schema.rb | `db/schema.rb` | commentsテーブル（252-260行目）、action_text_rich_textsテーブル（72-82行目）の構造 |

**読解のコツ**: Commentモデルは`has_rich_text :body`でAction Textを使用しています。`belongs_to :creator`でユーザーとの関連、`belongs_to :card, touch: true`でカードの自動更新が設定されています。

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

コントローラのeditアクションを確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | comments_controller.rb | `app/controllers/cards/comments_controller.rb` | edit, update, destroyアクションの実装 |

**主要処理フロー**:
1. **4行目**: `before_action :set_comment` でコメントを取得
2. **5行目**: `before_action :ensure_creatorship` で作成者チェック
3. **24-25行目**: editアクションは単にビューをレンダリング
4. **27-33行目**: updateアクションでコメントを更新
5. **36-42行目**: destroyアクションでコメントを削除

#### Step 3: ビューレイヤーを理解する

編集フォームのテンプレートを確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | edit.html.erb | `app/views/cards/comments/edit.html.erb` | 編集フォームの構造、Turbo Frame、キーボードショートカット |

**主要処理フロー**:
- **1行目**: `turbo_frame_tag @comment, :container` でTurbo Frameを定義
- **9-28行目**: form_withによるフォーム、Stimulusコントローラの設定
- **10行目**: keydownイベントでCtrl+Enter/Cmd+Enterで送信、Escでキャンセル
- **11-13行目**: rich_textareaによるリッチテキスト入力欄
- **22-26行目**: 削除ボタンとturbo_confirm

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

```
Cards::CommentsController#edit
    │
    ├─ CardScoped#set_card (card_id から @card を取得)
    │
    ├─ set_comment (@card.comments.find で @comment を取得)
    │
    ├─ ensure_creatorship (Current.user と @comment.creator を比較)
    │
    └─ render edit.html.erb
           │
           ├─ turbo_frame_tag
           │
           ├─ avatar_tag (@comment.creator のアバター表示)
           │
           ├─ form_with
           │      └─ rich_textarea :body
           │
           └─ form_with (削除用フォーム)
```

### データフロー図

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

URLパラメータ           CommentsController#edit
  card_id ─────────────▶ @card 取得
  comment_id ──────────▶ @comment 取得 ──────────────▶ edit.html.erb
                              │
                        ensure_creatorship
                              │
                        権限チェック ─────────────────▶ 403 or 続行

フォーム入力             CommentsController#update
  body ────────────────▶ @comment.update! ────────────▶ Turbo Stream
                              │                              │
                        action_text_rich_texts          コメント表示更新
                              更新

削除ボタン              CommentsController#destroy
  確認後 ──────────────▶ @comment.destroy ────────────▶ Turbo Stream
                                                            │
                                                       コメント削除
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| comments_controller.rb | `app/controllers/cards/comments_controller.rb` | コントローラ | コメントのCRUD処理 |
| edit.html.erb | `app/views/cards/comments/edit.html.erb` | テンプレート | 編集フォームの表示 |
| comment.rb | `app/models/comment.rb` | モデル | コメントのデータ定義 |
| card_scoped.rb | `app/controllers/concerns/card_scoped.rb` | コンサーン | カード取得の共通処理 |
| routes.rb | `config/routes.rb` | 設定 | ルーティング定義（99-101行目） |
| schema.rb | `db/schema.rb` | スキーマ | DBテーブル定義 |
