# 通知設計書 10-メンバー削除成功

## 概要

本ドキュメントは、Liamアプリケーションにおけるメンバー削除成功時のUI通知（トースト）の設計仕様を定義する。組織管理者がメンバー管理画面で組織メンバーを削除し、正常に削除された場合に表示される成功通知について、表示仕様、トリガー条件、処理フローを詳細に記載する。

### 本通知の処理概要

メンバー削除成功通知は、組織メンバー管理画面でメンバーを削除し、削除処理が正常に完了した際に表示されるトースト通知である。

**業務上の目的・背景**：組織からのメンバー削除は、セキュリティとアクセス管理の観点から重要な操作である。退職者やプロジェクト離脱者のアクセス権を速やかに削除する必要があり、削除が確実に完了したことをユーザーに明確にフィードバックすることで、アクセス管理の確実性を担保する。また、自分自身が組織から離脱する場合（自己削除）も同様にフィードバックを提供する。

**通知の送信タイミング**：組織メンバー管理画面（`/organizations/{organizationId}/settings/members`）でメンバーの削除ボタンを押下し、確認ダイアログで削除を確定した後、サーバーアクション`removeMember`が正常に完了した時点で表示される。

**通知の受信者**：メンバー削除操作を実行した組織管理者本人。現在表示しているメンバー管理画面上でトースト通知が表示される。

**通知内容の概要**：「Member removed」というタイトルと、削除されたメンバーに関する説明文が、成功（success）ステータスのトースト通知として表示される。自分自身を削除した場合は「You have left the organization.」、他のメンバーを削除した場合は「{memberName} has been removed from the organization.」という説明文が表示される。

**期待されるアクション**：ユーザーはメンバーの削除が完了したことを確認し、メンバー管理画面での作業を続けるか、他のページへ遷移する。

## 通知種別

UI通知（トースト）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（サーバーアクション完了後に即座に表示） |
| 優先度 | 中 |
| リトライ | なし（UI表示のため不要） |

### 送信先決定ロジック

メンバー削除操作を実行したユーザーの現在のページ上でトースト通知を表示する。

## 通知テンプレート

### UI通知の場合

| 項目 | 内容 |
|-----|------|
| タイトル | Member removed |
| 説明文 | 自己削除時: You have left the organization. / 他メンバー削除時: {memberName} has been removed from the organization. |
| ステータス | success |
| 表示位置 | header（ヘッダー下部） |

### 本文テンプレート

```
タイトル: Member removed
説明（自己削除）: You have left the organization.
説明（他メンバー削除）: ${memberName} has been removed from the organization.
```

### 添付ファイル

| ファイル名 | 形式 | 条件 | 説明 |
|----------|------|------|------|
| なし | - | - | UI通知のため添付ファイルなし |

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| memberName | 削除されたメンバーの名前 | コンポーネントのprops | Yes |
| isSelf | 自己削除かどうか | コンポーネントのprops | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 画面操作 | メンバー削除確定ボタン押下 | removeMemberが成功 | result.successがtrueになった時点 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| 削除失敗時 | result.successがfalseの場合は表示しない（エラートースト表示） |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[ユーザーがDeleteボタン押下] --> B[DeleteMemberModal表示]
    B --> C[削除確定ボタン押下]
    C --> D[handleDelete関数実行]
    D --> E[removeMember Server Action呼び出し]
    E --> F{削除結果}
    F -->|成功| G[成功トースト表示]
    F -->|失敗| H[エラートースト表示]
    G --> I{isSelf確認}
    I -->|true| J[You have left... メッセージ]
    I -->|false| K[{memberName} has been removed... メッセージ]
    J --> L[モーダルクローズ]
    K --> L
    L --> M[onSuccess コールバック実行]
    M --> N[終了]
    H --> N
