# 画面設計書 247-不正利用レポート一覧

## 概要

本ドキュメントは、GitLab管理者がユーザーから報告された不正利用レポートを一覧表示し管理する画面の設計書です。

### 本画面の処理概要

不正利用レポート一覧画面は、GitLabユーザーから報告された不正利用（スパム、フィッシング、著作権侵害など）のレポートを一覧表示し、管理者が対応を行うための画面です。

**業務上の目的・背景**：GitLabはオープンなプラットフォームであり、悪意のあるユーザーによる不正行為（スパム投稿、フィッシング、マルウェア配布など）が発生する可能性があります。管理者はこの画面から報告された不正利用を確認し、適切な対応（ユーザーのBAN、ブロック、削除など）を行うことで、プラットフォームの健全性を維持します。

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

**主要な操作・処理内容**：
1. 不正利用レポートの一覧表示（ステータス別フィルタ）
2. カテゴリ別フィルタリング
3. ユーザー/報告者別フィルタリング
4. ソート機能
5. レポート詳細画面への遷移
6. ページネーション

**画面遷移**：
- 遷移元：管理者ダッシュボード
- 遷移先：不正利用レポート詳細画面

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

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 139 | 監査イベント | 主機能 | 不正利用レポート一覧表示・管理 |

## 画面種別

一覧

## URL/ルーティング

- URL: `/admin/abuse_reports`
- HTTP メソッド: GET
- ルート名: `admin_abuse_reports`

## 入出力項目

本画面は主にフィルタリング・検索のための入力があります。

| 項目名 | 項目ID | 型 | 必須 | 備考 |
|--------|--------|-----|------|------|
| ステータス | status | String | - | open/closed |
| カテゴリ | category | String | - | spam, offensive等 |
| ユーザー | user | String | - | ユーザー名 |
| 報告者 | reporter | String | - | 報告者ユーザー名 |
| ソート | sort | String | - | 並び替え条件 |

## 表示項目

| 項目名 | 表示形式 | 備考 |
|--------|----------|------|
| ページタイトル | テキスト | "Abuse reports" |
| レポート一覧 | テーブル/カード | Vue.jsコンポーネント |
| ステータスフィルタ | タブ/ボタン | Open/Closed |
| カテゴリフィルタ | ドロップダウン | spam, offensive等 |
| ページネーション | ナビゲーション | ページ切り替え |

### 一覧表示項目（集約表示）

| 項目名 | 説明 |
|--------|------|
| 報告対象ユーザー | 報告されたユーザー情報 |
| カテゴリ | 不正利用のカテゴリ |
| 報告件数 | 同一ユーザー・カテゴリの報告数 |
| 報告者 | 報告したユーザー |
| 報告日時 | 最初の報告日時 |
| ステータス | Open/Closed |

## イベント仕様

### 1-ステータスフィルタ切り替え

**トリガー**: ステータスタブ切り替え

**処理フロー**:
1. statusパラメータを変更してGETリクエスト
2. AbuseReportsFinderで該当ステータスのレポート取得
3. 一覧再表示

### 2-カテゴリフィルタ

**トリガー**: カテゴリドロップダウン選択

**処理フロー**:
1. categoryパラメータを設定してGETリクエスト
2. by_categoryスコープでフィルタリング
3. 一覧再表示

### 3-レポート詳細表示

**トリガー**: レポート行クリック

**処理フロー**: 不正利用レポート詳細画面へ遷移

### 4-ページネーション

**トリガー**: ページリンククリック

**処理フロー**:
1. pageパラメータを設定してGETリクエスト
2. 該当ページのレポート取得
3. 一覧再表示

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

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

本画面は一覧表示のため、直接的なデータベース更新はありません。

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 一覧表示 | abuse_reports | SELECT | レポート取得 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| MSG001 | 空状態 | レポートなしメッセージ | 該当レポートが0件の場合 |

## 例外処理

| 例外条件 | 処理内容 | 表示メッセージ |
|----------|----------|---------------|
| 権限不足 | 403エラー画面へリダイレクト | アクセスが拒否されました |

