# 機能設計書 37-マイビュー

## 概要

本ドキュメントは、Jenkinsにおけるマイビュー（MyView）機能の設計を記載したものである。マイビューは、ユーザー個人用のカスタムビューであり、現在のユーザーがItem.CONFIGUREを持つジョブのみを自動的に表示する。

### 本機能の処理概要

本機能は、ログインユーザーが設定権限を持つジョブのみを自動的にフィルタリングして表示する特殊なビューを提供する。

**業務上の目的・背景**：大規模なJenkins環境では、ユーザーは通常、全てのジョブではなく自分が管理するジョブにのみ関心がある。マイビューを使用することで、ユーザーは自動的に自分に関係するジョブ（設定権限を持つジョブ）のみを表示でき、効率的に作業できる。手動でジョブを選択する必要がないため、新しいジョブが追加されても自動的に表示に反映される。

**機能の利用シーン**：
- 自分が担当するジョブのみを一覧表示
- プロジェクトマネージャーが自分の管轄ジョブを把握
- 新規メンバーが自分に割り当てられたジョブを確認
- 権限設定の動的な反映によるリアルタイムなビュー更新

**主要な処理内容**：
1. 現在のユーザーの認証情報取得
2. Item.CONFIGURE権限に基づくジョブフィルタリング
3. 動的なジョブ一覧の生成
4. 編集不要（設定ページなし）のシンプルな構造

**関連システム・外部連携**：Viewの基底クラスを継承。SecurityRealmと連携してユーザー認証情報を取得。ACLを使用して権限チェック。

**権限による制御**：セキュリティが有効な場合のみインスタンス化可能。表示されるジョブはItem.CONFIGURE権限に基づく。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 21 | 新しいビューの作成 | 作成画面 | マイビューの新規作成 |

## 機能種別

UI管理 / ユーザー個人化 / 動的フィルタリング

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| name | String | Yes | ビュー名 | Jenkins.checkGoodName() |

### 入力データソース

- SecurityContext: 現在のユーザー認証情報
- ACL: 各ジョブの権限情報

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| items | Collection<TopLevelItem> | Item.CONFIGUREを持つジョブ一覧 |

### 出力先

- HTMLレスポンス: ジョブ一覧テーブル
- JSON/XML: REST APIレスポンス

## 処理フロー

### 処理シーケンス

```
1. getItems()呼び出し
   └─ ビューに含まれるジョブの取得要求
2. 全ジョブ取得
   └─ ViewGroup.getItemGroup().getItems()で全ジョブを取得
3. 権限フィルタリング
   └─ 各ジョブでitem.hasPermission(Item.CONFIGURE)をチェック
4. 結果返却
   └─ 権限のあるジョブのみを返却
```

### フローチャート

```mermaid
flowchart TD
    A[getItems呼出] --> B[ItemGroup.getItems取得]
    B --> C[各ジョブをループ]
    C --> D{hasPermission Item.CONFIGURE?}
    D -->|Yes| E[結果リストに追加]
    D -->|No| F[スキップ]
    E --> G{次のジョブ?}
    F --> G
    G -->|Yes| C
    G -->|No| H[結果返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-37-01 | セキュリティ必須 | セキュリティが無効な場合、MyViewは作成不可 | isInstantiable() |
| BR-37-02 | 設定不要 | MyViewは設定ページを持たない（submit()は空） | 常時 |
| BR-37-03 | 動的更新 | 権限変更は即座にビューに反映 | 常時（キャッシュなし） |
| BR-37-04 | CONFIGURE基準 | Item.CONFIGURE権限で表示を判定 | contains(), getItems() |

### 計算ロジック

ジョブ表示判定: `item.hasPermission(Item.CONFIGURE)`

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

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

| 操作 | 対象 | 操作種別 | 概要 |
|-----|------|---------|------|
| ビュー作成 | config.xml | UPDATE | ViewGroup設定にMyViewを追加 |
| ビュー削除 | config.xml | UPDATE | ViewGroup設定からMyViewを削除 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | MyViewは単純な構造のため特別なエラーは少ない | - |

### リトライ仕様

getItems()はステートレスな読み取り操作であり、リトライは安全。

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

MyViewは設定を持たないため、トランザクション管理は不要。

## パフォーマンス要件

- getItems()は全ジョブに対して権限チェックを行うため、大規模環境では注意
- 権限チェックはACLを使用するため、キャッシュが効く場合が多い

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

- Item.CONFIGUREはItem.READ以上の権限を要求するため、閲覧のみの権限では表示されない
- 動的なフィルタリングにより、権限変更が即座に反映

## 備考

- @Symbol("myView")により、JenkinsfileからmyViewとして参照可能
- getPostConstructLandingPage()は空文字を返す（設定ページがないため）
- MyViewsPropertyと組み合わせてユーザー専用ビューコンテナを提供

---

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

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

### 推奨読解順序

#### Step 1: MyViewの構造を理解する

マイビューのシンプルな構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | MyView.java | `core/src/main/java/hudson/model/MyView.java` | クラス全体 |

**主要処理フロー**:
- **52行目**: MyViewクラス定義（View継承）
- **53-56行目**: コンストラクタ（@DataBoundConstructor）
- **63-66行目**: contains() - Item.CONFIGUREで判定
- **70-77行目**: doCreateItem() - ジョブ作成（ViewGroupに委譲）
- **80-83行目**: getItems() - Item.CONFIGUREでフィルタリング
- **86-88行目**: getPostConstructLandingPage() - 空文字（設定ページなし）
- **91-101行目**: submit() - 空実装（設定なし）

**読解のコツ**: MyViewは非常にシンプルな実装であり、contains()とgetItems()がItem.CONFIGUREでフィルタリングしている点が重要。

#### Step 2: Descriptorを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | MyView.java | `core/src/main/java/hudson/model/MyView.java` | DescriptorImpl内部クラス |

**主要処理フロー**:
- **112-121行目**: DescriptorImpl
- **118-120行目**: isInstantiable() - セキュリティ有効時のみtrue
- **124-127行目**: getDisplayName() - 表示名取得

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

```
MyView.getItems()
    │
    └─ getOwner().getItemGroup().getItems(filter)
           │
           ├─ ItemGroup.getItems()
           │
           └─ filter: item -> item.hasPermission(Item.CONFIGURE)
                  │
                  └─ ACL.hasPermission(Item.CONFIGURE)
                         │
                         └─ AuthorizationStrategy.getACL(item)
```

### データフロー図

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

SecurityContext ────────▶ MyView.getItems() ─────────────▶ List<TopLevelItem>
      │                        │
      │                        ▼
      │               ItemGroup.getItems(filter)
      │                        │
      │                        ▼
      │               各ジョブでhasPermission
      │                        │
      └────────────────▶ Item.CONFIGURE判定
                               │
                               ▼
                      権限ありジョブのみ返却
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| MyView.java | `core/src/main/java/hudson/model/MyView.java` | ソース | マイビュー実装 |
| MyViewsProperty.java | `core/src/main/java/hudson/model/MyViewsProperty.java` | ソース | ユーザーごとのビューコンテナ |
| View.java | `core/src/main/java/hudson/model/View.java` | ソース | ビューの基底クラス |
| view/main.jelly | `core/src/main/resources/hudson/model/MyView/main.jelly` | ビュー | メイン表示画面 |
| view/newViewDetail.jelly | `core/src/main/resources/hudson/model/MyView/newViewDetail.jelly` | ビュー | 新規作成時の説明 |
