# 機能設計書 68-アバター設定

## 概要

本ドキュメントは、Fizzyアプリケーションにおけるプロフィール画像（アバター）を設定する機能の設計を詳述する。

### 本機能の処理概要

**業務上の目的・背景**：チームメンバーを視覚的に識別しやすくするため、ユーザーごとにプロフィール画像（アバター）を設定できる機能が必要である。アバターはカード、コメント、ユーザー一覧など、アプリケーション全体で表示される。

**機能の利用シーン**：プロフィール編集画面でアバター画像をアップロードする場面、アバター画像を表示する場面で利用される。アバターが設定されていない場合は、ユーザー名のイニシャルから自動生成されるSVG画像が表示される。

**主要な処理内容**：
1. アバター画像の表示（show）
   - システムユーザーの場合はデフォルト画像を表示
   - アバターが添付されている場合はサムネイルを表示
   - アバターがない場合はイニシャルSVGを生成して表示
2. アバター画像の設定（UsersController#updateで処理）
   - 画像のバリデーション（形式、サイズ）
   - Active Storageへの保存
   - サムネイルの生成

**関連システム・外部連携**：Active Storageによるファイル保存、画像処理ライブラリによるサムネイル生成。

**権限による制御**：アバターの表示は認証不要（公開）。設定・削除はcan_change?メソッドで権限を判定。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 39 | プロフィール編集画面 | 主画面 | プロフィール画像（アバター）を設定 |

## 機能種別

ファイルアップロード処理 / データ参照処理（READ）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| user_id | UUID | Yes | ユーザーID（URLパラメータ） | Current.account.users内に存在 |
| user[avatar] | File | No | アバター画像ファイル（UsersController経由） | content_type, dimensions |

### 入力データソース

- URLパラメータ（user_id）
- フォームからのファイルアップロード（user[avatar]）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| アバター画像 | Binary/SVG | 画像データまたはSVG |
| Content-Type | String | image/jpeg, image/png, image/svg+xml など |

### 出力先

- HTTPレスポンス（画像データ）
- リダイレクト（Active Storageのblob URL）

## 処理フロー

### 処理シーケンス

```
1. リクエスト受信（GET /users/:user_id/avatar）
   └─ Users::AvatarsController#show
2. ユーザー取得
   └─ set_user (before_action)
3. アバター判定
   └─ system? → デフォルト画像へリダイレクト
   └─ avatar.attached? → blob URLへリダイレクト
   └─ それ以外 → イニシャルSVGを生成
4. レスポンス
   └─ リダイレクトまたはSVGレンダリング
```

### フローチャート

