# 画面設計書 74-タグ検索プロンプト画面

## 概要

本ドキュメントは、Fizzyアプリケーションにおける「タグ検索プロンプト画面」の設計仕様を記述したものである。

### 本画面の処理概要

タグ検索プロンプト画面は、テキスト入力フィールドでタグを検索・選択するためのオートコンプリート機能を提供するAPI画面である。主にリッチテキストエディタ内でタグをメンション（挿入）する際や、カードへのタグ付け時に使用される。アカウント内の全タグをアルファベット順で表示する。

**業務上の目的・背景**：タグは、カードの分類や検索において重要な役割を果たす。ユーザーがコメントやカード説明文内でタグを参照したり、カードにタグを付与する際に、既存のタグ一覧から素早く選択できることで、タグの統一性と再利用性が向上する。「#」に続けてタグ名の一部を入力することで、フロントエンド側でリアルタイムに候補を絞り込む。

**画面へのアクセス方法**：リッチテキストエディタ（Lexxyエディタ）内で「#」を入力するとプロンプトが表示される。URLは `/prompts/tags` であり、Ajax（Fetch API）経由で非同期に呼び出される。

**主要な操作・処理内容**：
1. アカウント内の全タグをアルファベット順で取得
2. フロントエンドでのクライアントサイドフィルタリング
3. タグ選択によるタグ挿入

**画面遷移**：
- 遷移元：カード編集画面、コメント入力欄等のリッチテキストエディタ、カードタグ付け画面
- 遷移先：なし（タグがエディタに挿入される）

**権限による表示制御**：認証必須。同一アカウント内のタグのみが表示される。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 41 | タグ一覧表示 | 主機能 | タグ検索用のオートコンプリートプロンプト |

## 画面種別

APIレスポンス画面（オートコンプリートプロンプト）

## URL/ルーティング

| パス | HTTPメソッド | コントローラ#アクション |
|------|-------------|----------------------|
| `/prompts/tags` | GET | `Prompts::TagsController#index` |

## 入出力項目

### 入力項目

本APIはパラメータを受け取らない（全タグを返却）。

### 出力項目

| 項目 | 説明 |
|------|------|
| タグ候補リスト | lexxy-prompt-item要素のリスト |

## 表示項目

### タグ候補アイテム（lexxy-prompt-item）

| 項目 | 属性 | 説明 |
|------|------|------|
| search | 属性 | タグタイトル（フロントエンド検索用） |
| sgid | 属性 | タグのGlobal ID（ActionText用） |
| メニュー表示（menu） | テンプレート | `#タイトル` 形式 |
| エディタ挿入時表示（editor） | テンプレート | `#タイトル` 形式 |

## イベント仕様

### 1-タグ一覧取得

画面初回アクセス時にAjax経由でAPI呼び出しが行われる。

- リクエスト: `GET /prompts/tags`
- レスポンス: HTMLフラグメント（lexxy-prompt-itemのリスト）

### 2-タグ選択

候補リストからタグを選択すると、エディタにタグが挿入される。

- 挿入形式: `#タイトル`
- sgid属性: ActionText用のGlobal ID

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

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

本画面は読み取り専用であり、データベースの更新は発生しない。

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| タグ一覧取得 | tags | SELECT | アカウント内全タグの取得 |

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

#### tags（参照のみ）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | id, title | account_id = Current.account.id | alphabeticallyスコープ適用 |

## メッセージ仕様

本画面では特定のメッセージ表示はない（候補が0件の場合は空のレスポンス）。

## 例外処理

| 条件 | 処理内容 |
|------|---------|
| 未認証アクセス | ログイン画面へリダイレクト |

## 備考

- レイアウトなし（`render layout: false`）
- ETagベースのキャッシュを使用（`stale? etag: @tags`）
- 全タグを返却し、フロントエンドで `search` 属性を使ってフィルタリング
- `attachable_sgid` はActionTextでタグをリッチテキストに埋め込むために使用
- タグは小文字に正規化されている（`normalizes :title, with: -> { it.downcase }`）

---

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

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

### 推奨読解順序

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

タグモデルの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | tag.rb | `app/models/tag.rb` | Tagモデルの定義、alphabeticallyスコープ（11行目）、Attachableモジュール |

**読解のコツ**: `Attachable` モジュールにより `attachable_sgid` メソッドが提供される。これはActionTextでタグを参照可能にするためのGlobal ID。

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

処理の起点となるコントローラーを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | tags_controller.rb | `app/controllers/prompts/tags_controller.rb` | indexアクションの実装 |

**主要処理フロー**:
1. **3行目**: `@tags = Current.account.tags.all.alphabetically` - アカウント内全タグをアルファベット順で取得
2. **5-7行目**: ETagキャッシュ確認、変更がない場合は304を返却

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

テンプレートの構造を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.html.erb | `app/views/prompts/tags/index.html.erb` | タグコレクションのレンダリング |
| 3-2 | _tag.html.erb | `app/views/prompts/tags/_tag.html.erb` | 個別タグの表示形式 |

**主要処理フロー**:
- **index.html.erb 1行目**: `render partial: "prompts/tags/tag", collection: @tags`
- **_tag.html.erb 1-8行目**: `lexxy-prompt-item` 要素の生成
  - search属性: `tag.title`（フロントエンドフィルタ用）
  - sgid属性: `tag.attachable_sgid`（ActionText用）
  - menu: `#タイトル`
  - editor: `#タイトル`

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

```
Prompts::TagsController#index
    │
    ├─ Current.account.tags.all.alphabetically
    │      │
    │      └─ Tag.alphabetically
    │             └─ order("lower(title)")
    │
    └─ stale? etag: @tags
           │
           └─ render layout: false
                  │
                  └─ index.html.erb
                         └─ _tag.html.erb (collection)
```

### データフロー図

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

(なし) ─────▶ Prompts::TagsController#index
                       │
                       ▼
              Current.account.tags.all.alphabetically
                       │
                       ▼
                   @tags
                       │
                       ▼
               index.html.erb
                       │
                       ▼
              lexxy-prompt-item (HTML)
                       │
                       ▼
              フロントエンド
              (search属性でフィルタリング)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| tags_controller.rb | `app/controllers/prompts/tags_controller.rb` | コントローラー | リクエストハンドリング |
| index.html.erb | `app/views/prompts/tags/index.html.erb` | テンプレート | メインビュー |
| _tag.html.erb | `app/views/prompts/tags/_tag.html.erb` | パーシャル | タグ候補アイテム |
| tag.rb | `app/models/tag.rb` | モデル | タグモデル |
| routes.rb | `config/routes.rb` | 設定 | ルーティング定義（184行目） |
