# 機能設計書 10-ボード削除

## 概要

本ドキュメントは、Fizzyアプリケーションにおけるボードとその関連データを削除する機能の設計書である。ボード管理者がボードを削除すると、関連するカード、カラム、アクセス権などすべての関連データが削除される。

### 本機能の処理概要

**業務上の目的・背景**：不要になったプロジェクトやチームのボードを整理し、システムリソースを解放するために、ボード削除機能が必要である。削除は不可逆な操作であるため、慎重に実行する必要がある。

**機能の利用シーン**：プロジェクト終了後やチーム解散後に、ボード管理者がボード設定画面からボードを削除する。削除前に確認を行い、削除後はルート画面にリダイレクトされる。

**主要な処理内容**：
1. ボード管理者権限の確認
2. ボードの削除（destroy）
3. 関連データの連鎖削除（dependent: :destroy / :delete_all）
4. ルート画面へのリダイレクト

**関連システム・外部連携**：なし

**権限による制御**：ボード管理者（can_administer_board?）のみがボード削除可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 12 | ボード設定画面 | 主画面 | ボードとその関連データを削除 |

## 機能種別

CRUD操作 / データ削除

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| id | String | Yes | ボードID | UUID形式 |

### 入力データソース

- URLパラメータ（ボードID）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| - | - | なし（データ削除） |

### 出力先

- データベース（各テーブルからレコード削除）
- リダイレクト（ルート画面）

## 処理フロー

### 処理シーケンス

```
1. ボード取得（set_board）
   └─ Current.user.boards.find(params[:id])
2. 権限チェック（ensure_permission_to_admin_board）
   └─ can_administer_board?がfalseならhead :forbidden
3. ボード削除（destroy）
   └─ @board.destroy
   └─ 関連データの連鎖削除
4. リダイレクト
   └─ HTML: root_path
   └─ JSON: head :no_content
```

### フローチャート

```mermaid
flowchart TD
    A[ボード削除リクエスト] --> B[set_board]
    B --> C{アクセス権あり?}
    C -->|No| D[404 Not Found]
    C -->|Yes| E{管理者権限?}
    E -->|No| F[403 Forbidden]
    E -->|Yes| G[@board.destroy]
    G --> H[関連データ連鎖削除]
    H --> I{レスポンス形式}
    I -->|HTML| J[ルート画面へリダイレクト]
    I -->|JSON| K[204 No Content]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 管理者権限必須 | can_administer_board?がtrueのユーザーのみ削除可能 | 削除実行時 |
| BR-002 | 連鎖削除 | ボード削除時に関連データも削除 | 削除実行時 |
| BR-003 | 不可逆操作 | 削除後は復元不可 | 削除完了後 |

### 計算ロジック

特になし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| ボード削除 | boards | DELETE | ボードレコード削除 |
| アクセス権削除 | accesses | DELETE | dependent: :delete_allで一括削除 |
| カード削除 | cards | DELETE | dependent: :destroyで連鎖削除 |
| カラム削除 | columns | DELETE | 連鎖削除 |
| Webhook削除 | webhooks | DELETE | dependent: :destroyで連鎖削除 |
| イベント削除 | events | DELETE | 連鎖削除 |

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

#### boards

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| DELETE | id | params[:id] | destroyメソッドで削除 |

#### accesses

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| DELETE | board_id | 削除対象ボードのID | delete_allで一括削除 |

#### cards（関連含む）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| DELETE | board_id | 削除対象ボードのID | コメント、ステップ等も連鎖削除 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 403 | Forbidden | 管理者権限なし | 403レスポンス |
| 404 | Not Found | ボードが存在しないまたはアクセス権なし | 404画面表示 |

### リトライ仕様

該当なし（削除は不可逆）

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

- destroyはActiveRecordのコールバック含めトランザクション内で実行
- 連鎖削除も同一トランザクション内

## パフォーマンス要件

- accesses: delete_allで効率的に一括削除
- 大量のカードがある場合は削除に時間がかかる可能性

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

- 管理者権限チェック: ensure_permission_to_admin_boardで厳格にチェック
- 削除確認: フロントエンドで確認ダイアログ表示（推奨）

## 備考

- dependent: :delete_allは高速だがコールバックが呼ばれない
- dependent: :destroyはコールバック付きで連鎖削除
- 削除は物理削除（論理削除ではない）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | board.rb | `app/models/board.rb` | dependent設定、関連モデル |
| 1-2 | accessible.rb | `app/models/board/accessible.rb` | has_many :accessesのdependent設定 |

**読解のコツ**: dependent: :delete_allと:destroyの違いを理解する。delete_allはSQLのDELETE文で直接削除、destroyはRubyオブジェクト経由で削除。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | boards_controller.rb | `app/controllers/boards_controller.rb` | destroyアクションの実装 |

**主要処理フロー**:
1. **4行目**: before_action :set_board
2. **5行目**: ensure_permission_to_admin_board
3. **59-66行目**: destroyアクションの実装
4. **60行目**: @board.destroy

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

```
BoardsController#destroy
    │
    ├─ set_board
    │      └─ Current.user.boards.find(params[:id])
    │
    ├─ ensure_permission_to_admin_board
    │      └─ Current.user.can_administer_board?(@board)
    │
    └─ @board.destroy
           │
           ├─ accesses.delete_all (dependent: :delete_all)
           │
           ├─ cards.destroy_all (dependent: :destroy)
           │      ├─ comments.destroy
           │      ├─ steps.destroy
           │      └─ ...
           │
           ├─ webhooks.destroy_all (dependent: :destroy)
           │
           └─ events.destroy_all
```

### データフロー図

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

id (ボードID) ─────────▶ BoardsController#destroy
                              │
                              ├──▶ 権限チェック ──────────▶ [NG] 403/404
                              │
                              └──▶ @board.destroy
                                     │
                                     ├──▶ accesses削除（DB）
                                     ├──▶ cards削除（DB）
                                     ├──▶ webhooks削除（DB）
                                     └──▶ リダイレクト
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| boards_controller.rb | `app/controllers/boards_controller.rb` | コントローラー | ボード削除処理 |
| board.rb | `app/models/board.rb` | モデル | ボードモデル、dependent設定 |
| accessible.rb | `app/models/board/accessible.rb` | コンサーン | アクセス権管理 |
| routes.rb | `config/routes.rb` | 設定 | ルーティング定義 |
