# 画面設計書 61-リアクション追加画面

## 概要

本ドキュメントは、Fizzyアプリケーションにおけるリアクション追加画面の設計仕様を定義するものである。

### 本画面の処理概要

この画面は、カードまたはコメントに対して絵文字リアクションを追加するためのインライン編集フォームを提供する。ユーザーはテキスト入力フィールドに直接絵文字を入力するか、プリセットされた絵文字メニューから選択してリアクションを送信できる。

**業務上の目的・背景**：チーム内のコミュニケーションを活性化し、カードやコメントに対する簡易的なフィードバック手段を提供する。テキストによる返信よりも軽量なコミュニケーション手段として、賛同・感謝・注目などの意思表示を素早く行うことができる。これにより、チームメンバー間の相互理解と協働を促進する。

**画面へのアクセス方法**：カード詳細画面またはコメント表示部分にある「リアクション追加」ボタン（+アイコン）をクリックすることで、Turbo Frameを通じてこの入力フォームが展開される。

**主要な操作・処理内容**：
1. 絵文字入力フィールドへの直接入力またはメニューからの絵文字選択
2. チェックボタンを押下してリアクションを送信
3. キャンセルボタンを押下してフォームを閉じる
4. Escキーを押下してフォームをキャンセル

**画面遷移**：
- 遷移元：カード詳細画面、カードコメント詳細画面
- 遷移先：リアクション追加後は元の画面（カード詳細画面またはコメント詳細画面）に戻り、新しいリアクションが表示される

**権限による表示制御**：ログイン済みユーザーのみがリアクションを追加可能。リアクション対象（カードまたはコメント）への閲覧権限が必要。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 49 | カードにリアクション | 主機能 | リアクションを追加 |
| 50 | カードのリアクション削除 | 補助機能 | カードに付けたリアクションを削除 |

## 画面種別

登録（インラインフォーム）

## URL/ルーティング

- カードへのリアクション追加: `GET /cards/:card_id/reactions/new`
- コメントへのリアクション追加: `GET /cards/:card_id/comments/:comment_id/reactions/new`

## 入出力項目

| 項目名 | 項目ID | データ型 | 必須 | 最大長 | 入力形式 | 説明 |
|--------|--------|----------|------|--------|----------|------|
| リアクション内容 | content | string | 必須 | 16文字 | テキスト | 絵文字または短いテキスト |

## 表示項目

| 項目名 | 説明 |
|--------|------|
| ユーザーアバター | 現在のログインユーザーのアバター画像 |
| リアクション入力フィールド | 絵文字を入力するテキストフィールド |
| 絵文字メニュー | プリセットの絵文字を選択するためのポップアップメニュー |
| 送信ボタン | リアクションを送信するボタン（チェックマークアイコン） |
| キャンセルボタン | フォームを閉じるボタン（クローズアイコン） |

## イベント仕様

### 1-絵文字メニューボタン押下

絵文字メニューのダイアログがポップアップ表示される。ダイアログ内には45種類のプリセット絵文字が表示され、クリックで選択可能。

### 2-絵文字選択

プリセットメニューから絵文字を選択すると、入力フィールドに絵文字が挿入され、ダイアログが閉じる。

### 3-送信ボタン押下

1. 入力内容のバリデーション（空文字チェック、最大16文字チェック）
2. `POST /cards/:card_id/reactions` にリアクション作成リクエスト送信
3. Turbo Streamによりリアクション一覧が更新される
4. フォームが閉じ、新しいリアクションが表示される

### 4-キャンセルボタン押下・Escキー押下

フォームが閉じ、リアクション一覧表示に戻る。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 送信ボタン押下 | reactions | INSERT | 新規リアクションレコードを作成 |
| 送信ボタン押下 | cards | UPDATE | カードのlast_active_atを更新（touch） |

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

#### reactions

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | id | UUID自動生成 | 主キー |
| INSERT | account_id | reactable.account_id | リアクション対象のアカウントID |
| INSERT | content | フォーム入力値 | 最大16文字 |
| INSERT | reactable_type | "Card" または "Comment" | ポリモーフィック関連 |
| INSERT | reactable_id | 対象カードまたはコメントのID | ポリモーフィック関連 |
| INSERT | reacter_id | Current.user.id | リアクションしたユーザー |
| INSERT | created_at | 現在日時 | 自動設定 |
| INSERT | updated_at | 現在日時 | 自動設定 |

## メッセージ仕様

