# 画面設計書 241-トピック新規作成

## 概要

本ドキュメントは、GitLab管理者がプロジェクトを分類・整理するための新規トピック（Topic）を作成する画面の設計書です。

### 本画面の処理概要

トピック新規作成画面は、GitLabインスタンス内でプロジェクトをカテゴリ分けするためのトピックを新規作成する管理者専用画面です。

**業務上の目的・背景**：GitLabでは多数のプロジェクトが存在する場合、ユーザーがプロジェクトを効率的に探索・発見できるようにするためのトピック機能が提供されています。管理者はこの画面から新しいトピックを作成し、プロジェクトの分類・整理を行うことで、ユーザーのプロジェクト探索体験を向上させることができます。トピックは組織（Organization）に紐づくため、マルチテナント環境でも適切に管理できます。

**画面へのアクセス方法**：
1. 管理者としてGitLabにログイン
2. 左サイドメニューから「Admin Area」をクリック
3. 「Overview」セクションの「Topics」をクリック
4. 「New topic」ボタンをクリック

**主要な操作・処理内容**：
1. トピックスラッグ（name）の入力 - URLに使用される識別子（英数字、ハイフン、アンダースコア、ドットのみ）
2. トピックタイトル（title）の入力 - 表示名
3. 説明（description）の入力 - Markdown対応
4. アバター画像のアップロード（オプション）
5. 「Create topic」ボタンでトピック作成

**画面遷移**：
- 遷移元：トピック一覧画面（Admin > Topics）
- 遷移先（成功時）：トピック一覧画面（成功メッセージ付き）
- 遷移先（失敗時）：本画面（エラーメッセージ表示）
- キャンセル時：トピック一覧画面

**権限による表示制御**：管理者権限を持つユーザーのみがこの画面にアクセス可能です。一般ユーザーはアクセスできません。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 102 | グローバル検索 | 主機能 | トピックの作成処理 |

## 画面種別

登録（新規作成）

## URL/ルーティング

- URL: `/admin/topics/new`
- HTTP メソッド: GET（画面表示）/ POST（トピック作成）
- ルート名: `new_admin_topic` / `admin_topics`

## 入出力項目

| 項目名 | 項目ID | 型 | 必須 | 最大長 | バリデーション | 備考 |
|--------|--------|-----|------|--------|----------------|------|
| トピックスラッグ | name | String | ○ | 255 | ASCII文字のみ、改行禁止、一意性 | URL識別子として使用 |
| トピックタイトル | title | String | ○ | 255 | - | 表示名 |
| 説明 | description | Text | - | 1024 | - | Markdown対応 |
| アバター | avatar | File | - | - | 画像ファイル | CarrierWave使用 |

## 表示項目

| 項目名 | 表示形式 | 備考 |
|--------|----------|------|
| ページタイトル | テキスト | "New topic" |
| パンくずリスト | リンク | Topics > New topic |
| 入力フォーム | フォーム | 上記入出力項目参照 |
| Markdownプレビュー | ボタン/パネル | 説明フィールド用 |
| アバタープレビュー | 画像 | アップロード時に表示 |

## イベント仕様

### 1-トピック作成（Create topic）

**トリガー**: 「Create topic」ボタンクリック

**処理フロー**:
1. フォームデータのサーバー送信
2. `Admin::TopicsController#create`アクション呼び出し
3. `Projects::Topic`モデルのインスタンス作成
4. バリデーション実行
   - name: 必須、255文字以内、ASCII文字のみ、組織内で一意
   - title: 必須、255文字以内
   - description: 1024文字以内
5. 成功時: トピック一覧へリダイレクト（成功メッセージ付き）
6. 失敗時: 本画面再表示（エラーメッセージ表示）

### 2-キャンセル

**トリガー**: 「Cancel」ボタンクリック

**処理フロー**: トピック一覧画面へ遷移

### 3-Markdownプレビュー

**トリガー**: プレビュータブクリック

**処理フロー**:
1. `preview_markdown_admin_topics_path`へAjaxリクエスト
2. 入力されたMarkdownをHTMLにレンダリング
3. プレビューパネルに表示

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| Create topic押下 | projects_topics | INSERT | 新規トピックレコード作成 |

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

