# 画面設計書 24-カードカラム変更画面

## 概要

本ドキュメントは、Fizzyアプリケーションにおけるカードカラム変更画面の設計を記述したものです。カードカラム変更画面は、カードの所属カラム（ステータス）を変更するためのインライン形式のUIコンポーネントです。

### 本画面の処理概要

**業務上の目的・背景**：カンバンボードでタスク管理を行う際、タスク（カード）の進捗状況に応じてカラム（例：To Do、In Progress、Done）間を移動させる必要があります。この画面により、ユーザーは直感的にカードの状態を変更でき、タスクの進捗を視覚的に管理できます。

**画面へのアクセス方法**：カード詳細画面のカラム選択エリアに表示されます。URLは `/cards/:card_id/column/edit` ですが、通常はTurbo Frameとしてカード詳細画面に埋め込まれます。

**主要な操作・処理内容**：
1. 現在のカラム状態の表示（選択状態でハイライト）
2. 「Not now」への移動（カードを一時的に保留）
3. 「Maybe?」（トリアージ待ち）への移動
4. 通常カラムへの移動
5. 「Done」への移動（カードを完了状態に）

**画面遷移**：
- 遷移元：カード詳細画面（インライン表示）
- 遷移先：なし（Turbo Streamで画面更新）

**権限による表示制御**：ログインユーザーのみアクセス可能です。カードにアクセス権限があるユーザーのみ操作可能です。現在選択されているカラムは`disabled`状態となり、再選択できません。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 27 | カードを別カラムに移動 | 主機能 | カードを別のカラムに移動 |

## 画面種別

選択（インライン）

## URL/ルーティング

| HTTPメソッド | URL | コントローラー#アクション |
|-------------|-----|------------------------|
| GET | `/cards/:card_id/column/edit` | `cards/columns#edit` |
| POST | `/cards/:card_id/not_now` | `cards/not_nows#create` |
| DELETE | `/cards/:card_id/triage` | `cards/triages#destroy` |
| POST | `/cards/:card_id/column` | `cards/columns#create` |
| POST | `/cards/:card_id/closure` | `cards/closures#create` |

## 入出力項目

| 項目名 | 入出力 | データ型 | 必須 | 説明 |
|-------|-------|---------|-----|------|
| column_id | 入力 | UUID | - | 移動先のカラムID（通常カラム選択時） |

## 表示項目

| 項目名 | データソース | 説明 |
|-------|-------------|------|
| Not now ボタン | 固定文字列 | 保留状態への移動 |
| Maybe? ボタン | 固定文字列 | トリアージ待ちへの移動 |
| カラムボタン一覧 | @columns | ボード内の通常カラム |
| Done ボタン | 固定文字列 | 完了状態への移動 |

## イベント仕様

### 1-「Not now」ボタンクリック

カードを保留状態（postponed）に移動します。

**処理内容**：
1. `card_not_now_path`へPOSTリクエスト送信
2. カードのステータスを`postponed`に変更
3. Turbo Streamでカード表示を更新

### 2-「Maybe?」ボタンクリック

カードをトリアージ待ち状態に移動します。

**処理内容**：
1. `card_triage_path`へDELETEリクエスト送信
2. カードのカラムをNULLにリセット（ストリーム状態）
3. Turbo Streamでカード表示を更新

### 3-通常カラムボタンクリック

カードを指定したカラムに移動します。

**処理内容**：
1. `card_column_path`へPOSTリクエスト送信
2. カードのcolumn_idを更新
3. Turbo Streamでカード表示を更新

### 4-「Done」ボタンクリック

カードを完了状態に移動します。

**処理内容**：
1. `card_closure_path`へPOSTリクエスト送信
2. カードにClosureレコードを作成
3. Turbo Streamでカード表示を更新

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 画面表示 | columns | SELECT | ボード内のカラム一覧を取得 |
| Not now選択 | card_not_nows | INSERT | 保留状態レコードの作成 |
| Not now選択 | cards | UPDATE | ステータス更新 |
| Maybe?選択 | cards | UPDATE | column_idをNULLに更新 |
| カラム選択 | cards | UPDATE | column_idの更新 |
| Done選択 | closures | INSERT | 完了レコードの作成 |
| Done選択 | cards | UPDATE | ステータス更新 |

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

#### cards

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | column_id | 選択したカラムのID / NULL | カラム移動時 |
| UPDATE | status | 状態に応じて変更 | postponed/closed等 |
| UPDATE | updated_at | 現在時刻 | 自動更新 |

