# 画面設計書 282-Wiki表示

## 概要

本ドキュメントは、GitLabのWikiページ表示画面の設計を記載したものである。

### 本画面の処理概要

**業務上の目的・背景**：Wikiはプロジェクトやグループに関するドキュメントを作成・共有するための機能である。Wiki表示画面は、ユーザーがWikiページのコンテンツを閲覧するために必要な画面であり、プロジェクト情報の共有、技術ドキュメントの参照、チームナレッジの蓄積といった業務ニーズに対応する。Markdownやその他のマークアップ形式で記述されたコンテンツをレンダリングして表示する。

**画面へのアクセス方法**：プロジェクトまたはグループのサイドバーから「Wiki」をクリックするか、直接URLで `/:namespace/:project/-/wikis/:page_slug` にアクセスする。Wiki閲覧権限を持つユーザーがアクセス可能。

**主要な操作・処理内容**：
1. Wikiページのコンテンツを表示する（Markdown/AsciiDoc/その他形式）
2. ページの編集履歴を確認する
3. ページの編集画面に遷移する
4. サイドバーでページ一覧を確認する
5. 新規ページを作成する
6. クローンURLを取得する（SSH/HTTP）
7. ページを削除する（権限がある場合）
8. 過去バージョンを表示する
9. コメント・ディスカッションを追加する

**画面遷移**：
- 遷移元：プロジェクト詳細画面、グループ詳細画面、Wiki一覧画面、検索結果画面
- 遷移先：Wiki編集画面、Wiki履歴画面、Wiki差分画面、新規Wiki作成画面

**権限による表示制御**：
- 読み取り権限：Wikiの閲覧が可能
- 作成権限：編集ボタン、新規作成ボタンが表示される
- 管理権限：削除ボタンが表示される
- アーカイブされたコンテナ：編集機能が無効化される

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 68 | Wiki閲覧 | 主機能 | Wikiページの表示処理 |

## 画面種別

詳細

## URL/ルーティング

| メソッド | パス | コントローラー#アクション |
|----------|------|---------------------------|
| GET | `/:namespace/:project/-/wikis/:id` | `projects/wikis#show` |
| GET | `/:namespace/:project/-/wikis/:id/:version_id` | `projects/wikis#show` (過去バージョン) |
| GET | `/groups/:group_id/-/wikis/:id` | `groups/wikis#show` |

## 入出力項目

| 項目名 | 項目ID | データ型 | 必須 | 説明 |
|--------|--------|----------|------|------|
| ページスラッグ | id | String | Yes | URLパス内のページ識別子 |
| バージョンID | version_id | String | No | 特定バージョン表示時のコミットSHA |

## 表示項目

| 項目名 | 説明 |
|--------|------|
| ページタイトル | Wikiページのタイトル（Front Matterから取得可能） |
| ページコンテンツ | Markdownなどからレンダリングされた本文 |
| 最終更新情報 | 更新者、更新日時 |
| 編集ボタン | 編集画面への遷移ボタン（権限がある場合） |
| 新規作成ボタン | 新規ページ作成画面への遷移ボタン |
| 履歴ボタン | 履歴画面への遷移ボタン |
| クローンURL | SSH/HTTPのクローンURL |
| サイドバー | ページ一覧とナビゲーション |
| バージョン情報 | 過去バージョン表示時のコミット情報 |
| 復元ボタン | 過去バージョン表示時に表示 |

## イベント仕様

### 1-編集ボタン押下

**トリガー**：「Edit」ボタンをクリック

**処理フロー**：
1. Wiki編集画面へ遷移
2. パス: `/:namespace/:project/-/wikis/:id/edit`

### 2-新規作成ボタン押下

**トリガー**：「New page」ボタンをクリック

**処理フロー**：
1. 新規Wiki作成画面へ遷移
2. ランダムUUIDを含むパスにリダイレクト

### 3-履歴ボタン押下

**トリガー**：「History」ボタンをクリック

**処理フロー**：
1. Wiki履歴画面へ遷移
2. パス: `/:namespace/:project/-/wikis/:id/history`

### 4-バージョン復元

**トリガー**：過去バージョン表示時に「Restore this version」ボタンをクリック

**処理フロー**：
1. 該当バージョンの内容で新しいコミットを作成
2. 最新バージョンとして保存
3. 最新ページ表示にリダイレクト

### 5-削除ボタン押下

**トリガー**：「Delete」ボタンをクリック

**処理フロー**：
1. 確認ダイアログを表示
2. 承認後、WikiPages::DestroyServiceを呼び出し
3. Wiki一覧画面へリダイレクト

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| ページ表示 | - | SELECT | Gitリポジトリから読み取り（DBアクセスなし） |
| 復元操作 | wiki_page_meta | UPDATE | メタ情報の更新（必要時） |
| 削除操作 | wiki_page_meta | DELETE | メタ情報の削除 |

### 備考

WikiコンテンツはGitリポジトリに格納されるため、主なデータアクセスはGitalyを介したGit操作となる。データベースには一部のメタ情報のみが格納される。

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| MSG001 | 通知 | Wiki page was successfully deleted. | ページ削除成功時 |
| MSG002 | 警告 | The content of this page is not encoded in UTF-8. Edits can only be made via the Git repository. | 非UTF-8エンコーディング検出時 |
| MSG003 | 通知 | The page at `X` has been moved to `Y`. | リダイレクト発生時 |
| MSG004 | エラー | Page not found | ページが存在しない場合 |
| MSG005 | エラー | Could not access the Wiki Repository at this time. | リポジトリアクセスエラー時 |