#### projects_topics

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | name | フォーム入力値 | トピックスラッグ |
| INSERT | title | フォーム入力値 | トピックタイトル |
| INSERT | description | フォーム入力値（任意） | 説明テキスト |
| INSERT | avatar | アップロードファイル（任意） | アバター画像パス |
| INSERT | organization_id | Current.organization.id | 現在の組織ID |
| INSERT | created_at | 現在日時 | 作成日時 |
| INSERT | updated_at | 現在日時 | 更新日時 |
| INSERT | total_projects_count | 0 | 初期値 |
| INSERT | non_private_projects_count | 0 | 初期値 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| MSG001 | 成功 | Topic {topic_name} was successfully created. | トピック作成成功時 |
| MSG002 | エラー | Please fill in a name for your topic. | name未入力時 |
| MSG003 | エラー | Please fill in a title for your topic. | title未入力時 |
| MSG004 | エラー | has characters that are not allowed | name に改行文字が含まれる場合 |
| MSG005 | エラー | must only include ASCII characters | name に非ASCII文字が含まれる場合 |
| MSG006 | エラー | has already been taken | 同一組織内でnameが重複 |

## 例外処理

| 例外条件 | 処理内容 | 表示メッセージ |
|----------|----------|---------------|
| 権限不足 | 403エラー画面へリダイレクト | アクセスが拒否されました |
| バリデーションエラー | 画面再表示 | 各フィールドにエラーメッセージ表示 |
| ファイルアップロードエラー | 画面再表示 | アバターアップロードエラー |

## 備考

- トピックは組織（Organization）に紐づくため、`organization_id`が自動設定される
- トピックスラッグ（name）は英数字、ハイフン、アンダースコア、ドットのみ使用可能
- 説明フィールドはMarkdown形式をサポートし、プレビュー機能が利用可能
- アバター画像はCarrierWaveを使用してアップロードされる

---

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

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

### 推奨読解順序

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

まず、トピックのデータ構造と検証ルールを理解することが重要です。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | topic.rb | `app/models/projects/topic.rb` | トピックモデルの定義、バリデーションルール、アソシエーション |

**読解のコツ**:
- `validates`メソッドでバリデーションルールを確認
- `cache_markdown_field :description`でMarkdownキャッシュ機能を確認
- `belongs_to :organization`で組織との関連を確認

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

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

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

**主要処理フロー**:
1. **18-19行目**: `new`アクション - 空のTopicインスタンス作成
2. **24-32行目**: `create`アクション - トピック作成処理
3. **69-71行目**: `topic_params`メソッド - Strong Parameters定義
4. **73-79行目**: `allowed_topic_params` - 許可パラメータ一覧

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

画面のレンダリング処理を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | new.html.haml | `app/views/admin/topics/new.html.haml` | 画面レイアウト、フォーム呼び出し |
| 3-2 | _form.html.haml | `app/views/admin/topics/_form.html.haml` | フォームフィールド定義、Markdownエディタ設定 |

**主要処理フロー**:
- **5行目**: フォームパーシャル呼び出し
- フォームパーシャル内の各入力フィールド定義

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

URLとコントローラの対応を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | admin.rb | `config/routes/admin.rb` | トピック関連のルーティング定義 |

**主要処理フロー**:
- **84-90行目**: topicsリソースのルーティング定義

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

```
ブラウザ (GET /admin/topics/new)
    │
    ├─ Admin::TopicsController#new
    │      └─ Projects::Topic.new
    │
    └─ View: admin/topics/new.html.haml
           └─ Partial: admin/topics/_form.html.haml
                  └─ GitLab UI Form Components

ブラウザ (POST /admin/topics)
    │
    └─ Admin::TopicsController#create
           ├─ Projects::Topic.new(topic_params)
           ├─ topic.save
           │      ├─ validate_name_format
           │      └─ ActiveRecord validations
           └─ redirect_to admin_topics_path (成功時)
              または render "new" (失敗時)
```

### データフロー図

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

フォームデータ ───────▶ TopicsController#create ───────▶ 成功: トピック一覧画面
  - name                      │                              (フラッシュメッセージ)
  - title                     ├─ topic_params
  - description               ├─ Topic.new
  - avatar                    ├─ topic.save
                              │     └─ バリデーション
                              │
                              └───────────────────────▶ 失敗: 新規作成画面
                                                            (エラーメッセージ)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| topics_controller.rb | `app/controllers/admin/topics_controller.rb` | コントローラ | リクエスト処理、CRUD操作 |
| topic.rb | `app/models/projects/topic.rb` | モデル | データ定義、バリデーション |
| new.html.haml | `app/views/admin/topics/new.html.haml` | ビュー | 新規作成画面レイアウト |
| _form.html.haml | `app/views/admin/topics/_form.html.haml` | ビュー | 入力フォーム |
| admin.rb | `config/routes/admin.rb` | 設定 | ルーティング定義 |
| topics_finder.rb | `app/finders/projects/topics_finder.rb` | ファインダー | トピック検索クエリ |
