# 機能設計書 66-ユーザー名編集

## 概要

本ドキュメントは、Fizzyアプリケーションにおけるユーザー名を編集する機能の設計を詳述する。

### 本機能の処理概要

**業務上の目的・背景**：ユーザーが自分の表示名を変更できるようにすることで、チーム内での識別や、組織変更に伴う名前変更などに対応できる。この機能により、ユーザーは自分のアイデンティティを柔軟に管理できる。

**機能の利用シーン**：プロフィール編集画面から自分のユーザー名を変更する場面、新規ユーザーが初回ログイン時に名前を設定する場面（ユーザー検証画面）で利用される。

**主要な処理内容**：
1. 編集画面（edit）でユーザー情報の入力フォームを表示
2. フォームからユーザー名（とオプションでアバター）を受け取る
3. バリデーションを実行（名前は必須）
4. データベースを更新
5. 成功時はプロフィール画面にリダイレクト、失敗時は編集画面を再表示

**関連システム・外部連携**：プロフィール表示（機能No.65）と連携。アバター設定（機能No.68）と同時に実行可能。

**権限による制御**：自分自身または管理者（admin）のみが編集可能。can_change?メソッドで権限を判定。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 39 | プロフィール編集画面 | 主画面 | ユーザー名を編集 |
| 46 | ユーザー検証画面 | 参照画面 | ユーザー検証を行い名前を設定 |

## 機能種別

データ更新処理（UPDATE）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| id | UUID | Yes | ユーザーID（URLパラメータ） | Current.account.users.active内に存在 |
| user[name] | String | Yes | ユーザー名 | presence: true |
| user[avatar] | File | No | アバター画像ファイル | content_type, dimensions（Avatar concern） |

### 入力データソース

- フォーム入力（user[name], user[avatar]）
- URLパラメータ（id）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| @user | User | 更新後のユーザーオブジェクト |
| リダイレクト先 | URL | 成功時: /users/:id、失敗時: /users/:id/edit |
| エラーメッセージ | Array | バリデーションエラーの一覧 |

### 出力先

- 成功時: プロフィール画面へリダイレクト（HTML）またはhead :no_content（JSON）
- 失敗時: 編集画面を再表示（HTML）またはエラーJSONを返却

## 処理フロー

### 処理シーケンス

```
1. リクエスト受信（PATCH /users/:id）
   └─ UsersController#update
2. ユーザー取得
   └─ set_user (before_action)
3. 権限チェック
   └─ ensure_permission_to_change_user (before_action)
   └─ Current.user.can_change?(@user)
4. バリデーション
   └─ @user.update(user_params)
5. 結果に応じた処理
   └─ 成功: redirect_to @user
   └─ 失敗: render :edit, status: :unprocessable_entity
```

### フローチャート

```mermaid
flowchart TD
    A[PATCH /users/:id] --> B[set_user でユーザー取得]
    B --> C{ユーザーが存在?}
    C -->|No| D[404 Not Found]
    C -->|Yes| E[ensure_permission_to_change_user]
    E --> F{can_change?}
    F -->|No| G[403 Forbidden]
    F -->|Yes| H[@user.update]
    H --> I{バリデーション成功?}
    I -->|Yes| J[redirect_to @user]
    I -->|No| K[render :edit]
    J --> L[プロフィール画面表示]
    K --> M[編集画面再表示]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-66-01 | 名前必須 | ユーザー名は必須入力 | 常に |
| BR-66-02 | 自己編集可能 | 自分自身は常に編集可能 | other == self |
| BR-66-03 | 管理者編集可能 | 管理者は非オーナーユーザーを編集可能 | admin? && !other.owner? |
| BR-66-04 | オーナー保護 | オーナーは他者から編集されない | other.owner? |

### 計算ロジック

can_change?(other)の判定ロジック:
- (admin? && !other.owner?) || other == self

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| ユーザー更新 | users | UPDATE | nameカラムの更新 |
| アバター添付 | active_storage_attachments | INSERT | アバターが添付された場合 |
| アバターBlob | active_storage_blobs | INSERT | アバターが添付された場合 |

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

#### users

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 404 | ActiveRecord::RecordNotFound | ユーザーが存在しない | Rails標準の404ページ |
| 403 | Forbidden | can_change?がfalse | head :forbidden |
| 422 | Unprocessable Entity | バリデーションエラー | 編集画面を再表示 |

### リトライ仕様

リトライ不要。エラー時は画面からの再送信を促す。

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

- @user.updateは暗黙のトランザクションで実行
- アバターの添付も同一トランザクション内で処理

## パフォーマンス要件

- レスポンス時間：1秒以内
- アバターのアップロードはバックグラウンドで処理される場合がある

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

- 認証必須
- can_change?による権限チェック
- Strong Parametersでuser_paramsをフィルタリング
- params.expect(user: [ :name, :avatar ])で許可パラメータを制限

## 備考

- アバターもこの画面から同時に更新可能
- メールアドレスの変更は別機能（機能No.71）で実装

---

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

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

### 推奨読解順序

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

Userモデルのバリデーションを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | user.rb | `app/models/user.rb` | バリデーション定義 |

**読解のコツ**: user.rbの9行目で`validates :name, presence: true`が定義されている。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 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でupdate, destroyアクションに権限チェック
3. **12-13行目**: editアクション（空、@userをそのまま使用）
4. **15-27行目**: updateアクションでユーザー情報を更新
5. **43-45行目**: ensure_permission_to_change_userでcan_change?チェック
6. **47-49行目**: user_paramsでStrong Parameters定義

#### Step 3: 権限判定ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | role.rb | `app/models/user/role.rb` | can_change?の定義 |

**主要処理フロー**:
- **17-19行目**: can_change?(other) - admin?かつ!other.owner? または other == self

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | edit.html.erb | `app/views/users/edit.html.erb` | プロフィール編集フォーム |

**読解のコツ**: edit.html.erbは名前入力フィールドとアバターアップロードフィールドを含むフォーム。form_withでPATCHリクエストを送信。

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

```
UsersController#update
    │
    ├─ before_action :set_user
    │      └─ Current.account.users.active.find(params[:id])
    │
    ├─ before_action :ensure_permission_to_change_user
    │      └─ Current.user.can_change?(@user)
    │             └─ (admin? && !@user.owner?) || @user == Current.user
    │
    └─ @user.update(user_params)
           │
           ├─ params.expect(user: [:name, :avatar])
           │
           ├─ validates :name, presence: true
           │
           └─ (avatarがある場合)
                  └─ Avatar concern によるバリデーション
```

### データフロー図

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

params[:id]     ───▶ Current.account.users.active.find ───▶ @user
                              │
user_params     ───▶ @user.update(name:, avatar:)
                              │
                              ▼
                    ┌─────────┴─────────┐
                    ▼                   ▼
              成功               失敗
                    │                   │
                    ▼                   ▼
          redirect_to @user    render :edit
                    │                   │
                    ▼                   ▼
          プロフィール画面      編集画面（エラー表示）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| users_controller.rb | `app/controllers/users_controller.rb` | コントローラー | ユーザー編集のエントリーポイント |
| user.rb | `app/models/user.rb` | モデル | ユーザーエンティティ、バリデーション |
| role.rb | `app/models/user/role.rb` | モデルconcern | can_change?の定義 |
| edit.html.erb | `app/views/users/edit.html.erb` | ビュー | プロフィール編集フォーム |
| routes.rb | `config/routes.rb` | 設定 | ルーティング定義（13行目） |