```

## データベース参照・更新仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| なし | - | 直接参照なし |

### テーブル別参照項目詳細

該当なし（メンバー情報はコンポーネントのpropsから取得）。

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| organization_members | DELETE | 組織メンバーレコードの削除 |

#### organization_members

| 操作 | 項目（カラム名） | 更新値 | 備考 |
|-----|-----------------|-------|------|
| DELETE | - | - | WHERE id = ${memberId} AND organization_id = ${organizationId} |

#### 送信ログテーブル

| 操作 | 項目（カラム名） | 更新値 | 備考 |
|-----|-----------------|-------|------|
| - | - | - | UI通知のため送信ログなし |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| なし | - | 成功通知のためエラーケースなし |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | なし（UI表示のため制限不要） |
| 1日あたり上限 | なし |

### 配信時間帯

特に制限なし。ユーザー操作に応じて即座に表示される。

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

- メンバーの削除は認可されたユーザー（組織管理者）のみ実行可能
- サーバーサイドでmemberIdとorganizationIdの両方を検証し、不正な削除を防止
- 削除操作後はrevalidatePathでキャッシュを無効化し、メンバーリストを更新

## 備考

- useTransitionを使用して削除処理中のローディング状態を管理
- 削除成功後はモーダルをクローズし、オプションでonSuccessコールバックを実行
- 自己削除（isSelf=true）と他メンバー削除で異なるメッセージを表示
- タイトルには絵文字プレフィックス（チェックマーク）が含まれる

---

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

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

### 推奨読解順序

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

まず、サーバーアクションの入力スキーマと戻り値を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | removeMember.ts | `frontend/apps/app/components/OrganizationMembersPage/components/DeleteMemberModal/actions/removeMember.ts` | RemoveMemberSchema（7-10行目）で入力バリデーション、戻り値の型を理解する |

**読解のコツ**: valibotのobject/stringでシンプルなスキーマを定義している。

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

処理の起点となるUIコンポーネントを特定。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | DeleteMemberModal.tsx | `frontend/apps/app/components/OrganizationMembersPage/components/DeleteMemberModal/DeleteMemberModal.tsx` | handleDelete関数（39-71行目）で削除処理とトースト表示を理解する |

**主要処理フロー**:
1. **39行目**: handleDelete関数定義
2. **40-47行目**: startTransitionでFormData作成とサーバーアクション呼び出し
3. **49-56行目**: 失敗時のエラートースト表示
4. **59-66行目**: 成功時の成功トースト表示
5. **69-70行目**: モーダルクローズとonSuccessコールバック

#### Step 3: サーバーアクションを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | removeMember.ts | `frontend/apps/app/components/OrganizationMembersPage/components/DeleteMemberModal/actions/removeMember.ts` | バリデーション（14-24行目）、削除処理（30-35行目）を理解する |

**主要処理フロー**:
- **14-17行目**: valibotでフォームデータをバリデーション
- **19-23行目**: バリデーション失敗時のエラーレスポンス
- **30-35行目**: Supabaseでorganization_membersテーブルからDELETE
- **45行目**: revalidatePathでキャッシュ無効化

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

```
DeleteMemberModal.tsx
    │
    └─ handleDelete()
           │
           ├─ startTransition()
           │      │
           │      └─ removeMember() [Server Action]
           │             │
           │             ├─ v.safeParse() [Validation]
           │             │
           │             ├─ supabase.from('organization_members').delete()
           │             │
           │             └─ revalidatePath()
           │
           ├─ [成功時] toast({ title: 'Member removed', ... })
           │
           ├─ onClose()
           │
           └─ onSuccess() [optional]
```

### データフロー図

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

削除確定                 ───▶ removeMember                 ───▶ 結果判定
(memberId,                    │                               │
 organizationId)              │                               ▼
                              ├─▶ バリデーション          [成功時]
                              │                           ├─ 成功トースト
                              └─▶ DB DELETE               ├─ モーダルクローズ
                                                          └─ onSuccess()

                                                          [失敗時]
                                                          └─ エラートースト
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| DeleteMemberModal.tsx | `frontend/apps/app/components/OrganizationMembersPage/components/DeleteMemberModal/DeleteMemberModal.tsx` | ソース | メンバー削除モーダルUI・トースト表示 |
| removeMember.ts | `frontend/apps/app/components/OrganizationMembersPage/components/DeleteMemberModal/actions/removeMember.ts` | ソース | メンバー削除サーバーアクション |
| Toast.tsx | `frontend/packages/ui/src/components/Toast/Toast.tsx` | ソース | トースト通知UIコンポーネント |
| useToast.tsx | `frontend/packages/ui/src/components/Toast/useToast.tsx` | ソース | トーストフック |
