# 機能設計書 74-リリースアセット

## 概要

本ドキュメントは、GitLabのリリースアセット機能について、その処理概要、入出力仕様、処理フロー、データベース操作仕様を定義する。

### 本機能の処理概要

リリースアセット機能は、リリースに添付するファイル（バイナリ、ドキュメント、パッケージなど）のリンクを管理する機能である。リリースには複数のアセットリンクを追加でき、ダウンロード用の外部URL、またはプロジェクト内リソースへのリンクを設定できる。

**業務上の目的・背景**：ソフトウェアリリースにおいて、ソースコード以外にもコンパイル済みバイナリ、インストーラー、ドキュメント、依存パッケージなど様々な成果物を配布する必要がある。リリースアセット機能により、これらの配布物をリリースに紐づけて一元管理し、ユーザーが必要なファイルを容易にダウンロードできるようにする。

**機能の利用シーン**：
- コンパイル済みバイナリ（exe、dmg、debなど）を配布する場合
- APIドキュメントやリリースノートPDFを添付する場合
- Dockerイメージへのリンクを提供する場合
- 運用手順書（Runbook）へのリンクを追加する場合
- CI/CDパイプラインで自動生成されたアーティファクトをリンクする場合

**主要な処理内容**：
1. アセットリンクの追加（名前、URL、ファイルパス、リンクタイプの設定）
2. アセットリンクの編集
3. アセットリンクの削除
4. アセット一覧の表示
5. アセットのダウンロード（外部URLまたは内部リソース）
6. ソースコードアーカイブ（自動生成）の提供

**関連システム・外部連携**：
- リリース機能（親エンティティ）
- 外部ストレージ（ファイルホスティング）
- CI/CDアーティファクト

**権限による制御**：
- アセットの追加/編集/削除: リリース更新権限
- アセットの閲覧/ダウンロード: リリース閲覧権限

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 86 | リリース新規作成 | 入力画面 | リリースアセットの添付 |
| 87 | リリース詳細 | 結果表示画面 | リリースエビデンスの表示 |
| 88 | リリース編集 | 入力画面 | リリースアセットの編集 |

## 機能種別

CRUD操作 / ファイル管理 / リンク管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| name | String | Yes | リンクの表示名 | 必須、リリース内で一意 |
| url | String | Yes | リンク先URL | 必須、http/https/ftpスキーム、リリース内で一意 |
| filepath | String | No | 直接ダウンロード用パス | 最大128文字、特定形式、リリース内で一意 |
| link_type | String | No | リンクの種別 | other/runbook/package/image |

### 入力データソース

- 画面入力（リリース作成・編集フォーム）
- API リクエスト

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| id | Integer | リンクID |
| name | String | リンク表示名 |
| url | String | リンク先URL |
| filepath | String | 直接ダウンロード用パス |
| link_type | String | リンク種別 |
| external | Boolean | 外部リンクかどうか |
| created_at | DateTime | 作成日時 |

### 出力先

- 画面表示（HTML）
- JSON API レスポンス
- ダウンロードリダイレクト

## 処理フロー

### 処理シーケンス

