# 画面設計書 320-ロール編集

## 概要

本ドキュメントは、Aureus ERPシステムにおける「ロール編集」画面の設計仕様を定義します。この画面はセキュリティモジュールに属する管理画面であり、既存ロール（役割）の編集と権限変更機能を提供します。

### 本画面の処理概要

**業務上の目的・背景**：ロール編集画面は、システム管理者が既存のロール（役割）の情報を更新し、割り当てられた権限を変更するために必要です。この画面により、ロール名の変更と、リソース別・機能別の詳細な権限設定の更新が可能です。

**画面へのアクセス方法**：ロール一覧画面から「編集」アクションを選択、またはURL直接アクセス（`/roles/{id}/edit`）でアクセス可能です。

**主要な操作・処理内容**：
1. ロール名の変更
2. ガード名の変更（オプション）
3. 全権限選択（select_all）
4. リソース別権限の変更
5. ロールの更新
6. ロールの削除（ヘッダーアクション）

**画面遷移**：
- 一覧画面 → 編集画面（編集アクション選択）
- 詳細画面 → 編集画面（編集アクション選択）
- 編集画面 → 一覧画面（更新成功後/削除成功後）

**権限による表示制御**：Filament Shieldによる権限制御が実装されており、ロール編集権限を持つユーザーのみがアクセス可能です。panel_userロールは削除できません。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| FN-SEC-ROLE-003 | ロール編集 | 主機能 | ロール情報と権限の更新 |
| FN-SEC-ROLE-001 | ロール一覧 | 遷移元機能 | 一覧画面からの遷移 |
| FN-SEC-ROLE-004 | ロール削除 | 補助機能 | ヘッダーからの削除操作 |

## 画面種別

編集（Edit）

## URL/ルーティング

- **URL**: `/roles/{record}/edit`
- **ルート名**: `filament.resources.roles.edit`

## 画面構成

```
+------------------------------------------------------------------+
|  ナビゲーションバー                                                 |
+------------------------------------------------------------------+
|  ロール編集                                          [削除]        |
+------------------------------------------------------------------+
|  +------------------------------------------------------------+  |
|  | 基本情報                                                    |  |
|  | ┌──────────────┐ ┌──────────────┐ ┌──────────────┐         |  |
|  | │ ロール名 *   │ │ ガード名     │ │ チーム       │         |  |
|  | │ [Admin____] │ │ [web______] │ │ [選択_____] │         |  |
|  | └──────────────┘ └──────────────┘ └──────────────┘         |  |
|  |                                                             |  |
|  | [x] すべて選択                                               |  |
|  +------------------------------------------------------------+  |
|                                                                   |
|  +------------------------------------------------------------+  |
|  | リソース権限                                                 |  |
|  | ┌─────────────────────────────────────────────────────────┐|  |
|  | │ Support                                          [折畳] │|  |
|  | │  ┌───────────────┐  ┌───────────────┐                   │|  |
|  | │  │ Company       │  │ Currency      │                   │|  |
|  | │  │ [x] view      │  │ [x] view      │                   │|  |
|  | │  │ [x] view_any  │  │ [x] view_any  │                   │|  |
|  | │  │ [x] create    │  │ [ ] create    │                   │|  |
|  | │  │ [x] update    │  │ [ ] update    │                   │|  |
|  | │  │ [ ] delete    │  │ [ ] delete    │                   │|  |
|  | │  │ [ ] delete_any│  │ [ ] delete_any│                   │|  |
|  | │  └───────────────┘  └───────────────┘                   │|  |
|  | └─────────────────────────────────────────────────────────┘|  |
|  +------------------------------------------------------------+  |
+------------------------------------------------------------------+
|                                [キャンセル] [保存]                 |
+------------------------------------------------------------------+
```

## 入出力項目

| No | 項目名 | 項目ID | 入出力種別 | データ型 | 必須 | バリデーション |
|----|--------|--------|-----------|---------|------|---------------|
| 1 | ロール名 | name | 入力 | string | Yes | 最大255文字、一意制約（自レコード除外） |
| 2 | ガード名 | guard_name | 入力 | string | No | 最大255文字 |
| 3 | チーム | team_id | 入力 | integer | No | テナンシー有効時のみ表示 |
| 4 | すべて選択 | select_all | 入力 | boolean | No | - |
| 5 | リソース権限 | [動的] | 入力 | array | No | リソース別にチェックボックスリスト |

## ヘッダーアクション

| No | アクション名 | 表示条件 | 説明 |
|----|------------|---------|------|
| 1 | 削除 | ロール名がpanel_user以外 | ロールの削除 |

## イベント仕様

### 1-保存ボタン押下

