# 機能設計書 32-トピック追加

## 概要

本ドキュメントは、Wikipedia iOSアプリにおけるトークページ（議論ページ）への新規トピック追加機能について、その設計仕様を詳細に記載したものである。

### 本機能の処理概要

トピック追加機能は、ユーザーがWikipediaのトークページに新しい議論トピック（セクション）を作成するための機能である。

**業務上の目的・背景**：Wikipediaのトークページは記事の編集方針について議論を行う場である。新しい議題を提起するためには新規トピックを作成する必要があり、この機能はモバイルアプリから議論を開始するために不可欠である。記事改善のための提案や質問を投稿することで、Wikipediaコミュニティへの貢献を促進する。

**機能の利用シーン**：
- 記事の編集方針について新しい議題を提起したい場合
- 記事の内容に関する質問を投稿したい場合
- 記事の改善提案を行いたい場合
- 編集者間で新しい合意形成を開始したい場合

**主要な処理内容**：
1. トピック追加画面の表示（モーダルビュー）
2. トピックタイトルと本文の入力
3. 入力内容のバリデーション
4. MediaWiki APIを通じたトピック投稿
5. 投稿結果の処理とトークページデータの再取得

**関連システム・外部連携**：MediaWiki Action APIを使用してトークページに新規セクションを追加する。

**権限による制御**：ログイン済みユーザーは自身のアカウントで投稿可能。一時アカウント機能が有効なWikiでは、未ログインユーザーも一時アカウントとして投稿できる。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | TalkPageViewController | 主画面 | トピック追加ボタンのタップ |
| - | TalkPageTopicComposeViewController | 入力画面 | トピックタイトル・本文入力、投稿 |

## 機能種別

CRUD操作（Create） / データ連携

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| topicTitle | String | Yes | トピックのタイトル | 空文字列でないこと、空白のみでないこと |
| topicBody | String | Yes | トピックの本文 | 空文字列でないこと、空白のみでないこと |

### 入力データソース

- 画面入力：ユーザーがテキストフィールド/テキストビューに入力した内容

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 投稿結果 | Result<Void, Error> | トピック投稿の成功または失敗 |
| 更新されたトークページ | TalkPageDataController | 新規トピックを含むトークページ情報 |

### 出力先

- MediaWiki API（新規セクション追加）
- 画面表示（投稿結果のフィードバック）

## 処理フロー

### 処理シーケンス

```
1. ユーザーがトピック追加ボタン（+ボタン）をタップ
   └─ TalkPageViewController.addTopicButtonPressed()
2. トピック作成画面をモーダル表示
   └─ TalkPageTopicComposeViewController
3. ユーザーがタイトルと本文を入力
   └─ titleTextField, bodyTextView
4. 入力内容のバリデーション
   └─ evaluatePublishButtonEnabledState()
5. 投稿ボタンタップ
   └─ tappedPublish()
6. デリゲート経由で投稿処理を実行
   └─ TalkPageTopicComposeViewControllerDelegate.tappedPublish()
7. TalkPageDataControllerを通じてAPI呼び出し
   └─ postTopic(title:body:)
8. 投稿結果の処理
   └─ 成功時：モーダルを閉じ、データを再取得
   └─ 失敗時：エラーメッセージを表示
```

### フローチャート

