# 画面設計書 21-カード下書き画面

## 概要

本ドキュメントは、Fizzyアプリケーションにおけるカード下書き画面の設計を記述したものです。カード下書き画面は、まだ公開されていない下書き状態のカードを表示し、編集や公開を行うための画面です。

### 本画面の処理概要

**業務上の目的・背景**：カードを作成する際、即座に公開するのではなく、一度下書きとして保存し、内容を確認・編集してから公開したいというニーズに応えるための画面です。これにより、不完全な状態のカードがボードに表示されることを防ぎ、ユーザーは十分に内容を練ってから公開できます。

**画面へのアクセス方法**：ボード詳細画面で新しいカードを作成すると、カードは下書き状態で作成され、この画面に遷移します。URLは `/cards/:number/draft` 形式でアクセスできます。

**主要な操作・処理内容**：
1. 下書きカードのタイトル・説明の表示および編集
2. カードに画像を添付する機能
3. 添付画像の削除（ライトボックス経由）
4. カードの公開（ボードに正式に追加）
5. 既読状態のビーコン送信

**画面遷移**：
- 遷移元：ボード詳細画面（カード作成時）
- 遷移先：カード詳細画面（公開後）、ボード詳細画面（ヘッダーの戻るリンク）

**権限による表示制御**：ログインユーザーのみアクセス可能です。自分がアクセス可能なカードの下書きのみ表示できます。既に公開済みのカードにアクセスした場合は、カード詳細画面にリダイレクトされます。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 23 | カードプレビュー | 主機能 | カードの下書きをプレビュー |
| 22 | カード公開 | 補助機能 | 下書き状態のカードを公開状態にする |

## 画面種別

詳細（プレビュー）

## URL/ルーティング

| HTTPメソッド | URL | コントローラー#アクション |
|-------------|-----|------------------------|
| GET | `/cards/:card_id/draft` | `cards/drafts#show` |

## 入出力項目

本画面は表示専用のため、直接的な入力項目はありません。ただし、埋め込まれたパーシャルを通じてカードの編集や公開が可能です。

## 表示項目

| 項目名 | データソース | 説明 |
|-------|-------------|------|
| ページタイトル | card.title | ブラウザのタイトルバーに表示 |
| ボード名（戻るリンク） | card.board | ヘッダー左側に表示される戻るリンク |
| カードタイトル | card.title | カードのメインタイトル |
| カード説明 | card.description | リッチテキスト形式の説明文 |
| カード画像 | card.image | 添付されている場合に表示 |
| タグ一覧 | card.tags | カードに付けられたタグ |
| ステップ一覧 | card.steps | チェックリスト形式のステップ |
| メタ情報 | card | 作成者、作成日時などのメタ情報 |

## イベント仕様

### 1-戻るリンククリック

ヘッダー左側の戻るリンクをクリックすると、カードが所属するボードの詳細画面に遷移します。

### 2-画像削除ボタンクリック

ライトボックスで画像を表示中に削除ボタンをクリックすると、カードに添付された画像が削除されます。`button_to_remove_card_image` ヘルパーにより、DELETEリクエストが送信されます。

### 3-カード公開

フッター部分のパーシャル（SaaS版と通常版で異なる）を通じて、カードを公開できます。公開後はカード詳細画面にリダイレクトされます。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 画面表示 | cards | SELECT | カード情報の取得 |
| 画面表示 | cards | UPDATE | 既読状態のビーコン送信時にlast_active_at更新 |
| 画像削除 | active_storage_attachments | DELETE | 画像添付の削除 |
| 画像削除 | active_storage_blobs | UPDATE | Blob情報の更新 |

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

#### cards

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | * | number = params[:card_id] AND status = 'drafted' | 下書き状態のカードのみ取得 |
| UPDATE | last_active_at | 現在時刻 | ビーコン送信時 |

## メッセージ仕様

| 種別 | 条件 | メッセージ |
|------|------|----------|
| リダイレクト | 既に公開済みのカードにアクセス | カード詳細画面にリダイレクト（メッセージなし） |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| カードが存在しない | 404エラーページを表示 |
| カードへのアクセス権限がない | 404エラーページを表示 |
| カードが公開済み | カード詳細画面にリダイレクト |

