# 機能設計書 16-アカウント削除

## 概要

本ドキュメントは、Chatwootのアカウント削除機能について、その処理内容、データベース操作、およびコード構成を詳細に記述した設計書である。

### 本機能の処理概要

アカウント削除機能は、契約終了時やユーザー要求時にアカウントとその関連データを安全に削除する機能である。GDPRなどのプライバシー規制に準拠するため、ユーザーデータの適切な処理（ソフトデリートまたはハードデリート）を行う。

**業務上の目的・背景**：GDPRの「忘れられる権利」やその他のプライバシー規制に対応するため、ユーザーがアカウント削除を要求した場合に、関連するすべてのデータを適切に処理する必要がある。また、契約終了時には顧客データを確実に削除し、コンプライアンス要件を満たす必要がある。

**機能の利用シーン**：
- 契約終了によるアカウント削除
- ユーザーからの削除要求（GDPR対応）
- テストアカウントのクリーンアップ
- 組織統合によるアカウント廃止

**主要な処理内容**：
1. アカウント削除対象の特定と処理開始
2. 孤立ユーザーの特定とソフトデリート（他にアカウントを持たないユーザー）
3. コンプライアンス通知メールの送信
4. 非同期ジョブによるアカウントデータの削除
5. 削除完了後のログ記録

**関連システム・外部連携**：
- メール送信システム（コンプライアンス通知）
- バックグラウンドジョブシステム（Sidekiq）

**権限による制御**：
- アカウント削除はSuper Admin または特定の管理操作でのみ実行可能

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | Super Admin管理画面 | 主画面 | アカウント削除の実行 |

## 機能種別

データ削除 / コンプライアンス処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| account | Account | Yes | 削除対象アカウントオブジェクト | 存在確認 |

### 入力データソース

- 管理画面からの削除操作
- スケジュールされた削除ジョブ

## 出力仕様

### 出力データ

本機能は直接的な出力データを返さない（非同期処理）。

### 出力先

- ログファイル（削除処理の記録）
- メール通知（コンプライアンス通知）

## 処理フロー

### 処理シーケンス

```
1. AccountDeletionService初期化
   └─ 削除対象アカウントを受け取る

2. perform実行
   └─ 削除処理開始ログ出力

3. 孤立ユーザーのソフトデリート
   ├─ アカウント内の全ユーザーを走査
   ├─ 他にアカウントを持たないユーザーを特定
   └─ メールアドレスを xxx-deleted.com 形式に変更

4. コンプライアンス通知送信
   └─ 管理者向けに削除完了通知メール送信

5. 非同期削除ジョブ実行
   └─ DeleteObjectJob.perform_later(account)

6. 関連データの削除（DeleteObjectJob内）
   └─ dependent: :destroy_async で関連レコード削除
```

### フローチャート

```mermaid
flowchart TD
    A[アカウント削除開始] --> B[削除開始ログ出力]
    B --> C[ユーザー走査開始]
    C --> D{次のユーザー}
    D -->|あり| E{他のアカウント存在?}
    E -->|Yes| D
    E -->|No| F[メールをソフトデリート]
    F --> G[ソフトデリートログ出力]
    G --> D
    D -->|なし| H[コンプライアンス通知送信]
    H --> I[DeleteObjectJob投入]
    I --> J[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 孤立ユーザー判定 | 削除対象アカウント以外にアカウントを持たないユーザーを孤立ユーザーとする | 全ユーザー走査時 |
| BR-002 | ソフトデリート形式 | 孤立ユーザーのメールは `{original_email}-deleted.com` 形式に変更 | ソフトデリート時 |
| BR-003 | 再確認スキップ | ソフトデリート時はメール再確認をスキップする | ソフトデリート時 |
| BR-004 | コンプライアンス通知 | 削除完了時に管理者へ通知メールを送信 | 削除処理完了時 |
| BR-005 | 非同期削除 | アカウント本体の削除は非同期ジョブで実行 | アカウント削除時 |

### 計算ロジック

**孤立ユーザー判定**:
```ruby
other_accounts = user.account_users.where.not(account_id: account.id).count
is_orphaned = other_accounts.zero?
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| ユーザー走査 | account_users | SELECT | アカウント内ユーザー取得 |
| 孤立判定 | account_users | SELECT | 他アカウント所属確認 |
| ソフトデリート | users | UPDATE | メールアドレス変更 |
| アカウント削除 | accounts | DELETE | アカウントレコード削除 |
| 関連データ削除 | 多数 | DELETE | dependent: :destroy_async |

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

#### users（ソフトデリート）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | email | `{original_email}-deleted.com` | skip_reconfirmation! |

#### accounts

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| DELETE | - | id条件 | DeleteObjectJob経由 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ActiveRecord::RecordInvalid | ユーザー更新失敗 | 例外ログ記録、処理続行 |
| - | Sidekiq::DeadSet | ジョブ失敗 | リトライ後にデッドセット |