- **トリガー**: フォームの保存ボタンをクリック
- **処理内容**:
  1. 入力値のバリデーション実行
  2. mutateFormDataBeforeSaveで権限データを抽出
  3. ロールレコードを更新（name, guard_name）
  4. afterSaveで権限同期処理を実行
     - DBトランザクション内で処理
     - 既存の権限割当を全削除
     - 権限名を500件ずつチャンク処理
     - 存在しない権限は自動作成
     - role_has_permissionsテーブルに1000件ずつ挿入
  5. 権限キャッシュをクリア
  6. ロール一覧画面へリダイレクト
- **遷移先**: `/roles`

### 2-削除アクション

- **トリガー**: ヘッダーの削除ボタンをクリック
- **処理内容**:
  1. 確認ダイアログを表示
  2. 確認後、ロールを削除
  3. 関連する権限割当も削除
- **条件**: panel_userロールの場合は削除ボタン非表示
- **遷移先**: `/roles`（一覧画面）

### 3-すべて選択チェック

- **トリガー**: すべて選択チェックボックスをクリック
- **処理内容**: 全リソースの全権限をチェック/アンチェック

### 4-キャンセルボタン押下

- **トリガー**: キャンセルボタンをクリック
- **処理内容**: ロール一覧画面へ戻る
- **遷移先**: `/roles`

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 保存ボタン押下 | roles | UPDATE | ロールレコード更新 |
| 保存ボタン押下 | role_has_permissions | DELETE | 既存権限割当全削除 |
| 保存ボタン押下 | permissions | INSERT | 不足権限の自動作成 |
| 保存ボタン押下 | role_has_permissions | INSERT | 新しい権限割当 |
| 削除アクション | roles | DELETE | ロール削除 |
| 削除アクション | role_has_permissions | DELETE | 権限割当削除 |
| 削除アクション | model_has_roles | DELETE | ユーザー割当削除 |

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

#### roles

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | name | フォーム入力値 | ロール名 |
| UPDATE | guard_name | Utils::getFilamentAuthGuard() | 認証ガード名 |
| UPDATE | updated_at | 現在時刻 | 更新日時 |

#### role_has_permissions

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| DELETE | role_id | 対象ロールID | 既存割当全削除 |
| INSERT | role_id | 対象ロールID | ロールID |
| INSERT | permission_id | 権限ID | 権限ID |

## メッセージ仕様

| No | メッセージ種別 | メッセージ内容 | 表示条件 |
|----|---------------|---------------|---------:|
| 1 | 成功 | ロールが正常に更新されました | 更新成功時 |
| 2 | 成功 | ロールが正常に削除されました | 削除成功時 |
| 3 | エラー | このロール名は既に使用されています | ロール名重複時 |

## 例外処理

| No | 例外条件 | 処理内容 | 表示メッセージ |
|----|---------|---------|---------------|
| 1 | 権限不足 | 画面へのアクセスを拒否 | アクセス権限がありません |
| 2 | ロール名重複 | バリデーションエラー表示 | このロール名は既に使用されています |
| 3 | panel_user削除試行 | 削除アクションを非表示 | - |
| 4 | データベースエラー | トランザクションロールバック、エラー通知表示 | 更新に失敗しました |

## 権限同期の技術的詳細

### 処理フロー

```
フォームデータ取得 → 権限名を抽出
  ↓
ロールレコード更新（name, guard_name）
  ↓
afterSaveでトランザクション開始
  ↓
既存のrole_has_permissions全削除
  ↓
権限名を500件ずつチャンク処理
  ↓
既存権限確認 → 不足権限を特定
  ↓
不足権限があれば → permissionsテーブルにINSERT
  ↓
全権限IDを収集
  ↓
role_has_permissionsに1000件ずつINSERT
  ↓
キャッシュクリア → forgetCachedPermissions()
  ↓
レコードrefresh
```

### 権限同期の特徴

- 既存権限を一度全削除してから新しい権限を割り当てる（完全同期）
- チャンク処理で大量の権限を効率的に処理
- insertOrIgnoreで既存権限との競合を回避
- トランザクション内で処理し、エラー時は自動ロールバック

## 備考

- EditRecordを継承した編集画面です
- Filament Shieldパッケージの機能を拡張しています
- panel_userロール（設定ファイルで定義）は削除できないよう保護されています
- 権限はプラグイン（モジュール）別にグループ化されて表示されます
- 各リソースのFieldsetは折り畳み可能（collapsible）です
- 編集画面では既存の権限がチェック済みの状態で表示されます
- setPermissionStateForRecordPermissionsメソッドで既存権限の状態を復元します
- 権限同期はチャンク処理で大量の権限を効率的に処理します
- ガード名は常にUtils::getFilamentAuthGuard()で上書きされます