## 備考

- ヘッダーには `header--card` クラスが適用され、カード専用のスタイリングが適用されます
- `beacon` コントローラーにより、既読状態がサーバーに送信されます
- `lightbox` コントローラーにより、画像の拡大表示と削除操作が可能です
- SaaS版と通常版でフッター部分のUIが異なります（`Fizzy.saas?` で分岐）

---

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

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

### 推奨読解順序

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

まず、カードモデルの構造と下書き状態の概念を理解することが重要です。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | card.rb | `app/models/card.rb` | Cardモデルの基本構造、statusカラムによる状態管理を確認 |
| 1-2 | schema.rb | `db/schema.rb` | cardsテーブルの構造（202-218行目）、statusカラムのデフォルト値が'drafted'であることを確認 |

**読解のコツ**: Cardモデルには多数のconcernがincludeされています。下書き関連の機能はStatusesモジュールに含まれていると推測されます。

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | drafts_controller.rb | `app/controllers/cards/drafts_controller.rb` | showアクションの処理、redirect_if_publishedの条件を確認 |
| 2-2 | card_scoped.rb | `app/controllers/concerns/card_scoped.rb` | CardScopedモジュールによるカード取得ロジックを確認 |

**主要処理フロー**:
1. **4行目**: `before_action :redirect_if_published` - 公開済みカードへのアクセス制御
2. **6-7行目**: `show` - シンプルなshowアクション（暗黙的にビューを描画）
3. **10-12行目**: `redirect_if_published` - `@card.drafted?`がfalseならリダイレクト

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | show.html.erb | `app/views/cards/drafts/show.html.erb` | メインビュー、beacon/lightboxコントローラーの設定 |
| 3-2 | _container.html.erb | `app/views/cards/drafts/_container.html.erb` | 下書きカードのコンテナ表示、SaaS分岐 |

**主要処理フロー**:
- **1行目**: `@page_title = @card.title` - ページタイトルの設定
- **10-16行目**: beacon/lightboxコントローラーの設定とコンテナ描画
- **14行目**: 画像が添付されている場合の削除ボタン表示

#### Step 4: ルーティングを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | routes.rb | `config/routes.rb` | 78行目の`resource :draft, only: :show`を確認 |

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

```
GET /cards/:card_id/draft
    |
    +-- Cards::DraftsController#show
           |
           +-- CardScoped#set_card (before_action)
           |      +-- Current.user.accessible_cards.find_by!
           |
           +-- CardScoped#set_board (before_action)
           |      +-- @card.board
           |
           +-- redirect_if_published (before_action)
           |      +-- @card.drafted? -> redirect_to @card if false
           |
           +-- render 'cards/drafts/show'
                  |
                  +-- render 'cards/drafts/_container'
                         |
                         +-- render 'cards/container/image'
                         +-- render 'cards/display/perma/board'
                         +-- render 'cards/display/perma/tags'
                         +-- render 'cards/container/content'
                         +-- render 'cards/display/perma/steps'
                         +-- render 'cards/display/perma/meta'
                         +-- render 'cards/container/footer/...'
```

### データフロー図

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

リクエスト               CardScoped                        ビュー
card_id ──────────────▶ accessible_cards.find_by! ──────▶ @card
                              |
                              ▼
                        redirect_if_published
                              |
                        ┌─────┴─────┐
                        ▼           ▼
                    drafted?     published?
                        |           |
                        ▼           ▼
                    showを描画   @cardにリダイレクト
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| drafts_controller.rb | `app/controllers/cards/drafts_controller.rb` | ソース | 下書き画面のコントローラー |
| card_scoped.rb | `app/controllers/concerns/card_scoped.rb` | ソース | カード取得の共通処理 |
| show.html.erb | `app/views/cards/drafts/show.html.erb` | テンプレート | メインビューテンプレート |
| _container.html.erb | `app/views/cards/drafts/_container.html.erb` | テンプレート | 下書きカードのコンテナ |
| card.rb | `app/models/card.rb` | ソース | カードモデル |
| routes.rb | `config/routes.rb` | 設定 | ルーティング定義 |
| schema.rb | `db/schema.rb` | 設定 | データベーススキーマ |
