# 通知設計書 31-プラグイン検索エラー通知

## 概要

本ドキュメントは、Etherpad管理画面におけるプラグイン検索エラー通知の設計を記載する。この通知は、管理者がプラグイン検索を実行した際にnpmレジストリへのアクセスエラーなどが発生した場合に表示されるトースト通知である。

### 本通知の処理概要

管理画面のホームページ（プラグイン管理ページ）において、プラグイン検索機能でエラーが発生した際に、管理者に対してエラーを視覚的に通知する処理を行う。

**業務上の目的・背景**：Etherpadの管理者は、プラグインの追加・更新を行うためにnpmレジストリからプラグイン一覧を検索する必要がある。ネットワーク障害やnpmサービスの一時的な問題、あるいはサーバー側の設定問題などにより検索が失敗した場合、管理者はその原因を把握し、適切な対応を行う必要がある。本通知は、検索失敗を即座に管理者に伝え、問題解決のきっかけを提供する。

**通知の送信タイミング**：サーバー側でプラグイン検索処理（`search`イベント）が実行され、例外がスローされた場合に`results:searcherror`イベントがクライアントに送信される。クライアントはこのイベントを受信すると、トースト通知を表示する。

**通知の受信者**：管理画面にログインしている管理者ユーザー（`is_admin`が`true`のユーザー）のみが受信対象となる。

**通知内容の概要**：「Error retrieving plugins」という固定メッセージがトースト通知として表示される。サーバー側で発生した具体的なエラーメッセージはコンソールにログ出力されるが、ユーザー向けのトースト通知には詳細は含まれない。

**期待されるアクション**：管理者はエラー通知を確認後、ブラウザの開発者ツールでコンソールログを確認するか、サーバーログを確認して具体的なエラー原因を特定する。ネットワーク接続を確認し、必要に応じてページをリロードして再試行する。

## 通知種別

アプリ内通知（トースト通知）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（Socket.IO経由のリアルタイム通知） |
| 優先度 | 高 |
| リトライ | なし |

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

管理画面のプラグインページ（`/admin/`）にアクセスしている管理者ユーザーに対して通知が送信される。送信先はSocket.IO接続を通じて特定され、認証済みの管理者セッションを持つクライアントのみが対象となる。

## 通知テンプレート

### トースト通知の場合

| 項目 | 内容 |
|-----|------|
| タイトル | Error retrieving plugins |
| 説明 | なし（titleのみ表示） |
| 表示スタイル | ToastRootFailure（エラースタイル） |

### 本文テンプレート

```
Error retrieving plugins
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| title | 通知タイトル | ハードコード値 | Yes |
| success | 成功/失敗フラグ | false固定 | Yes |
| open | 表示状態 | true固定 | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| Socket.IOイベント | results:searcherror | サーバー側でプラグイン検索中に例外が発生 | npmレジストリへのアクセス失敗、タイムアウト、パースエラーなど |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| 管理者以外のユーザー | is_adminがfalseの場合、Socket.IO接続自体が拒否される |
| 検索が正常に完了した場合 | results:searchイベントが送信され、エラー通知は発生しない |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[管理者がプラグインページにアクセス] --> B[検索パラメータ変更/初期化]
    B --> C[pluginsSocket.emit 'search']
    C --> D[サーバー: search イベント処理]
    D --> E{検索処理結果}
    E -->|成功| F[results:search イベント送信]
    E -->|失敗| G[results:searcherror イベント送信]
    G --> H[クライアント: エラーイベント受信]
    H --> I[console.log でエラー詳細出力]
    I --> J[setToastState でトースト表示]
    J --> K[ToastDialog コンポーネント表示]
    F --> L[プラグイン一覧更新]
```

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

### 参照テーブル一覧

本通知処理においてデータベース参照は発生しない。プラグイン検索はnpmレジストリへの外部API呼び出しによって実行される。

### 更新テーブル一覧

該当なし

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| ネットワークエラー | npmレジストリへの接続失敗 | ネットワーク接続を確認し、再試行 |
| タイムアウト | npmレジストリからの応答遅延 | 時間をおいて再試行 |
| レスポンスパースエラー | npmレジストリからの不正なレスポンス | サーバーログを確認 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（自動リトライなし） |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし（管理画面アクセス時に随時送信）

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