#### card_not_nows

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | account_id | card.account_id | 自動設定 |
| INSERT | card_id | @card.id | 対象カード |
| INSERT | user_id | Current.user.id | 操作ユーザー |

#### closures

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | account_id | card.account_id | 自動設定 |
| INSERT | card_id | @card.id | 対象カード |
| INSERT | user_id | Current.user.id | クローズしたユーザー |

## メッセージ仕様

本画面では明示的なメッセージ表示はありません。状態変更は即座にUIに反映されます。

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| カードが存在しない | 404エラーページを表示 |
| カードへのアクセス権限がない | 404エラーページを表示 |
| 無効なカラムIDが指定された | 422エラー |

## 備考

- Turbo Frameで読み込まれ、`turbo_frame_tag @card, :columns`でフレームを識別します
- `scroll-to`コントローラーにより、現在選択されているカラムが自動的にスクロール表示されます
- `radiogroup`ロールで、アクセシビリティに配慮した実装になっています
- 各ボタンは`role="radio"`で、`aria-checked`で選択状態を示します
- カラムの色は`--column-color` CSS変数で制御されます
- 現在選択中のカラムは`disabled`属性が設定され、再選択不可になります
- `button_to_set_column`ヘルパーで通常カラムのボタンが生成されます

---

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

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

### 推奨読解順序

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

まず、カードのステータス管理とカラムの関係を理解することが重要です。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | card.rb | `app/models/card.rb` | Cardモデル、statusカラム、column関連 |
| 1-2 | schema.rb | `db/schema.rb` | cardsテーブル（column_id, status）、columnsテーブル、closures、card_not_nows |

**読解のコツ**: カードは`column_id`（通常カラム）、`status`（drafted/closed等）、`card_not_nows`（保留）、`closures`（完了）の複数の状態管理機構を持っています。

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

処理の起点となるコントローラーを特定します。

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

**主要処理フロー**:
1. **3行目**: `@card` - アクセス可能なカードを取得
2. **4行目**: `@columns` - ボード内のカラムを取得（sorted順）
3. **6行目**: `fresh_when` - ETTagによるキャッシュ制御

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

画面の表示内容を構成するビューファイルを確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | edit.html.erb | `app/views/cards/columns/edit.html.erb` | カラム選択UI |

**主要処理フロー**:
- **1行目**: `turbo_frame_tag @card, :columns` - Turbo Frameの定義
- **2行目**: `radiogroup`ロールの設定
- **5-12行目**: 「Not now」ボタン
- **14-21行目**: 「Maybe?」ボタン
- **23-25行目**: 通常カラムのループ
- **27-34行目**: 「Done」ボタン

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

```
GET /cards/:card_id/column/edit
    |
    +-- Cards::ColumnsController#edit
           |
           +-- Current.user.accessible_cards.find_by!
           +-- @card.board.columns.sorted
           |
           +-- render 'cards/columns/edit'

POST /cards/:card_id/not_now
    |
    +-- Cards::NotNowsController#create
           +-- カードを保留状態に

DELETE /cards/:card_id/triage
    |
    +-- Cards::TriagesController#destroy
           +-- カードをトリアージ待ちに

POST /cards/:card_id/column
    |
    +-- Cards::ColumnsController#create
           +-- カードを指定カラムに移動

POST /cards/:card_id/closure
    |
    +-- Cards::ClosuresController#create
           +-- カードを完了状態に
```

### データフロー図

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

ボタン選択               各Controller                      Turbo Stream
    |                         |
    +-- Not now ─────────▶ NotNowsController ──────────▶ card_not_nows INSERT
    |                                                      cards UPDATE
    |
    +-- Maybe? ──────────▶ TriagesController ─────────▶ cards UPDATE (column_id=NULL)
    |
    +-- カラム ──────────▶ ColumnsController ─────────▶ cards UPDATE (column_id)
    |
    +-- Done ────────────▶ ClosuresController ────────▶ closures INSERT
                                                          cards UPDATE
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| columns_controller.rb | `app/controllers/cards/columns_controller.rb` | ソース | カラム変更コントローラー |
| edit.html.erb | `app/views/cards/columns/edit.html.erb` | テンプレート | カラム選択画面のビュー |
| card.rb | `app/models/card.rb` | ソース | Cardモデル |
| column.rb | `app/models/column.rb` | ソース | Columnモデル |
| routes.rb | `config/routes.rb` | 設定 | ルーティング定義 |
| schema.rb | `db/schema.rb` | 設定 | データベーススキーマ |
