# 機能設計書 133-デザインマネジメント

## 概要

本ドキュメントは、GitLabにおけるデザインマネジメント機能の設計について記述する。イシューへのデザイン画像のアップロード、バージョン管理、コメント機能を通じて、デザイナーと開発者のコラボレーションを支援する機能を定義する。

### 本機能の処理概要

**業務上の目的・背景**：ソフトウェア開発においてデザインレビューは重要なプロセスであるが、従来はデザインファイルが分散して管理され、バージョン管理やフィードバック収集が困難であった。デザインマネジメント機能により、GitLabのイシュー管理と統合されたデザインレビューワークフローを実現し、デザイナーと開発者のコラボレーションを効率化する。

**機能の利用シーン**：
- UIデザインの新規作成時にイシューへデザイン画像をアップロード
- デザイン変更時にバージョン履歴を保持して差分を確認
- デザインの特定箇所にピンポイントでコメントを付与してフィードバック
- デザインのステータス管理（新規/現行/削除済み）
- デザイン間の相対位置による並び順管理

**主要な処理内容**：
1. イシューへのデザイン画像のアップロード
2. デザインのバージョン管理（Git LFSを利用）
3. デザインへのコメント・メンション機能
4. デザインのステータス管理（new/current/deleted）
5. デザイン参照リンクの生成
6. デザインに関するイベント記録

**関連システム・外部連携**：
- Git LFS（大容量ファイルストレージ）
- デザイン専用Gitリポジトリ
- イシュー管理システム

**権限による制御**：
- `read_design`: デザインの閲覧
- `create_design`: デザインのアップロード
- `destroy_design`: デザインの削除

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | イシュー詳細画面 | 主機能 | デザインタブでの表示・操作 |
| - | ワークアイテム詳細 | 補助機能 | デザインウィジェット表示 |

## 機能種別

CRUD操作 / バージョン管理 / コメント / ファイル管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| filename | String | Yes | デザインファイル名 | 最大255文字、画像拡張子のみ |
| issue_id | Integer | Yes | 紐付けるイシューID | 存在するイシュー |
| description | String | No | デザイン説明 | 最大10000文字 |
| file | File | Yes (アップロード時) | 画像ファイル | サポートされる画像形式 |

### 入力データソース

- GitLab UI上でのファイルアップロード
- GraphQL APIからのミューテーション

### サポートされる画像形式

安全な画像形式: png, jpg, jpeg, gif, bmp, tiff, ico, webp
危険な画像形式（フィーチャーフラグで有効化）: svg

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| id | Integer | デザインID |
| iid | Integer | プロジェクト内の一意ID |
| filename | String | ファイル名 |
| description | String | デザイン説明 |
| status | String | ステータス（new/current/deleted） |
| versions | Array | バージョン一覧 |
| notes_count | Integer | コメント数 |
| diff_refs | Object | 差分参照情報 |
| full_path | String | ファイルフルパス |

### 出力先

- GitLab UIでのデザイン一覧・詳細表示
- GraphQL APIレスポンス
- イベントストリーム（アクティビティ）

## 処理フロー

### 処理シーケンス

```
1. デザインアップロードリクエスト受信
   └─ ファイルと紐付けイシューの情報を受け取る
2. ファイルバリデーション
   └─ ファイル形式、サイズ、ファイル名をチェック
3. デザインリポジトリにコミット
   └─ designs/issue-{iid}/{filename}のパスでコミット
4. デザインレコード作成/更新
   └─ design_management_designsテーブルにレコード作成
5. バージョン作成
   └─ design_management_versionsテーブルにバージョン作成
6. アクション記録
   └─ design_management_actionsテーブルにcreated/modification/deletionを記録
7. イベント発行
   └─ アクティビティフィードにイベント追加
```

### フローチャート

