# 画面設計書 39-プロフィール編集画面

## 概要

本ドキュメントは、Fizzyアプリケーションにおけるプロフィール編集画面の設計仕様を記述したものです。

### 本画面の処理概要

プロフィール編集画面は、ユーザーが自分の名前とアバター画像を編集する画面です。また、メールアドレスの変更への導線も提供します。

**業務上の目的・背景**：ユーザーは自分のプロフィール情報を適切に管理する必要があります。名前の変更やプロフィール画像の設定は、チーム内での識別や親しみやすさの向上に寄与します。本画面は、これらの基本的なプロフィール情報を簡単に更新できるようにします。

**画面へのアクセス方法**：ユーザープロフィール画面の編集アイコン（鉛筆）をクリックすることでアクセスできます。

**主要な操作・処理内容**：
1. ユーザー名の編集
2. アバター画像のアップロード
3. アバター画像の削除
4. メールアドレス変更画面へ遷移

**画面遷移**：
- 遷移元：ユーザープロフィール画面
- 遷移先：ユーザープロフィール画面（保存後）、メールアドレス追加画面

**権限による表示制御**：自分自身のプロフィールのみ編集可能です。他のユーザーの編集画面にアクセスしようとした場合は403 Forbiddenが返されます。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 66 | ユーザー名編集 | 主機能 | ユーザー名を編集 |
| 68 | アバター設定 | 補助機能 | プロフィール画像（アバター）を設定 |
| 69 | アバター削除 | 補助機能 | アバターを削除 |

## 画面種別

編集

## URL/ルーティング

- **パス**: `/users/:id/edit`
- **HTTPメソッド**: GET（表示）
- **コントローラ**: `UsersController#edit`

## 入出力項目

| 項目名 | 項目ID | 入出力 | データ型 | 必須 | 最大長 | 説明 |
|--------|--------|--------|----------|------|--------|------|
| ユーザーID | id | パラメータ | UUID | 必須 | - | 編集対象ユーザーのID |
| ユーザー名 | name | 入力 | String | 必須 | - | 表示名 |
| アバター画像 | avatar | 入力 | File | 任意 | - | プロフィール画像（jpg/png/gif/webp） |

## 表示項目

| 項目名 | 説明 | データ取得元 |
|--------|------|-------------|
| ページタイトル | 「Edit your profile」 | - |
| 戻るリンク | プロフィール画面への戻りリンク | - |
| アバタープレビュー | 現在のアバター画像またはプレビュー | @user.avatar |
| アバター削除ボタン | アバター削除用ボタン | アバターが設定されている場合のみ |
| 名前入力欄 | ユーザー名の入力フィールド | @user.name |
| メールアドレス表示 | 現在のメールアドレス（読み取り専用） | @user.identity.email_address |
| メール変更リンク | メールアドレス変更画面へのリンク | - |
| 保存ボタン | 変更を保存するボタン | - |
| キャンセルリンク | 編集をキャンセルするリンク | - |
| エラーメッセージ | バリデーションエラー表示 | @user.errors |

## イベント仕様

### 1-プロフィール保存

プロフィール情報を保存します。

- **トリガー**: 「Save changes」ボタンをクリック
- **処理フロー**:
  1. フォームデータをPATCH `/users/:id` に送信
  2. `UsersController#update` でバリデーション・保存
  3. 成功時：プロフィール画面へリダイレクト
  4. 失敗時：エラーメッセージを表示
- **データ更新**: users.name, avatarアタッチメント

### 2-アバターアップロード

アバター画像をアップロードします。

- **トリガー**: アバター画像エリアをクリック、ファイルを選択
- **処理フロー**:
  1. Stimulusコントローラ（upload-preview）でプレビュー表示
  2. フォーム送信時にActive Storageでアップロード
- **許可形式**: image/jpeg, image/png, image/gif, image/webp

### 3-アバター削除

アバター画像を削除します。

- **トリガー**: 削除ボタン（マイナスアイコン）をクリック
- **処理フロー**:
  1. 確認ダイアログ「Are you sure you want to remove your avatar? This can't be undone.」を表示
  2. 確認後、DELETE `/users/:id/avatar` に送信
  3. アバターアタッチメントを削除
- **表示条件**: アバターが設定されている場合のみ

### 4-キャンセル

編集をキャンセルします。

- **トリガー**: Escキー、またはキャンセルリンク（非表示）
- **処理フロー**: プロフィール画面へ戻る

### 5-メールアドレス変更へ遷移

メールアドレス変更画面へ遷移します。

- **トリガー**: 「Change email」リンクをクリック
- **遷移先**: `/users/:user_id/email_addresses/new`

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 保存 | users | UPDATE | ユーザー名を更新 |
| アバターアップロード | active_storage_blobs | INSERT | 画像データを保存 |
| アバターアップロード | active_storage_attachments | INSERT | ユーザーとの関連を保存 |
| アバター削除 | active_storage_attachments | DELETE | 関連を削除 |
| アバター削除 | active_storage_blobs | DELETE | 画像データを削除 |