```mermaid
flowchart TD
    A[+ボタンタップ] --> B[トピック作成画面表示]
    B --> C[タイトル入力]
    C --> D[本文入力]
    D --> E{バリデーション}
    E -->|タイトル空| F[投稿ボタン無効]
    E -->|本文空| F
    E -->|両方入力済み| G[投稿ボタン有効]
    G --> H[投稿ボタンタップ]
    H --> I{認証状態確認}
    I -->|ログイン済み| J[投稿実行]
    I -->|未ログイン| K{一時アカウント対応Wiki?}
    K -->|Yes| J
    K -->|No| L[ログイン促進パネル]
    L --> J
    J --> M{投稿成功?}
    M -->|Yes| N[モーダルを閉じる]
    N --> O[トークページ再取得]
    M -->|No| P[エラー表示]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-32-01 | タイトル必須 | トピックタイトルは必須入力 | 常時 |
| BR-32-02 | 本文必須 | トピック本文は必須入力 | 常時 |
| BR-32-03 | 空白トリム | 入力値の前後空白を除去して判定 | バリデーション時 |
| BR-32-04 | 破棄確認 | 入力済み状態で閉じる場合は確認ダイアログ表示 | タイトルまたは本文入力済み時 |
| BR-32-05 | ライセンス同意 | 投稿時にCC BY-SA 4.0とGFDLライセンスに同意 | 投稿時 |

### 計算ロジック

該当なし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| トピック投稿 | MediaWiki API | INSERT（外部API） | トークページに新規セクションを追加 |

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

ローカルデータベースへの直接操作はなし。MediaWiki APIを介した外部システムへの書き込みのみ。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ネットワークエラー | 通信失敗時 | エラーアラート表示 |
| - | 認証エラー | セッション切れ時 | 再ログインを促す |
| - | APIエラー | MediaWiki側でエラー発生時 | エラーメッセージを表示 |

### リトライ仕様

自動リトライは実装されていない。ユーザーが手動で再投稿を試みる必要がある。

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

MediaWiki APIへの単一リクエストのため、アプリ側でのトランザクション管理は不要。

## パフォーマンス要件

特に明示的な要件なし。ネットワーク状況に依存する。

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

- 認証トークンはKeychainに安全に保存
- 一時アカウント機能による匿名ユーザーのプライバシー保護
- HTTPS通信による通信内容の暗号化
- ライセンス条項への同意を画面に表示

## 備考

- RTL（右から左）言語への対応
- 書式設定ツールバーが提供され、Wikiテキスト形式での入力を支援
- キーボード表示時のレイアウト自動調整

---

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

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

### 推奨読解順序

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

まず、トピック作成に必要なビューモデルを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | TalkPageTopicComposeViewController.swift | `Wikipedia/Code/TalkPageTopicComposeViewController.swift` | TalkPageTopicComposeViewModel構造体（8-13行目） |

**読解のコツ**: ビューモデルには`semanticContentAttribute`（RTL対応）、`siteURL`、`pageLink`、`wikiHasTempAccounts`（一時アカウント対応フラグ）が含まれる。

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

トピック追加ボタンタップから処理が開始される。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | TalkPageTopicComposeViewController.swift | `Wikipedia/Code/TalkPageTopicComposeViewController.swift` | トピック作成UIの全体構造 |

**主要処理フロー**:
1. **178-191行目**: `viewDidLoad()`でUI初期化、ナビゲーションバー設定
2. **489-491行目**: `evaluatePublishButtonEnabledState()`でバリデーション
3. **533-579行目**: `tappedPublish()`で投稿処理開始

#### Step 3: UIコンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TalkPageTopicComposeViewController.swift | `Wikipedia/Code/TalkPageTopicComposeViewController.swift` | 入力フィールドとボタンの配置 |

**主要処理フロー**:
- **69-75行目**: titleTextField（タイトル入力フィールド）
- **83-93行目**: bodyTextView（本文入力テキストビュー）
- **38-42行目**: publishButton（投稿ボタン）

#### Step 4: キーボード処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | TalkPageTopicComposeViewController.swift | `Wikipedia/Code/TalkPageTopicComposeViewController.swift` | キーボードフレーム変化への対応 |

**主要処理フロー**:
- **425-460行目**: キーボード表示・非表示時のレイアウト調整

#### Step 5: デリゲート実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | TalkPageViewController.swift | `Wikipedia/Code/TalkPageViewController.swift` | TalkPageTopicComposeViewControllerDelegateの実装 |

**主要処理フロー**:
- `tappedPublish(topicTitle:topicBody:composeViewController:)`での実際の投稿処理

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

```
TalkPageViewController
    │
    ├─ addTopicButtonPressed()
    │      └─ TalkPageTopicComposeViewController（モーダル表示）
    │              ├─ viewDidLoad()
    │              ├─ evaluatePublishButtonEnabledState()
    │              └─ tappedPublish()
    │
    └─ tappedPublish(topicTitle:topicBody:composeViewController:) [デリゲートコールバック]
           └─ TalkPageDataController.postTopic()
                   └─ MediaWiki API呼び出し
```

### データフロー図

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

タイトル入力 ────────────▶  TalkPageTopicComposeViewController  ▶ MediaWiki API
                           ┌────────────────────────────────┐     (新規セクション)
本文入力 ────────────────▶  │  バリデーション               │
                           │  認証状態確認                  │  ─▶ 画面更新
サイト情報 ────────────────▶│  投稿リクエスト生成           │     (結果通知)
(viewModel)                └────────────────────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| TalkPageTopicComposeViewController.swift | `Wikipedia/Code/TalkPageTopicComposeViewController.swift` | ソース | トピック作成画面のビューコントローラー |
| TalkPageViewController.swift | `Wikipedia/Code/TalkPageViewController.swift` | ソース | トークページ全体の制御、デリゲート実装 |
| TalkPageDataController.swift | `Wikipedia/Code/TalkPageDataController.swift` | ソース | トークページデータ操作、API呼び出し |
| TalkPageFormattingToolbarView.swift | `Wikipedia/Code/TalkPageFormattingToolbarView.swift` | ソース | 書式設定ツールバー |
| EditAttemptFunnel.swift | `Wikipedia/Code/EditAttemptFunnel.swift` | ソース | 編集試行のイベントログ |
