# 機能設計書 70-タグ作成

## 概要

本ドキュメントは、Fat Free CRM の管理機能における「タグ作成」機能の設計を記述する。

### 本機能の処理概要

管理者が新規タグを作成するための機能である。作成されたタグは、各エンティティ（取引先、連絡先、リード、商談等）への付与に使用できる。

**業務上の目的・背景**：CRM システムでは、顧客や案件を柔軟に分類するためのタグ機能が重要である。本機能により、管理者は業務に必要なタグを事前に作成し、ユーザーが一貫した分類を行えるようにすることができる。

**機能の利用シーン**：
- 新しい分類カテゴリの追加（例：業種、地域、優先度等）
- キャンペーン用タグの作成
- プロジェクト固有の分類タグの作成
- システム導入時のマスタデータ準備

**主要な処理内容**：
1. 新規作成フォームの表示（AJAX）
2. タグ名の入力受付
3. バリデーション
4. タグレコードの作成

**関連システム・外部連携**：acts-as-taggable-on gem を使用したタグ機能を利用。

**権限による制御**：本機能は管理者権限（admin: true）を持つユーザーのみが実行可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 42 | タグ管理画面 | 補助機能 | 新規タグ作成 |

## 機能種別

CRUD操作（Create）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| tag[name] | String | Yes | タグ名 | 必須、一意性（acts-as-taggable-on） |
| tag[taggings_count] | Integer | No | タグ使用件数 | 整数 |

### 入力データソース

- 画面入力（新規作成フォーム）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| @tag | Tag | 作成されたタグオブジェクト |
| errors | Array | バリデーションエラーメッセージ |

### 出力先

- 画面表示（AJAX レスポンスによる部分更新）
- tags テーブル

## 処理フロー

### 処理シーケンス

```
1. 管理者がタグ管理画面で「Create Tag」リンクをクリック
   └─ AJAX リクエスト: GET /admin/tags/new

2. new アクションで新規作成フォームを表示
   └─ @tag に空のタグオブジェクトをロード
   └─ 新規作成フォーム HTML を返却

3. 管理者がフォームにタグ名を入力して送信
   └─ AJAX リクエスト: POST /admin/tags

4. create アクションでタグを作成
   └─ tag_params でパラメータをフィルタリング
   └─ @tag.update(tag_params) でバリデーションと保存

5. 作成結果を返却
   └─ 成功時: タグ一覧に新しい行を追加
   └─ 失敗時: エラーメッセージを表示
```

### フローチャート

```mermaid
flowchart TD
    A[Create Tag リンククリック] --> B[GET /admin/tags/new]
    B --> C[load_resource で空タグ取得]
    C --> D[新規作成フォーム表示]
    D --> E[フォーム入力・送信]
    E --> F[POST /admin/tags]
    F --> G[tag_params でフィルタリング]
    G --> H{バリデーション}
    H -->|成功| I[タグ作成]
    I --> J[一覧に行を追加]
    H -->|失敗| K[エラー表示]
    K --> D
    J --> L[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-70-01 | タグ名必須 | タグ名は必須入力 | 常時（acts-as-taggable-on 規約） |
| BR-70-02 | タグ名一意性 | システム内でタグ名は一意である必要がある | 常時（tags テーブルの unique index） |
| BR-70-03 | 初期カウント | 作成時の taggings_count は 0 | 常時 |

### 計算ロジック

特になし

## データベース操作仕様

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| タグ作成 | tags | INSERT | 新規タグレコードの作成 |

### テーブル別操作詳細

#### tags

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | name | フォーム入力値 | 一意性インデックスあり |
| INSERT | taggings_count | 0（デフォルト）または指定値 | カウンターキャッシュ |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | バリデーションエラー | タグ名が未入力 | フォームにエラーメッセージを表示 |
| - | バリデーションエラー | タグ名が重複 | フォームにエラーメッセージを表示 |
| - | 認可エラー | 非管理者によるアクセス | ルート画面にリダイレクト |

### リトライ仕様

バリデーションエラー時は新規作成フォームを再表示し、ユーザーが修正後に再送信可能。

## トランザクション仕様

ActiveRecord のデフォルトトランザクションにより、update メソッド実行時に自動的にトランザクション管理される。

## パフォーマンス要件

- AJAX リクエストのため、レスポンス時間は 500ms 以内を目標
- 単一タグの作成処理であり、特別なパフォーマンス考慮は不要

## セキュリティ考慮事項

- 管理者権限チェック（before_action :require_admin_user）
- Strong Parameters によるパラメータフィルタリング
- CSRF トークンによるクロスサイトリクエストフォージェリ対策

## 備考

- 新規作成フォームは AJAX で表示されるため、ページ遷移なしで操作可能
- タグはエンティティに紐付けることで taggings_count が自動更新される
- acts-as-taggable-on gem により、タグ名は大文字小文字を区別しない場合がある（設定依存）

---

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

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

### 推奨読解順序

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

まず、タグモデルと acts-as-taggable-on の関連を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | tag.rb | `app/models/polymorphic/tag.rb` | タグモデルの定義 |
| 1-2 | schema.rb | `db/schema.rb` | tags テーブルの構造、一意性インデックス |

**読解のコツ**:
- **8行目**: `class Tag < ActsAsTaggableOn::Tag` で acts-as-taggable-on を継承
- tags テーブルの `name` カラムには unique index が設定されている

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | tags_controller.rb | `app/controllers/admin/tags_controller.rb` | new, create アクション |
| 2-2 | application_controller.rb | `app/controllers/admin/application_controller.rb` | 管理者権限チェック |

**主要処理フロー**:
- **23-26行目**: new アクション

```ruby
def new
  respond_with(@tag)
