# 通知設計書 25-エラー通知

## 概要

本ドキュメントは、操作が失敗した際に表示される赤色のトースト通知「エラー通知」の設計仕様を定義する。ユーザーに対してエラーの発生を明確に伝達し、問題の認識と対処を促すUI通知である。

### 本通知の処理概要

エラー通知（Error Toast）は、アプリケーション内でエラーが発生したことをユーザーに通知するためのUI通知コンポーネントである。操作の失敗、API呼び出しエラー、バリデーションエラーなど、ユーザーの操作が正常に完了しなかった場合に使用される。

**業務上の目的・背景**：アプリケーション操作中にエラーが発生した場合、ユーザーに即座にフィードバックを返すことは、ユーザー体験の維持と問題解決のために極めて重要である。エラー通知は、操作が失敗したことを明確に伝え、ユーザーが次のアクション（再試行、別の方法を試す、サポートに問い合わせる等）を判断できるようにする。赤色のビジュアルスタイルは、世界的に「エラー」「危険」「停止」を示す色として認識されており、ユーザーの注意を強く引きつける。preserve: trueがデフォルトで設定されており、ユーザーが明示的に閉じるまで表示され続ける。

**通知の送信タイミング**：アプリケーション内でエラーが検出された直後にリアルタイムで表示される。具体的には、error関数を呼び出した際、またはtry-catchブロック内のエラーハンドリングでtoast関数にtype: 'error'を指定して呼び出した際に即座に画面右下にトースト通知が表示される。

**通知の受信者**：現在アプリケーションを操作中のユーザー本人のみが受信する。エラー通知はクライアントサイドで生成され、エラーが発生したユーザーのブラウザのみに表示される。他のユーザーや外部システムには送信されない。

**通知内容の概要**：トースト通知には、メッセージ（message）が必須で、オプションとしてタイトル（title）を含めることができる。エラー通知は赤色のグラデーションスタイルで表示され、視覚的にエラー・失敗を示す。テキストは--color-errorカラートークンで定義された色で表示される。error関数ではアクションボタンは設定できない設計となっている。

**期待されるアクション**：ユーザーはエラー通知を確認し、エラーの内容を理解する。その後、再試行、入力内容の修正、別の操作方法の選択、またはサポートへの問い合わせなどの対処を行うことが期待される。エラー通知はpreserve: trueがデフォルトのため、ユーザーが内容を確認するまで消えない。

## 通知種別

アプリ内通知（Toast / UI通知）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（クライアントサイド） |
| 優先度 | 高 |
| リトライ | なし（クライアントサイド表示のため） |

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

- 現在のブラウザセッションでアプリケーションを操作中のユーザー
- ToastProviderコンポーネントがレンダリングされている画面のみ

## 通知テンプレート

### UI通知の場合

| 項目 | 内容 |
|-----|------|
| 表示位置 | 画面右下（bottom-right） |
| 幅 | 360px（最大100vw） |
| 背景色 | 赤色グラデーション（--color-error系） |
| 形式 | Glass morphism UI |

### 本文テンプレート

```
┌──────────────────────────────────────┐
│ [タイトル（オプション）]           [X] │
│ メッセージ本文                        │
└──────────────────────────────────────┘
```

### 添付ファイル

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

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| message | 通知メッセージ本文 | 呼び出し元コンポーネント | Yes |
| title | 通知タイトル | 呼び出し元コンポーネント | No |
| id | トーストの一意識別子 | 自動生成またはオプション指定 | No |
| preserve | 自動消去の有無 | 固定: true | - |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 画面操作 | error()関数呼び出し | 常時 | エラー通知専用ショートカット関数 |
| 画面操作 | toast()関数呼び出し | type='error' | 汎用トースト関数によるエラー通知 |
| 例外処理 | try-catchエラーハンドリング | 例外発生時 | 非同期処理等のエラー捕捉時 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| ToastProvider未配置 | ToastProviderがコンポーネントツリーに存在しない場合はエラー |
| SSRコンテキスト | サーバーサイドレンダリング中は表示されない |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[エラー発生] --> B[error関数呼び出し]
    B --> C{ToastContext存在?}
    C -->|Yes| D[トーストID生成/取得]
    C -->|No| E[エラースロー]
    D --> F[toasts配列に追加/更新]
    F --> G[type=error, preserve=true設定]
    G --> H[ToastPrimitive.Root描画]
    H --> I[赤色スタイルで表示]
    I --> J[手動クローズ待機]
    J --> K[ユーザーが閉じるボタンをクリック]
    K --> L[dismiss呼び出し]
    L --> M[toasts配列から削除]
    M --> N[終了]
    E --> N
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| なし | - | クライアントサイドのみで完結するためDB参照なし |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| なし | - | クライアントサイドのみで完結するためDB更新なし |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| Context未定義エラー | ToastProviderの外でuseToastsを呼び出し | "useToast must be used within a ToastProvider"エラーをスロー |