```
1. リリース存在確認
   └─ 指定されたリリースが存在するか確認
2. 権限確認
   └─ リリース更新権限を確認
3. バリデーション
   └─ 入力パラメータの検証（URL形式、一意性等）
4. アセットリンク保存
   └─ release_linksテーブルへの保存
5. レスポンス返却
   └─ 成功/失敗の結果を返す
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{リリース存在?}
    B -->|No| C[404エラー]
    B -->|Yes| D{更新権限あり?}
    D -->|No| E[403エラー]
    D -->|Yes| F[バリデーション]
    F -->|失敗| G[422エラー]
    F -->|成功| H{URL形式チェック}
    H -->|不正| G
    H -->|正常| I{一意性チェック}
    I -->|重複| G
    I -->|正常| J[DB保存]
    J --> K[成功レスポンス]
    K --> L[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-74-01 | 名前一意制約 | 同一リリース内でリンク名は一意 | リンク作成・編集時 |
| BR-74-02 | URL一意制約 | 同一リリース内でURLは一意 | リンク作成・編集時 |
| BR-74-03 | ファイルパス一意制約 | 同一リリース内でファイルパスは一意 | リンク作成・編集時 |
| BR-74-04 | ファイルパス形式 | `/`で始まり、英数字・ハイフン・ドット・アンダースコアのみ使用可能 | filepathが指定された場合 |
| BR-74-05 | ファイルパス長制限 | 最大128文字 | filepathが指定された場合 |
| BR-74-06 | URLスキーム制限 | http、https、ftpのみ許可 | リンク作成・編集時 |
| BR-74-07 | 内部/外部判定 | URLがプロジェクトのweb_urlで始まる場合は内部リンク | リンク表示時 |

### 計算ロジック

- `internal?`: url.start_with?(release.project.web_url)
- `assets_count`: links.size + sources.size

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| リンク追加 | release_links | INSERT | リリースリンクレコード作成 |
| リンク編集 | release_links | UPDATE | リリースリンク情報更新 |
| リンク削除 | release_links | DELETE | リリースリンクレコード削除 |
| リンク取得 | release_links | SELECT | リリースリンク一覧取得 |

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

#### release_links

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | release_id | リリースID | 必須、外部キー |
| INSERT | name | ユーザー入力値 | 必須 |
| INSERT | url | ユーザー入力値 | 必須 |
| INSERT | filepath | ユーザー入力値 | 任意 |
| INSERT | link_type | ユーザー入力値またはデフォルト(0:other) | enum値 |
| INSERT | created_at | 現在日時 | 自動設定 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 403 | 権限エラー | リリース更新権限なし | エラーメッセージ表示 |
| 404 | NotFound | 存在しないリリースへのアクセス | 404ページ表示 |
| 422 | バリデーションエラー | URL形式不正、名前重複など | エラー内容を表示 |

### リトライ仕様

特になし

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

- リリース作成時、リリースレコードとリンクレコードは同一トランザクション内で保存
- `accepts_nested_attributes_for :links, allow_destroy: true`により、リリース経由での操作をサポート

## パフォーマンス要件

- リンク一覧取得: リリースごとに取得
- ダウンロードリダイレクト: 即時

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

- 外部URLへのリダイレクト時の警告表示
- 内部URLと外部URLの判別
- 権限ベースのアクセス制御

## 備考

- リリースにはソースコードアーカイブ（zip、tar.gz等）が自動的に含まれる
- ソースコードアーカイブはReleases::Sourceクラスで生成
- link_typeによりアセットの種類を分類可能（other, runbook, package, image）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | link.rb | `app/models/releases/link.rb` | リリースリンクの属性、バリデーション、関連定義を確認 |
| 1-2 | source.rb | `app/models/releases/source.rb` | ソースコードアーカイブの自動生成を確認 |

**読解のコツ**:
- **5行目**: `self.table_name = 'release_links'`でテーブル名を確認
- **14-16行目**: バリデーションルールを確認（URL必須、名前必須、一意性）
- **30-35行目**: `link_type` enumの定義を確認

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | releases_controller.rb | `app/controllers/projects/releases_controller.rb` | ダウンロードアクションを確認 |

**主要処理フロー**:
1. **35-43行目**: `downloads`アクションでアセットダウンロード処理
2. **36行目**: `link.url`を解析
3. **38-42行目**: 内部URL/外部URLによる処理分岐

#### Step 3: モデル関連を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | release.rb | `app/models/release.rb` | リリースとリンクの関連定義を確認 |

**主要処理フロー（release.rb）**:
- **17-18行目**: `has_many :links`と`has_many :sorted_links`の関連定義
- **26行目**: `accepts_nested_attributes_for :links, allow_destroy: true`でネスト作成サポート

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

```
Projects::ReleasesController
    │
    └─ downloads
           │
           ├─ release.links.find_by_filepath!
           │
           ├─ internal_url?
           │      └─ redirect_to link.url
           │
           └─ external_url
                  └─ render redirect template
```

### データフロー図

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

リリース作成/編集 ───▶ CreateService ───▶ リリース情報
    │                      │
    │                      └─▶ Release.create ───▶ releasesテーブル
    │                             │
    │                             └─▶ Link.create ───▶ release_linksテーブル
    │
    └── params[:release][:links_attributes]

ダウンロード要求 ───▶ downloads ───▶ リダイレクト
    │                    │
    │                    ├─▶ 内部URL ───▶ 直接リダイレクト
    │                    │
    │                    └─▶ 外部URL ───▶ 警告ページ表示
    │
    └── filepath パラメータ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| link.rb | `app/models/releases/link.rb` | モデル | リリースリンクのデータ構造定義 |
| source.rb | `app/models/releases/source.rb` | モデル | ソースコードアーカイブ生成 |
| release.rb | `app/models/release.rb` | モデル | リリース（親）のデータ構造定義 |
| releases_controller.rb | `app/controllers/projects/releases_controller.rb` | コントローラー | ダウンロード処理 |
| links/params.rb | `app/services/releases/links/params.rb` | サービス | リンクパラメータの処理 |