end
```

- **36-41行目**: create アクション

```ruby
def create
  @tag.update(tag_params)
  respond_with(@tag)
end
```

- **68-70行目**: tag_params メソッド

```ruby
def tag_params
  params.require(:tag).permit(:name, :taggings_count)
end
```

#### Step 3: ビュー層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | new.js.haml | `app/views/admin/tags/new.js.haml` | 新規作成フォーム表示 JS |
| 3-2 | _new.html.haml | `app/views/admin/tags/_new.html.haml` | 新規作成フォーム HTML |
| 3-3 | _top_section.html.haml | `app/views/admin/tags/_top_section.html.haml` | フォーム入力部分 |
| 3-4 | create.js.haml | `app/views/admin/tags/create.js.haml` | 作成完了後の JS 処理 |

**読解のコツ**:
- `_new.html.haml` で remote: true により AJAX 送信
- `_top_section.html.haml` で f.text_field :name によりタグ名入力フィールドを定義

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | routes.rb | `config/routes.rb` | admin/tags のルート定義 |

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

```
[Admin::TagsController#new]
    │
    ├─ load_resource (CanCanCan)
    │      └─ Tag.new → @tag
    │
    └─ respond_with(@tag)
           └─ new.js.haml
                  └─ _new.html.haml
                         └─ _top_section.html.haml

[Admin::TagsController#create]
    │
    ├─ load_resource (CanCanCan)
    │      └─ Tag.new → @tag
    │
    ├─ tag_params
    │      └─ params.require(:tag).permit(:name, :taggings_count)
    │
    ├─ @tag.update(tag_params)
    │      └─ ActsAsTaggableOn バリデーション
    │             └─ name 一意性チェック
    │
    └─ respond_with(@tag)
           └─ create.js.haml
```

### データフロー図

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

新規作成フォーム    ───▶ tag_params                ───▶ tags テーブル
                           │                              │
tag[name]           ───▶ バリデーション                  │
tag[taggings_count] ───▶ @tag.update                     │
                                                         ▼
                                                   画面更新（AJAX）
                                                   一覧に行を追加
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| tags_controller.rb | `app/controllers/admin/tags_controller.rb` | コントローラー | new/create アクションの実装 |
| application_controller.rb | `app/controllers/admin/application_controller.rb` | コントローラー | 管理者権限チェック |
| tag.rb | `app/models/polymorphic/tag.rb` | モデル | タグモデル定義 |
| new.js.haml | `app/views/admin/tags/new.js.haml` | ビュー | 新規作成フォーム表示 JS |
| _new.html.haml | `app/views/admin/tags/_new.html.haml` | ビュー | 新規作成フォーム HTML |
| _top_section.html.haml | `app/views/admin/tags/_top_section.html.haml` | ビュー | フォーム入力部分 |
| create.js.haml | `app/views/admin/tags/create.js.haml` | ビュー | 作成完了後 JS |
| routes.rb | `config/routes.rb` | 設定 | ルーティング定義 |
| schema.rb | `db/schema.rb` | 設定 | データベーススキーマ |