### テーブル別更新項目詳細

#### users

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | name | フォーム入力値 | 必須 |
| UPDATE | updated_at | 現在時刻 | 自動更新 |

## メッセージ仕様

| 種別 | メッセージID | メッセージ内容 | 表示条件 |
|------|------------|---------------|---------|
| 確認 | confirm_avatar_delete | Are you sure you want to remove your avatar? This can't be undone. | アバター削除時 |
| エラー | validation_error | Your changes couldn't be saved: | バリデーションエラー |

## 例外処理

| 例外 | 発生条件 | 処理内容 |
|-----|---------|---------|
| RecordNotFound | ユーザーが存在しない | 404エラーページを表示 |
| Forbidden | 他のユーザーを編集しようとした | 403ステータスを返却 |
| ValidationError | 名前が空 | フォームにエラーを表示 |

## 備考

- Stimulusコントローラ（form, upload-preview）でインタラクティブ操作を制御
- メールアドレスは読み取り専用で表示
- アバターの許可形式はUser::Avatar::ALLOWED_AVATAR_CONTENT_TYPESで定義
- Escキーでキャンセル可能
- 1Password連携を無効化（data-1p-ignore）

---

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

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

### 推奨読解順序

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

ユーザーモデルとアバター機能を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | avatar.rb | `app/models/user/avatar.rb` | User::Avatarモジュール、許可されるコンテンツタイプ |
| 1-2 | user.rb | `app/models/user.rb` | Userモデル、バリデーション |

**読解のコツ**: `User::Avatar`モジュールで`has_one_attached :avatar`を定義。`ALLOWED_AVATAR_CONTENT_TYPES`で許可形式を指定。

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

コントローラのedit/updateアクションを確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | users_controller.rb | `app/controllers/users_controller.rb` | edit/updateアクション、権限チェック |

**主要処理フロー**:
1. **2行目**: `before_action :set_user` でユーザーを取得
2. **3行目**: `before_action :ensure_permission_to_change_user` で権限チェック
3. **12-13行目**: editアクションは空（ビューのみ）
4. **15-26行目**: updateアクションで保存、成功/失敗で分岐

#### Step 3: ビューレイヤーを理解する

編集画面のテンプレート構造を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | edit.html.erb | `app/views/users/edit.html.erb` | 編集フォームの構造 |

**主要処理フロー**:
- **11行目**: form_withでフォームを定義、Stimulusコントローラを設定
- **15-19行目**: アバター画像のアップロード入力
- **22-26行目**: アバター削除ボタン（条件付き表示）
- **32行目**: 名前入力欄
- **37-38行目**: メールアドレス表示（readonly）とChange emailリンク
- **60行目**: アバター削除用の別フォーム

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

```
UsersController#edit
    │
    ├─ set_user
    │      │
    │      └─ Current.account.users.active.find(params[:id])
    │
    ├─ ensure_permission_to_change_user
    │      │
    │      └─ Current.user.can_change?(@user)
    │             │
    │             └─ false: head :forbidden
    │
    └─ render edit.html.erb
           │
           ├─ form_with (メインフォーム)
           │      │
           │      ├─ file_field :avatar
           │      ├─ text_field :name
           │      └─ email_field (readonly)
           │
           └─ form_with (アバター削除フォーム)

UsersController#update
    │
    ├─ set_user, ensure_permission_to_change_user
    │
    ├─ @user.update(user_params)
    │      │
    │      ├─ 成功: redirect_to @user
    │      │
    │      └─ 失敗: render :edit, status: :unprocessable_entity
    │
    └─ user_params: [:name, :avatar]
```

### データフロー図

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

URLパラメータ            UsersController#edit
  user_id ──────────────▶ @user 取得
                              │
                        権限チェック
                              │
                        ┌─────┴─────┐
                       許可        拒否
                        │           │
                        ▼           ▼
                   edit.html.erb  403 Forbidden
                        │
                        ▼
フォーム入力             UsersController#update
  name, avatar ────────▶ @user.update
                              │
                        ┌─────┴─────┐
                       成功        失敗
                        │           │
                        ▼           ▼
                   redirect     edit.html.erb
                   (profile)    (errors)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| users_controller.rb | `app/controllers/users_controller.rb` | コントローラ | ユーザー編集処理 |
| edit.html.erb | `app/views/users/edit.html.erb` | テンプレート | 編集画面 |
| avatar.rb | `app/models/user/avatar.rb` | コンサーン | アバター機能 |
| user.rb | `app/models/user.rb` | モデル | ユーザーモデル |
| routes.rb | `config/routes.rb` | 設定 | ルーティング定義（13-27行目） |