### リトライ仕様

DeleteObjectJobは Sidekiq のデフォルトリトライポリシーに従う（最大25回リトライ）。

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

- ソフトデリート処理は各ユーザーごとに独立して実行（1ユーザーの失敗が他に影響しない）
- アカウント本体の削除は DeleteObjectJob 内でトランザクション管理

## パフォーマンス要件

- 非同期処理のため、即時レスポンスは必要なし
- 大規模アカウント（多数のユーザー・会話）の削除は数時間かかる場合がある

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

- Super Admin権限必須
- コンプライアンス通知による削除の証跡
- ソフトデリートによる復旧可能性の排除（メール形式変更）
- ログによる削除操作の記録

## 備考

- DeleteObjectJobは汎用的な削除ジョブで、Account以外のオブジェクト削除にも使用される
- 削除処理は非同期で行われるため、即座にデータが消えるわけではない

---

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

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

### 推奨読解順序

#### Step 1: サービスクラスを理解する

AccountDeletionServiceの全体構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | account_deletion_service.rb | `app/services/account_deletion_service.rb` | 削除処理の全体フロー |

**読解のコツ**:
- `attr_reader :account, :soft_deleted_users` でインスタンス変数を確認
- `perform` メソッドがエントリーポイント
- 処理順序: ログ出力 → ソフトデリート → 通知送信 → ジョブ投入

**主要処理フロー**:
1. **1-50行目**: AccountDeletionServiceクラス全体
2. **4-7行目**: initialize - アカウントとソフトデリートユーザー配列の初期化
3. **9-15行目**: perform - メイン処理フロー
4. **19-23行目**: send_compliance_notification - コンプライアンス通知
5. **26-48行目**: soft_delete_orphaned_users - 孤立ユーザーのソフトデリート

#### Step 2: ソフトデリート処理の詳細を理解する

孤立ユーザーの判定とソフトデリート処理を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | account_deletion_service.rb | `app/services/account_deletion_service.rb` | soft_delete_orphaned_users メソッド |

**主要処理フロー**:
1. **27行目**: `account.users.each` - アカウント内ユーザー走査
2. **29行目**: 他アカウント所属数カウント
3. **32行目**: `next unless other_accounts.zero?` - 孤立ユーザー以外はスキップ
4. **35-36行目**: メールアドレス変更（xxx-deleted.com形式）
5. **37行目**: `skip_reconfirmation!` - 再確認メールをスキップ
6. **40-43行目**: ソフトデリート情報を配列に保存

#### Step 3: 削除ジョブを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | delete_object_job.rb | `app/jobs/delete_object_job.rb` | 非同期削除ジョブ |

**主要処理フロー**:
- オブジェクトの destroy 実行

#### Step 4: コンプライアンス通知を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | account_compliance_mailer.rb | `app/mailers/administrator_notifications/account_compliance_mailer.rb` | 通知メール |

**主要処理フロー**:
- `account_deleted` メソッドで削除通知メール送信

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

```
AccountDeletionService
    │
    ├─ perform
    │      │
    │      ├─ Rails.logger.info (削除開始ログ)
    │      │
    │      ├─ soft_delete_orphaned_users
    │      │      │
    │      │      ├─ account.users.each
    │      │      │      ├─ user.account_users.where.not().count
    │      │      │      └─ user.save! (メール変更)
    │      │      │
    │      │      └─ Rails.logger.info (ソフトデリートログ)
    │      │
    │      ├─ send_compliance_notification
    │      │      └─ AccountComplianceMailer.account_deleted.deliver_later
    │      │
    │      └─ DeleteObjectJob.perform_later(account)
    │             └─ account.destroy
```

### データフロー図

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

Account オブジェクト ────▶ AccountDeletionService ────▶ ログ出力
                                │
                                ├────▶ soft_delete_orphaned_users
                                │            │
                                │            └───▶ users テーブル (UPDATE)
                                │
                                ├────▶ send_compliance_notification
                                │            │
                                │            └───▶ メール送信
                                │
                                └────▶ DeleteObjectJob
                                             │
                                             └───▶ accounts テーブル (DELETE)
                                                    + 関連テーブル (CASCADE)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| account_deletion_service.rb | `app/services/account_deletion_service.rb` | サービス | アカウント削除メイン処理 |
| delete_object_job.rb | `app/jobs/delete_object_job.rb` | ジョブ | 非同期オブジェクト削除 |
| account_compliance_mailer.rb | `app/mailers/administrator_notifications/account_compliance_mailer.rb` | メーラー | コンプライアンス通知 |
| account.rb | `app/models/account.rb` | モデル | アカウントモデル（関連定義） |
| user.rb | `app/models/user.rb` | モデル | ユーザーモデル（ソフトデリート対象） |
