# 画面設計書 94-記事新規作成画面

## 概要

本ドキュメントは、Chatwootのヘルプセンター機能における「記事新規作成画面」の設計仕様を記述したものである。

### 本画面の処理概要

記事新規作成画面は、ヘルプセンターポータルに新しい記事を作成するためのエディタ画面である。リッチテキストエディタを使用して記事のタイトルと本文を入力し、カテゴリや著者を設定して保存する。

**業務上の目的・背景**：顧客向けのナレッジベースを構築するために、サポート担当者やコンテンツ管理者が記事を作成する必要がある。直感的なWYSIWYGエディタを提供することで、技術的な知識がなくても質の高いヘルプ記事を作成できるようにする。記事は下書き状態で保存され、後から編集画面で公開・アーカイブの操作が可能。

**画面へのアクセス方法**：記事一覧画面の「New article」ボタンをクリック、または直接URL `/app/accounts/:accountId/portals/:portalSlug/:locale/articles/new` にアクセスする。

**主要な操作・処理内容**：
1. 記事タイトルを入力
2. 記事本文をリッチテキストエディタで入力
3. カテゴリを選択（オプション）
4. 著者を選択（デフォルトは現在のユーザー）
5. 保存ボタンで記事を作成
6. 作成成功後、記事編集画面へ自動遷移

**画面遷移**：
- 遷移元：記事一覧画面（portals_articles_index）
- 遷移先：記事編集画面（portals_articles_edit）- 作成成功時、記事一覧画面 - 戻るボタン押下時

**権限による表示制御**：administrator、agent、knowledge_base_manage権限を持つユーザーがアクセス可能。HELP_CENTERフィーチャーフラグが有効である必要がある。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 154 | ポータル記事 | 主機能 | 新しい記事の作成 |

## 画面種別

登録

## URL/ルーティング

| 項目 | 値 |
|------|-----|
| パス | `/app/accounts/:accountId/portals/:portalSlug/:locale/:categorySlug?/articles/new` |
| ルート名 | `portals_articles_new` |
| コンポーネント | `PortalsArticlesNewPage.vue` |

## 入出力項目

### 入力項目（URLパラメータ）

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| accountId | Number | Yes | アカウントID |
| portalSlug | String | Yes | ポータルのスラッグ |
| locale | String | Yes | ロケールコード |
| categorySlug | String | No | カテゴリスラッグ |

### 入力項目（フォーム）

| 項目名 | 型 | 必須 | バリデーション | 説明 |
|--------|-----|------|--------------|------|
| title | String | Yes | 必須入力 | 記事タイトル |
| content | String | Yes | 必須入力 | 記事本文（HTML形式） |
| categoryId | Number | No | - | カテゴリID |
| authorId | Number | No | - | 著者ID（デフォルト：現在のユーザー） |

### 出力項目

| 項目名 | 型 | 説明 |
|--------|-----|------|
| articleSlug | String | 作成された記事のスラッグ |

## 表示項目

### エディタ画面

| 項目名 | 型 | 説明 |
|--------|-----|------|
| タイトル入力フィールド | Input | 記事タイトル入力欄 |
| 本文エディタ | RichTextEditor | WYSIWYG形式の本文入力欄 |
| 戻るボタン | Button | 記事一覧への戻るボタン |
| 保存ボタン | Button | 記事保存ボタン |
| カテゴリセレクト | Select | カテゴリ選択 |
| 著者セレクト | Select | 著者選択 |

## イベント仕様

### 1-記事保存

**トリガー**: 保存ボタンクリック、または自動保存

**処理フロー**:
1. フォームバリデーション（タイトルと本文の必須チェック）
2. タイトルと本文が両方入力されている場合のみ処理を続行
3. isUpdatingフラグをtrueに設定
4. `articles/create` アクションをディスパッチ
5. POST `/api/v1/accounts/:accountId/portals/:portalSlug/articles` を呼び出し
6. 成功時：記事編集画面へ自動遷移（router.replace）
7. 失敗時：エラーメッセージを表示
8. イベントトラッキング（PORTALS_EVENTS.CREATE_ARTICLE）

### 2-カテゴリ設定

**トリガー**: カテゴリセレクト変更

**処理フロー**:
1. setCategory関数が呼び出される
2. selectedCategoryIdを更新
3. 記事保存時にこのカテゴリIDが使用される

### 3-著者設定

**トリガー**: 著者セレクト変更

**処理フロー**:
1. setAuthor関数が呼び出される
2. selectedAuthorIdを更新
3. 記事保存時にこの著者IDが使用される（未設定時はcurrentUserId）

### 4-記事一覧に戻る

**トリガー**: 戻るボタンクリック

**処理フロー**:
1. goBackToArticles関数を実行
2. 現在のtab, categorySlug, localeをパラメータとして設定
3. `portals_articles_index` ルートへ遷移

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 記事作成 | articles | INSERT | 新しい記事レコードを作成 |

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

#### articles

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | title | フォーム入力値 | 必須 |
| INSERT | content | フォーム入力値（HTML） | 必須 |
| INSERT | portal_id | ポータルIDから取得 | 自動設定 |
| INSERT | account_id | portal.account_id | 自動設定 |
| INSERT | author_id | selectedAuthorId または currentUserId | 必須 |
| INSERT | category_id | selectedCategoryId または 最初のカテゴリID | オプション |
| INSERT | locale | URLパラメータから取得 | 必須 |
| INSERT | status | 'draft' | デフォルト |
| INSERT | slug | タイトルから自動生成 | 自動設定 |
| INSERT | created_at | 現在日時 | 自動設定 |
| INSERT | updated_at | 現在日時 | 自動設定 |

## メッセージ仕様