- 管理者認証が必須であり、認証されていないユーザーにはSocket.IO接続が拒否される
- エラー詳細はコンソールログにのみ出力され、ユーザー向け通知には詳細なエラー情報は含まれない（情報漏洩防止）
- サーバー側のログにはエラー詳細が記録される（`logger.error`）

## 備考

- エラー通知はRadix UIのToastコンポーネントを使用して表示される
- 通知の表示状態はZustandストアで管理される
- トーストは一定時間後に自動的に閉じる（Radix UIのデフォルト動作）

---

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

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

### 推奨読解順序

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

まず、通知に関連するデータ構造（ToastStateとSearchParams）を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | store.ts | `admin/src/store/store.ts` | ToastState型（6-11行目）とsetToastState関数（41行目）の構造を確認 |
| 1-2 | Plugin.ts | `admin/src/pages/Plugin.ts` | SearchParams型（19-25行目）で検索パラメータの構造を確認 |

**読解のコツ**: Zustandストアのパターンを理解していると、状態管理の流れが把握しやすい。

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

クライアント側の通知表示処理の起点となるファイルを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | HomePage.tsx | `admin/src/pages/HomePage.tsx` | results:searcherrorイベントリスナー（133-140行目）がエントリーポイント |

**主要処理フロー**:
1. **133行目**: `pluginsSocket!.on('results:searcherror', ...)` - エラーイベントのリスナー登録
2. **134行目**: `console.log(data.error)` - エラー詳細をコンソールに出力
3. **135-139行目**: `useStore.getState().setToastState({...})` - トースト状態を更新

#### Step 3: サーバー側のエラー発生処理を理解する

サーバー側でエラーイベントが送信される処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | adminplugins.ts | `src/node/hooks/express/adminplugins.ts` | searchイベントハンドラ（86-100行目）でエラー処理を確認 |

**主要処理フロー**:
- **86行目**: `socket.on('search', async (query: QueryType) => {...})` - 検索イベントハンドラ
- **96-99行目**: catch節でエラーをログ出力し、`results:searcherror`イベントを送信

#### Step 4: トースト表示コンポーネントを理解する

通知の表示を担当するコンポーネントを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Toast.tsx | `admin/src/utils/Toast.tsx` | ToastDialogコンポーネント（5-26行目）でRadix UIトーストの実装を確認 |

**主要処理フロー**:
- **6行目**: Zustandストアからtoast状態を取得
- **7-9行目**: 成功/失敗に応じたスタイルクラスを決定
- **13-23行目**: Radix UIのToastコンポーネントをレンダリング

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

```
[クライアント] HomePage.tsx
    │
    ├─ pluginsSocket.emit('search', searchParams)
    │      │
    │      └─ [サーバー] adminplugins.ts: socket.on('search')
    │             │
    │             ├─ search() [pluginfw/installer]
    │             │      └─ npm registry API呼び出し
    │             │
    │             └─ catch: socket.emit('results:searcherror')
    │
    └─ pluginsSocket.on('results:searcherror')
           │
           ├─ console.log(data.error)
           │
           └─ useStore.getState().setToastState()
                  │
                  └─ Toast.tsx: ToastDialog表示
```

### データフロー図

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

検索パラメータ ───────▶ adminplugins.ts
(SearchParams)          │
                        ├─ search() 呼び出し
                        │
                        └─ エラー発生時
                           │
                           └─▶ results:searcherror ───▶ HomePage.tsx
                               (error: string)          │
                                                        ├─▶ console.log
                                                        │
                                                        └─▶ ToastState
                                                            │
                                                            └─▶ Toast.tsx表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| HomePage.tsx | `admin/src/pages/HomePage.tsx` | ソース | プラグイン管理ページ、エラーイベントリスナー |
| adminplugins.ts | `src/node/hooks/express/adminplugins.ts` | ソース | サーバー側プラグイン検索処理、エラーイベント送信 |
| store.ts | `admin/src/store/store.ts` | ソース | Zustandストア、ToastState管理 |
| Toast.tsx | `admin/src/utils/Toast.tsx` | ソース | トースト通知表示コンポーネント |
| Plugin.ts | `admin/src/pages/Plugin.ts` | ソース | プラグイン関連の型定義 |
| installer.js | `src/static/js/pluginfw/installer.js` | ソース | npmレジストリ検索処理 |