### リトライ仕様

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

## 配信設定

### レート制限

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

### 配信時間帯

制限なし（24時間、エラー発生に応じて即時表示）

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

- トースト通知は現在のユーザーセッションでのみ表示され、他ユーザーには漏洩しない
- XSS対策としてReactのエスケープ機能により、メッセージ内のHTMLはエスケープされる
- スタックトレースや内部エラー詳細をエラーメッセージに含めないこと
- ユーザー向けの分かりやすいエラーメッセージを表示すること

## 備考

- 実装ファイル: `internal-packages/ui/components/toast.tsx`
- Radix UIのToastプリミティブを使用
- Tailwind CSSでスタイリング
- カラートークン: --color-error
- preserve: trueが固定されており、自動消去されない
- error()ショートカット関数ではアクションボタンを設定できない

---

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

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

### 推奨読解順序

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

まず、トースト通知のデータ構造（インターフェース）を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | toast.tsx | `internal-packages/ui/components/toast.tsx` | Toastインターフェース（18-25行目）でtype: "error"が定義されていることを確認 |

**読解のコツ**: error関数とinfo関数のシグネチャの違いに注目する。

#### Step 2: error関数を理解する

エラー通知専用のショートカット関数を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | toast.tsx | `internal-packages/ui/components/toast.tsx` | error関数（122-127行目）がエラー通知のショートカット |

**主要処理フロー**:
1. **122行目**: useCallbackでメモ化されたerror関数
2. **123行目**: 引数はmessageとオプショナルな{ title? }のみ
3. **124行目**: _toast関数に{ type: "error", preserve: true }で委譲
4. **注目**: actionオプションが設定できない（infoとの違い）

#### Step 3: スタイリングを理解する

エラー通知に適用される赤色スタイルを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | toast.tsx | `internal-packages/ui/components/toast.tsx` | ToastPrimitive.Root内のclsx（153-165行目）でdata-[type=error]のスタイルを確認 |

**主要処理フロー**:
- **160行目**: data-[type=error]:bg-linear-to-b from-[--color-error]/18 で赤色グラデーション背景
- **160行目**: via-[--color-error]/12 でグラデーション中間色
- **160行目**: to-[--color-error]/8 でグラデーション終端色
- **163行目**: data-[type=error]:ring-[--color-error]/30 でリングカラー（やや強調）

#### Step 4: テキストカラーを理解する

エラー通知のテキストに適用される色を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | toast.tsx | `internal-packages/ui/components/toast.tsx` | ToastPrimitive.Title内（172-210行目）でgroup-data-[type=error]のテキスト色を確認 |

**主要処理フロー**:
- **179行目**: group-data-[type=error]:text-[color:var(--color-error)] でタイトルテキスト色
- **191行目**: group-data-[type=error]:text-[color:var(--color-error)]/70 で説明テキスト色（やや薄め）

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

```
error(message, { title? })
    |
    +-- useCallback内の処理
          |
          +-- _toast(message, { type: "error", preserve: true, title })
                |
                +-- upsertToastArray()
                |     |
                |     +-- { id, message, type: "error", preserve: true, ... }
                |
                +-- setToasts()
                      |
                      +-- React State更新
                            |
                            +-- ToastPrimitive.Root再レンダリング
                                  |
                                  +-- data-type="error"
                                  |     |
                                  |     +-- 赤色スタイル適用
                                  |
                                  +-- duration={POSITIVE_INFINITY}
                                        |
                                        +-- 自動消去なし
```

### データフロー図

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

error(message, { title }) ──────> useCallback error()
                                        |
                                        v
                                  _toast(message, {
                                    type: "error",
                                    preserve: true,
                                    title
                                  })
                                        |
                                        v
                                  upsertToastArray()
                                        |
                                        v
                                  { id, message, type: "error",
                                    preserve: true, title }
                                        |
                                        v
                                  [React State: toasts[]]
                                        |
                                        v
                                  toasts.map(render)
                                        |
                                        v
                                  <ToastPrimitive.Root
                                    data-type="error"
                                    duration={Infinity}>
                                        |
                                        v
                                  bg-linear-to-b from-[--color-error]
                                        |
                                        v
                                  画面右下に赤色トースト表示
                                  （手動クローズまで表示継続）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| toast.tsx | `internal-packages/ui/components/toast.tsx` | ソース | トースト通知コンポーネント・フック |
| index.ts | `internal-packages/ui/components/index.ts` | ソース | コンポーネントエクスポート |
| package.json | `internal-packages/ui/package.json` | 設定 | 依存関係定義（radix-ui, clsx） |