```mermaid
flowchart TD
    A[デザインアップロード] --> B{ファイル検証}
    B -->|有効| C[リポジトリにコミット]
    B -->|無効| X[エラー返却]
    C --> D{既存デザイン?}
    D -->|Yes| E[modification記録]
    D -->|No| F[デザイン作成]
    E --> G[バージョン作成]
    F --> G
    G --> H[イベント発行]
    H --> I[成功レスポンス]

    J[デザイン削除] --> K{権限チェック}
    K -->|OK| L[削除コミット]
    K -->|NG| Y[Forbidden]
    L --> M[deletion記録]
    M --> N[バージョン作成]
    N --> O[イベント発行]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-133-01 | ファイル名一意制約 | 同一イシュー内でファイル名は一意 | デザインアップロード時 |
| BR-133-02 | 画像形式制限 | サポートされる画像形式のみ許可 | デザインアップロード時 |
| BR-133-03 | 説明文字数制限 | 説明は最大10000文字 | デザイン作成/更新時 |
| BR-133-04 | 削除済みデザインの表示 | 削除済みデザインは特定バージョン指定時のみ表示 | デザイン一覧取得時 |
| BR-133-05 | iidの自動採番 | プロジェクト内でiidを自動採番 | デザイン作成時 |

### 計算ロジック

- **ファイルパス計算**: `designs/issue-{issue_iid}/{filename}`
- **ステータス判定**: 最新アクションがdeletionでなければcurrent、アクションがなければnew

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| デザイン作成 | design_management_designs | INSERT | デザインレコード作成 |
| デザイン更新 | design_management_designs | UPDATE | 説明等の更新 |
| バージョン作成 | design_management_versions | INSERT | バージョンレコード作成 |
| アクション記録 | design_management_actions | INSERT | created/modification/deletion記録 |
| ノート追加 | notes | INSERT | デザインへのコメント |
| イベント追加 | events | INSERT | アクティビティイベント |

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

#### design_management_designs

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | project_id, issue_id, filename, iid | アップロード情報 | iidは自動採番 |
| UPDATE | description | マークダウン形式の説明 | キャッシュマークダウン対応 |
| SELECT | issue_id, filename | イシューIDとファイル名 | 一意チェック用 |

#### design_management_versions

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | sha, issue_id, author_id | コミットSHA、イシューID、作者 | - |

#### design_management_actions

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | design_id, version_id, event | デザインID、バージョンID、イベント種別 | event: creation/modification/deletion |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 400 | Bad Request | 非対応のファイル形式 | サポートされる画像形式でアップロード |
| 403 | Forbidden | 権限不足 | 適切な権限を付与 |
| 422 | Unprocessable Entity | バリデーションエラー | 入力値を修正 |

### リトライ仕様

デザインリポジトリへのコミット失敗時は自動リトライなし（ユーザーに再試行を促す）

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

- デザイン作成とバージョン作成は同一トランザクション
- Gitリポジトリへのコミットはトランザクション外で先行実行
- コミット成功後にDBレコード作成

## パフォーマンス要件

- デザイン一覧取得は50件以下で200ms以内
- 画像ファイルはGit LFSで効率的に配信

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

- SVG形式はXSS脆弱性のリスクがあるため、フィーチャーフラグで制御
- アップロードされた画像は適切なContent-Typeで配信
- デザインへのアクセスはイシューへのアクセス権限に連動

## 備考

- デザイン参照形式: `#123[filename.png]` または `#123/designs[filename.png]`
- デザイン専用リポジトリはプロジェクトリポジトリとは別に管理

---

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

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

### 推奨読解順序

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

デザインマネジメントの中核となるデータモデルを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | design_management.rb | `app/models/design_management.rb` | モジュール定義、定数 |
| 1-2 | design.rb | `app/models/design_management/design.rb` | デザインのデータモデル |
| 1-3 | version.rb | `app/models/design_management/version.rb` | バージョンモデル |
| 1-4 | action.rb | `app/models/design_management/action.rb` | アクション記録 |