## 例外処理

| 例外条件 | 画面表示・動作 |
|----------|---------------|
| ページが存在しない | 404ページまたは作成フォームを表示（権限による） |
| Wikiリポジトリが存在しない | 空のWiki画面を表示 |
| エンコーディングエラー | 警告メッセージを表示、編集機能を制限 |
| Gitタイムアウト | Git error画面を表示 |
| アクセス権限不足 | 403 Forbiddenエラー |
| リダイレクトループ | 警告メッセージを表示、リダイレクトを停止 |

## 備考

- WikiコンテンツはGitリポジトリに格納される
- 対応マークアップ形式：Markdown、AsciiDoc、Org、RDoc等
- Front Matter（YAML形式）でタイトルなどのメタデータを指定可能
- diagrams.net連携が有効な場合、図の埋め込みが可能
- テンプレート機能：`templates/` ディレクトリ配下のページをテンプレートとして使用可能
- リダイレクト機能：`.redirects.yml` ファイルでリダイレクトを設定可能

---

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

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

### 推奨読解順序

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

WikiページのデータモデルとGit連携を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | wiki_page.rb | `app/models/wiki_page.rb` | WikiPageモデルの属性とバリデーション |
| 1-2 | wiki.rb | `app/models/wiki.rb` | Wikiリポジトリとの連携 |

**読解のコツ**: WikiPageはActiveRecordモデルではなく、Gitリポジトリのファイルをラップするクラス。`persisted?` はGitファイルの存在をチェックする。

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

コントローラーとConcernの処理フローを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | wiki_actions.rb | `app/controllers/concerns/wiki_actions.rb` | showアクションの実装 |
| 2-2 | show.html.haml | `app/views/shared/wikis/show.html.haml` | ビューテンプレートの構造 |

**主要処理フロー**:
1. **行131-147**: `show` アクションでページ存在チェック
2. **行132-140**: ページが存在する場合の処理
3. **行141-146**: ファイルBlobまたは作成フォームの表示分岐
4. **行149-184**: リダイレクト処理のハンドリング

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

Vue.jsコンポーネントとのデータ連携を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | show.html.haml | `app/views/shared/wikis/show.html.haml` | Vue.jsマウントポイントとデータ属性 |
| 3-2 | wiki_page_info helper | `app/helpers/wikis_helper.rb` | ページ情報のJSON生成 |

**主要データ属性**（行11-48）:
- `container_id`: コンテナ（プロジェクト/グループ）ID
- `page_info`: ページの詳細情報JSON
- `page_version`: バージョン情報
- `show_edit_button`: 編集ボタン表示フラグ
- `clone_ssh_url`, `clone_http_url`: クローンURL

#### Step 4: サービス層を理解する

Wiki操作のビジネスロジックを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | destroy_service.rb | `app/services/wiki_pages/destroy_service.rb` | 削除処理 |
| 4-2 | front_matter_parser.rb | `lib/gitlab/wiki_pages/front_matter_parser.rb` | Front Matter解析 |

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

```
WikiActions#show (Concern)
    │
    ├─ before_action :wiki
    │      └─ Wiki.for_container(container, current_user)
    │             └─ wiki.create_wiki_repository
    │
    ├─ before_action :page
    │      └─ wiki.find_page(*page_params)
    │             └─ Gitlab::Git::WikiPage
    │
    ├─ page存在時
    │      ├─ @templates = templates_list
    │      └─ render 'shared/wikis/show'
    │             └─ #js-vue-wiki-app (Vue.js)
    │
    └─ page不存在時
           ├─ file_blob存在 → send_wiki_file_blob
           └─ 権限あり → handle_create_form
                  └─ render 'shared/wikis/edit'
```

### データフロー図

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

URLパラメータ ───▶ WikiActions#show ───▶ Vue.js App
(id, version_id)          │
                          ▼
                    wiki.find_page
                          │
                          ▼
                    Gitaly (Git API)
                          │
                          ▼
                    WikiPage Object
                          │
                          ▼
                    wiki_page_info JSON ───▶ レンダリングされた
                          │                   Wikiコンテンツ
                          ▼
                    content_api (Ajax) ───▶ HTML出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| show.html.haml | `app/views/shared/wikis/show.html.haml` | テンプレート | 表示画面のビュー |
| wiki_actions.rb | `app/controllers/concerns/wiki_actions.rb` | Concern | Wiki関連アクション |
| wiki_page.rb | `app/models/wiki_page.rb` | モデル | WikiPageモデル |
| wiki.rb | `app/models/wiki.rb` | モデル | Wikiリポジトリモデル |
| wikis_helper.rb | `app/helpers/wikis_helper.rb` | ヘルパー | Wikiヘルパーメソッド |
| front_matter_parser.rb | `lib/gitlab/wiki_pages/front_matter_parser.rb` | ライブラリ | Front Matter解析 |
| destroy_service.rb | `app/services/wiki_pages/destroy_service.rb` | サービス | 削除ビジネスロジック |
| layout.html.haml | `app/views/shared/wikis/_layout.html.haml` | テンプレート | Wiki共通レイアウト |