```mermaid
flowchart TD
    A[GET /users/:user_id/avatar] --> B[set_user でユーザー取得]
    B --> C{@user.system?}
    C -->|Yes| D[system_user.pngへリダイレクト]
    C -->|No| E{@user.avatar.attached?}
    E -->|Yes| F[avatar_thumbnailのblob URLへリダイレクト]
    E -->|No| G{stale?チェック}
    G -->|キャッシュ有効| H[304 Not Modified]
    G -->|キャッシュ無効| I[イニシャルSVGを生成]
    I --> J[SVGをレンダリング]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-68-01 | 許可形式 | JPEG, PNG, GIF, WebP のみ許可 | 常に |
| BR-68-02 | 最大サイズ | 幅・高さともに4096px以下 | 常に |
| BR-68-03 | サムネイル生成 | 256x256にリサイズ | avatar.variable?の場合 |
| BR-68-04 | 公開アクセス | アバターは認証なしでアクセス可能 | 常に |
| BR-68-05 | キャッシュ制御 | 他ユーザーのアバターは30分キャッシュ、1週間stale-while-revalidate | 他ユーザーの場合 |

### 計算ロジック

イニシャル生成:
- ユーザー名の先頭文字を大文字で取得
- SVGテンプレートに埋め込み

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| アバター取得 | active_storage_attachments | SELECT | アバター添付を取得 |
| Blob取得 | active_storage_blobs | SELECT | 画像データを取得 |

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

（参照のみのため省略）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 404 | ActiveRecord::RecordNotFound | ユーザーが存在しない | Rails標準の404ページ |
| 422 | Unprocessable Entity | バリデーションエラー（形式、サイズ） | エラーメッセージを表示 |

### リトライ仕様

読み取り専用のため、リトライ仕様は不要。

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

読み取り専用のため、トランザクション制御は不要。

## パフォーマンス要件

- レスポンス時間：500ms以内
- サムネイルは即時処理（process: :immediately）
- HTTPキャッシュを活用

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

- アバター表示は認証不要（allow_unauthenticated_access only: :show）
- アバターは常に公開（publicly_accessible? = true）
- 画像形式のバリデーションで不正ファイルを拒否

## 備考

- アバターが設定されていない場合はイニシャルSVGが動的に生成される
- アップロードはUsersController#updateで処理される（機能No.66と共通）

---

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

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

### 推奨読解順序

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

User::Avatarモジュールの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | avatar.rb | `app/models/user/avatar.rb` | アバター関連の定義 |

**読解のコツ**: avatar.rbでhas_one_attached :avatarが定義されている（8-10行目）。バリデーション（14行目）とサムネイル生成（9行目: resize_to_fill: [256, 256]）の設定を確認。

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

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

**主要処理フロー**:
1. **2行目**: allow_unauthenticated_access only: :showで表示は認証不要
2. **4-5行目**: before_actionでset_userとensure_permission_to_administer_user
3. **7-14行目**: showアクションで条件分岐
   - **8-9行目**: system?の場合はデフォルト画像へリダイレクト
   - **10-11行目**: avatar.attached?の場合はblob URLへリダイレクト
   - **12-13行目**: それ以外はstale?チェック後にイニシャルSVGをレンダリング

#### Step 3: キャッシュ制御を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | avatars_controller.rb | `app/controllers/users/avatars_controller.rb` | cache_controlメソッド |

**主要処理フロー**:
- **31-37行目**: cache_controlメソッドで自分以外のユーザーには30分キャッシュを設定

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | show.svg.erb | `app/views/users/avatars/show.svg.erb` | イニシャルSVGテンプレート |

**読解のコツ**: SVGテンプレートでユーザー名のイニシャルを表示する円形のアバターを生成。

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

```
Users::AvatarsController#show
    │
    ├─ before_action :set_user
    │      └─ Current.account.users.find(params[:user_id])
    │
    └─ show
           │
           ├─ @user.system?
           │      └─ redirect_to image_path("system_user.png")
           │
           ├─ @user.avatar.attached?
           │      └─ redirect_to rails_blob_path(@user.avatar_thumbnail)
           │             └─ avatar.variant(:thumb)
           │
           └─ stale?(@user, cache_control: cache_control)
                  │
                  ├─ (キャッシュ有効) 304 Not Modified
                  │
                  └─ (キャッシュ無効) render_initials
                         └─ render formats: :svg
                                └─ show.svg.erb
```

### データフロー図

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

params[:user_id] ───▶ Current.account.users.find ───▶ @user
                              │
                              ▼
                    ┌─────────┴─────────┐
                    ▼                   ▼
            system?          avatar.attached?
                    │                   │
                    ▼                   ▼
          system_user.png    avatar_thumbnail (blob URL)
                              │
                              ▼
                    stale?チェック
                              │
                    ┌─────────┴─────────┐
                    ▼                   ▼
            304 Not Modified    イニシャルSVG生成
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| avatars_controller.rb | `app/controllers/users/avatars_controller.rb` | コントローラー | アバター表示のエントリーポイント |
| avatar.rb | `app/models/user/avatar.rb` | モデルconcern | アバター設定、バリデーション |
| show.svg.erb | `app/views/users/avatars/show.svg.erb` | ビュー | イニシャルSVGテンプレート |
| routes.rb | `config/routes.rb` | 設定 | ルーティング定義（15行目） |
| users_controller.rb | `app/controllers/users_controller.rb` | コントローラー | アバターアップロード（updateアクション） |