| メッセージ種別 | メッセージ内容 | 表示条件 |
|---------------|---------------|----------|
| 成功 | （メッセージなし、リアクションが追加表示される） | リアクション作成成功時 |
| エラー | バリデーションエラー | 入力内容が不正な場合 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| 未認証アクセス | ログイン画面へリダイレクト |
| 対象カード/コメントが見つからない | 404エラー |
| 権限不足 | 403 Forbidden |

## 備考

- 絵文字メニューには45種類のプリセット絵文字が含まれる（EmojiHelper::REACTIONSで定義）
- Turbo Frameを使用したインライン編集により、ページ遷移なしでリアクションを追加可能
- IME入力（日本語変換など）中の誤送信を防ぐため、compositionstart/compositionendイベントを監視

---

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

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

### 推奨読解順序

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

まず、リアクションのデータ構造とポリモーフィック関連を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | reaction.rb | `app/models/reaction.rb` | リアクションモデルの定義、ポリモーフィック関連（reactable）、スコープ |
| 1-2 | schema.rb | `db/schema.rb` | reactionsテーブルの構造（431-442行目） |

**読解のコツ**: Railsのポリモーフィック関連（`belongs_to :reactable, polymorphic: true`）により、CardとCommentの両方にリアクションを付けられる仕組みを理解する。

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

リアクション追加のリクエスト処理フローの起点。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | reactions_controller.rb | `app/controllers/cards/reactions_controller.rb` | new/createアクションの処理フロー |

**主要処理フロー**:
1. **11-13行目**: indexアクション - リアクション一覧を表示
2. **15-17行目**: newアクション - 新規リアクションフォームを表示
3. **19-25行目**: createアクション - リアクションを作成しTurbo Streamで応答
4. **38-40行目**: set_reactable - 対象カードを@reactableに設定

#### Step 3: ビューテンプレートを理解する

フォームのUIと動作を定義するテンプレート。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | new.html.erb | `app/views/reactions/new.html.erb` | メインのフォームテンプレート |
| 3-2 | _menu.html.erb | `app/views/reactions/_menu.html.erb` | 絵文字選択メニューのパーシャル |

**主要処理フロー**:
- **1行目**: turbo_frame_tagでTurbo Frame領域を定義
- **2-5行目**: form_withでフォームを構築、Stimulus controllerを設定
- **11-12行目**: テキスト入力フィールド（最大16文字、パターンバリデーション付き）
- **15行目**: 絵文字メニューパーシャルをレンダリング
- **17-19行目**: 送信ボタン
- **21-24行目**: キャンセルボタン

#### Step 4: ヘルパーとStimulusコントローラーを理解する

絵文字データとフロントエンド動作。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | emoji_helper.rb | `app/helpers/emoji_helper.rb` | プリセット絵文字の定義（REACTIONS定数） |

**主要処理フロー**:
- **2-53行目**: 45種類の絵文字とそのタイトル（説明）のハッシュ定義

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

```
[ユーザー] リアクション追加ボタンクリック
    │
    ├─ GET /cards/:card_id/reactions/new
    │      │
    │      └─ Cards::ReactionsController#new
    │             │
    │             └─ render "reactions/new"
    │                    │
    │                    ├─ turbo_frame_tag
    │                    │
    │                    └─ render "reactions/menu"
    │
    └─ POST /cards/:card_id/reactions（送信時）
           │
           └─ Cards::ReactionsController#create
                  │
                  ├─ @reactable.reactions.create!
                  │      │
                  │      └─ Reaction.after_create :register_card_activity
                  │
                  └─ render "reactions/create" (Turbo Stream)
```

### データフロー図

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

絵文字入力/選択 ───────▶ ReactionsController#create ───────▶ Turbo Stream応答
                              │
                              ├─ Reaction.create!
                              │      │
                              │      └─ reactions テーブルにINSERT
                              │
                              └─ card.touch_last_active_at
                                     │
                                     └─ cards テーブルをUPDATE
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| reactions_controller.rb | `app/controllers/cards/reactions_controller.rb` | コントローラー | カードへのリアクション操作を処理 |
| reaction.rb | `app/models/reaction.rb` | モデル | リアクションデータの管理 |
| new.html.erb | `app/views/reactions/new.html.erb` | ビュー | リアクション追加フォーム |
| _menu.html.erb | `app/views/reactions/_menu.html.erb` | パーシャル | 絵文字選択メニュー |
| emoji_helper.rb | `app/helpers/emoji_helper.rb` | ヘルパー | プリセット絵文字の定義 |
| routes.rb | `config/routes.rb` | 設定 | ルーティング定義（92-100行目） |