| 種別 | メッセージキー | メッセージ内容 | 表示条件 |
|------|--------------|--------------|----------|
| エラー | HELP_CENTER.EDIT_ARTICLE_PAGE.API.ERROR | "Error while saving article" | 保存失敗時 |
| プレースホルダー | HELP_CENTER.EDIT_ARTICLE.TITLE_PLACEHOLDER | "Article title goes here" | タイトル入力欄 |
| プレースホルダー | HELP_CENTER.EDIT_ARTICLE.CONTENT_PLACEHOLDER | "Write your article here" | 本文入力欄 |

## 例外処理

| 例外状況 | 処理内容 |
|---------|---------|
| バリデーションエラー（タイトル・本文未入力） | 保存処理をスキップ |
| API保存失敗 | useAlertでエラーメッセージを表示 |
| 権限不足 | ルートガードによりアクセス拒否 |

## 備考

- 記事は常に `draft` ステータスで作成される
- スラッグはタイトルから自動生成（タイムスタンプ + parameterize）
- 作成成功後は `router.replace` を使用して編集画面へ遷移（履歴置換）
- フィーチャーフラグ `HELP_CENTER` が有効である必要がある

---

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

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

### 推奨読解順序

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

記事のデータ構造と作成パラメータを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Article (Model) | `app/models/article.rb` | 記事のスキーマ定義、バリデーション、スラッグ自動生成 |
| 1-2 | articles_controller.rb | `app/controllers/api/v1/accounts/articles_controller.rb` | createアクションのパラメータ |

**読解のコツ**: ensure_article_slugメソッドでスラッグがどのように生成されるか確認する。

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

画面のエントリーポイントとコンポーネント構成を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | PortalsArticlesNewPage.vue | `app/javascript/dashboard/routes/dashboard/helpcenter/pages/PortalsArticlesNewPage.vue` | 画面コンポーネントのメイン処理 |
| 2-2 | ArticleEditor.vue | `app/javascript/dashboard/components-next/HelpCenter/Pages/ArticleEditorPage/ArticleEditor.vue` | エディタUI |
| 2-3 | helpcenter.routes.js | `app/javascript/dashboard/routes/dashboard/helpcenter/helpcenter.routes.js` | ルート定義 |

**主要処理フロー**:
1. **38-73行目**: createNewArticle関数で記事作成処理
2. **30-36行目**: setAuthorId, setCategoryId関数で設定値を管理
3. **75-81行目**: goBackToArticles関数で一覧へ戻る

#### Step 3: Vuex Actionsを理解する

記事作成のAPI呼び出し処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | actions.js (articles) | `app/javascript/dashboard/store/modules/helpCenterArticles/actions.js` | createアクションの実装 |
| 3-2 | articles.js (API) | `app/javascript/dashboard/api/helpCenter/articles.js` | createArticle APIメソッド |

**主要処理フロー**:
- **37-56行目**: createアクション - UIフラグ設定、API呼び出し、ストア更新

#### Step 4: バックエンドAPIを理解する

RailsコントローラーでのAPI処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | articles_controller.rb | `app/controllers/api/v1/accounts/articles_controller.rb` | createアクション |

**主要処理フロー**:
- **24-29行目**: createアクション - デフォルトステータス設定、記事作成、関連記事設定

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

```
PortalsArticlesNewPage.vue
    │
    ├─ ArticleEditor.vue
    │      │
    │      ├─ @save-article
    │      │      └─ createNewArticle()
    │      │             ├─ バリデーション（title, content必須）
    │      │             │
    │      │             └─ store.dispatch('articles/create')
    │      │                    └─ actions.create()
    │      │                           └─ articlesAPI.createArticle()
    │      │                                  └─ POST /api/v1/.../articles
    │      │                                         └─ ArticlesController#create
    │      │
    │      ├─ @set-author → setAuthorId()
    │      │
    │      ├─ @set-category → setCategoryId()
    │      │
    │      └─ @go-back → goBackToArticles()
    │             └─ router.push('portals_articles_index')
    │
    └─ 作成成功時
           └─ router.replace('portals_articles_edit')
```

### データフロー図

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

フォーム入力 ────────▶ createNewArticle() ──────────▶ articles/create
  - title                     │
  - content                   ▼
  - authorId             Vuex Action
  - categoryId                │
                              ▼
URLパラメータ ───────▶ articlesAPI.createArticle()
  - portalSlug                │
  - locale                    ▼
                         ArticlesController#create ──▶ articles INSERT
                              │                            │
                              │                            ▼
                              │                       articleId (slug)
                              │                            │
                              ▼                            ▼
                         router.replace() ──────────▶ portals_articles_edit
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| PortalsArticlesNewPage.vue | `app/javascript/dashboard/routes/dashboard/helpcenter/pages/PortalsArticlesNewPage.vue` | ソース | 画面コンポーネント |
| ArticleEditor.vue | `app/javascript/dashboard/components-next/HelpCenter/Pages/ArticleEditorPage/ArticleEditor.vue` | ソース | エディタUI |
| helpcenter.routes.js | `app/javascript/dashboard/routes/dashboard/helpcenter/helpcenter.routes.js` | ソース | ルート定義 |
| actions.js | `app/javascript/dashboard/store/modules/helpCenterArticles/actions.js` | ソース | Vuexアクション |
| articles.js | `app/javascript/dashboard/api/helpCenter/articles.js` | ソース | APIクライアント |
| articles_controller.rb | `app/controllers/api/v1/accounts/articles_controller.rb` | ソース | APIコントローラー |
| article.rb | `app/models/article.rb` | ソース | モデル定義 |
| helpCenter.json | `app/javascript/dashboard/i18n/locale/en/helpCenter.json` | 設定 | i18nメッセージ |