**読解のコツ**: DesignモデルはNoteable、Mentionable、Todoableなど多くのconcernをincludeしている。`relative_position`による並び順管理、`has_internal_id`によるiid自動採番に注目。

#### Step 2: データ構造の詳細

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | design.rb | `app/models/design_management/design.rb` | 主要なスコープと検証 |

**主要処理フロー（design.rb）**:
- **5-19行目**: includeされるconcernの確認
- **23-24行目**: project, issueとの関連
- **26-28行目**: actions, versions, authorsとの関連
- **40-43行目**: バリデーション（filename一意性、長さ制限）
- **87-98行目**: `visible_at_version`スコープ（特定バージョンでの可視性）
- **125-137行目**: `status`メソッド（new/current/deleted判定）
- **164-169行目**: `to_reference`メソッド（参照形式生成）

#### Step 3: リポジトリとバージョン管理

デザイン専用リポジトリの仕組みを理解。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | repository.rb | `app/models/design_management/repository.rb` | デザインリポジトリ |
| 3-2 | git_repository.rb | `app/models/design_management/git_repository.rb` | Gitリポジトリ操作 |

#### Step 4: システムノートサービス

デザイン操作に関するシステムノート。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | design_management_service.rb | `app/services/system_notes/design_management_service.rb` | システムノート生成 |

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

```
GraphQL Mutation (デザインアップロード)
    │
    ├─ DesignManagement::SaveDesignsService
    │      ├─ ファイルバリデーション
    │      ├─ リポジトリコミット
    │      │      └─ DesignManagement::Repository
    │      │             └─ DesignManagement::GitRepository
    │      │
    │      ├─ Design作成/更新
    │      │      └─ DesignManagement::Design.create/update
    │      │
    │      ├─ Version作成
    │      │      └─ DesignManagement::Version.create
    │      │
    │      ├─ Action記録
    │      │      └─ DesignManagement::Action.create
    │      │
    │      └─ イベント発行
    │             └─ Event.create

DesignManagement::Design
    │
    ├─ visible_at_version (スコープ)
    │      └─ DesignManagement::Action.most_recent
    │
    ├─ status (メソッド)
    │      └─ most_recent_action (delegation)
    │
    └─ to_reference (メソッド)
           └─ issue.to_reference
```

### データフロー図

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

画像ファイル ────────────▶ ファイルバリデーション ───────▶ design_management_designs
      │                           │                              │
      ▼                           ▼                              ▼
イシューID              デザインリポジトリコミット         design_management_versions
      │                           │                              │
      ▼                           ▼                              ▼
                         バージョン/アクション記録         design_management_actions
                                  │                              │
                                  ▼                              ▼
                            イベント発行                    events (アクティビティ)
                                  │
                                  ▼
                           デザイン一覧/詳細表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| design_management.rb | `app/models/design_management.rb` | モデル | モジュール定義 |
| design.rb | `app/models/design_management/design.rb` | モデル | デザインモデル |
| version.rb | `app/models/design_management/version.rb` | モデル | バージョンモデル |
| action.rb | `app/models/design_management/action.rb` | モデル | アクションモデル |
| design_action.rb | `app/models/design_management/design_action.rb` | モデル | デザインアクション |
| repository.rb | `app/models/design_management/repository.rb` | モデル | リポジトリモデル |
| git_repository.rb | `app/models/design_management/git_repository.rb` | モデル | Gitリポジトリ |
| design_at_version.rb | `app/models/design_management/design_at_version.rb` | モデル | バージョン付きデザイン |
| design_collection.rb | `app/models/design_management/design_collection.rb` | モデル | デザインコレクション |
| design_management_service.rb | `app/services/system_notes/design_management_service.rb` | サービス | システムノート |
| design_management_type.rb | `app/graphql/types/design_management_type.rb` | GraphQL | 型定義 |
| design_management_widget.vue | `app/assets/javascripts/work_items/components/design_management/design_management_widget.vue` | Vue | ウィジェット |