## 備考

- デフォルトステータスは「open」
- Openステータスの場合、同一ユーザー・カテゴリで集約表示される（aggregated_by_user_and_category）
- Vue.jsコンポーネント（`#js-abuse-reports-list-app`）でレンダリング
- カテゴリ: spam, offensive, phishing, crypto, credentials, copyright, malware, other
- ステータス: open, closed
- ソート: created_at_desc, created_at_asc, updated_at_desc, updated_at_asc, number_of_reports_desc

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | abuse_report.rb | `app/models/abuse_report.rb` | AbuseReportモデル定義、カテゴリ、ステータス |

**読解のコツ**:
- `enum :category`でカテゴリ定義確認
- `enum :status`でステータス定義確認
- `aggregated_by_user_and_category`メソッドで集約ロジック確認

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | abuse_reports_controller.rb | `app/controllers/admin/abuse_reports_controller.rb` | indexアクション |

**主要処理フロー**:
1. **6行目**: `before_action :set_status_param`でデフォルトステータス設定
2. **9-11行目**: `index`アクション - AbuseReportsFinderでレポート取得
3. **48-49行目**: デフォルトステータスを「open」に設定

#### Step 3: Finderを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | abuse_reports_finder.rb | `app/finders/abuse_reports_finder.rb` | クエリロジック |

**主要処理フロー**:
- **19-25行目**: `execute`メソッド - フィルタ・集約・ソート
- **29-44行目**: 各種フィルタメソッド
- **91-96行目**: `aggregate_reports` - Open時の集約処理

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | index.html.haml | `app/views/admin/abuse_reports/index.html.haml` | 一覧画面レイアウト |
| 4-2 | abuse_reports_helper.rb | `app/helpers/admin/abuse_reports_helper.rb` | データヘルパー |

**主要処理フロー**:
- **5行目**: Vue.jsコンポーネントマウントポイント
- ヘルパーでシリアライズデータ生成

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

```
ブラウザ (GET /admin/abuse_reports)
    │
    ├─ before_action :set_status_param
    │      └─ params[:status] ||= 'open'
    │
    └─ Admin::AbuseReportsController#index
           ├─ AbuseReportsFinder.new(permitted_index_params).execute
           │      ├─ filter_reports
           │      │      ├─ filter_by_status
           │      │      ├─ filter_by_user
           │      │      ├─ filter_by_reporter
           │      │      └─ filter_by_category
           │      ├─ aggregate_reports (Open時)
           │      │      └─ aggregated_by_user_and_category
           │      └─ sort_reports
           │
           └─ View: admin/abuse_reports/index.html.haml
                  └─ Vue.js Component: #js-abuse-reports-list-app
```

### データフロー図

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

フィルタパラメータ ───▶ AbuseReportsController#index ──▶ 一覧HTML
  - status                    │
  - category                  ├─ AbuseReportsFinder
  - user                      │      ├─ フィルタリング
  - reporter                  │      ├─ 集約（Open時）
  - sort                      │      └─ ソート
  - page                      │
                              └─ Vue.jsコンポーネントへデータ渡し
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| abuse_reports_controller.rb | `app/controllers/admin/abuse_reports_controller.rb` | コントローラ | リクエスト処理 |
| abuse_report.rb | `app/models/abuse_report.rb` | モデル | データ定義 |
| abuse_reports_finder.rb | `app/finders/abuse_reports_finder.rb` | ファインダー | クエリロジック |
| index.html.haml | `app/views/admin/abuse_reports/index.html.haml` | ビュー | 一覧画面 |
| abuse_reports_helper.rb | `app/helpers/admin/abuse_reports_helper.rb` | ヘルパー | データシリアライズ |
| admin.rb | `config/routes/admin.rb` | 設定 | ルーティング |
| abuse_report_serializer.rb | `app/serializers/admin/abuse_report_serializer.rb` | シリアライザ | JSON変換 |
