# 通知設計書 24-警告通知

## 概要

本ドキュメントは、注意が必要な状況で表示される黄色のトースト通知「警告通知」の設計仕様を定義する。ユーザーに対して注意喚起や警告を視覚的に伝達し、潜在的な問題や注意事項を認識させるUI通知である。

### 本通知の処理概要

警告通知（Warning Toast）は、アプリケーション内でユーザーに対して注意喚起や警告を通知するためのUI通知コンポーネントである。エラーではないが、ユーザーが認識しておくべき重要な情報を伝達する。

**業務上の目的・背景**：アプリケーション運用において、即座にエラーではないものの、ユーザーが注意を払うべき状況が発生することがある。例えば、データの有効期限が近づいている、互換性に関する注意事項がある、推奨されない操作が行われようとしている、などの場合である。警告通知は、これらの状況をユーザーに伝え、問題の発生を未然に防ぐための重要な役割を果たす。黄色のビジュアルスタイルは、世界的に「注意」「警告」を示す色として認識されており、ユーザーの注意を効果的に引きつける。

**通知の送信タイミング**：アプリケーション内で注意が必要な状況が検出された際にリアルタイムで表示される。具体的には、toast関数にtype: 'warning'を指定して呼び出した際に即座に画面右下にトースト通知が表示される。

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

**通知内容の概要**：トースト通知には、メッセージ（message）が必須で、オプションとしてタイトル（title）、アクションボタン（action）を含めることができる。警告通知は黄色のグラデーションスタイルで表示され、視覚的に注意・警告を示す。テキストは--color-warningカラートークンで定義された色で表示される。他のタイプと比較して、背景の透明度がやや高く設定されている。

**期待されるアクション**：ユーザーは警告通知を確認し、示された注意事項を理解する。必要に応じて推奨されるアクションを取るか、アクションボタンをクリックして対処する。警告通知は情報提供を目的としており、必ずしも即座のアクションを必要としないが、後続の問題を防ぐために内容を認識することが期待される。

## 通知種別

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

## 送信仕様

### 基本情報

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

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

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

## 通知テンプレート

### UI通知の場合

| 項目 | 内容 |
|-----|------|
| 表示位置 | 画面右下（bottom-right） |
| 幅 | 360px（最大100vw） |
| 背景色 | 黄色グラデーション（--color-warning系、透明度やや高め） |
| 形式 | Glass morphism UI |

### 本文テンプレート

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

### 添付ファイル

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

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| message | 通知メッセージ本文 | 呼び出し元コンポーネント | Yes |
| title | 通知タイトル | 呼び出し元コンポーネント | No |
| id | トーストの一意識別子 | 自動生成またはオプション指定 | No |
| preserve | 自動消去の有無 | オプション（デフォルト: true） | No |
| action.label | アクションボタンのラベル | オプション | No |
| action.onClick | アクションボタンのクリックハンドラ | オプション | No |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 画面操作 | toast()関数呼び出し | type='warning' | 汎用トースト関数による警告通知 |
| 検証結果 | バリデーション警告 | 注意が必要な入力値検出時 | 非致命的なバリデーション警告 |

### 送信抑止条件

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

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[警告条件検出] --> B[toast関数呼び出し type=warning]
    B --> C{ToastContext存在?}
    C -->|Yes| D[トーストID生成/取得]
    C -->|No| E[エラースロー]
    D --> F[toasts配列に追加/更新]
    F --> G[ToastPrimitive.Root描画]
    G --> H[黄色スタイルで表示]
    H --> I{preserve=true?}
    I -->|Yes| J[手動クローズ待機]
    I -->|No| K[自動消去]
    J --> L[dismiss呼び出し]
    K --> L
    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-warning
- 警告通知は他のタイプと比較して背景の透明度が高い（/30, /20, /12 vs 他の/18, /12, /8）
- 専用のwarning()ショートカット関数は未定義（info, errorのみ）

---

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

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

### 推奨読解順序

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

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

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

**読解のコツ**: type: "warning"の場合、他のタイプとスタイルがどう異なるかを注目する。

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

警告通知に適用される黄色スタイルを確認する。特に透明度の違いに注目。

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

**主要処理フロー**:
1. **148行目**: data-type={toast.type}でtype属性をDOMに設定
2. **159行目**: data-[type=warning]:bg-linear-to-b from-[--color-warning]/30 で黄色グラデーション背景（透明度30%）
3. **159行目**: via-[--color-warning]/20 でグラデーション中間色（透明度20%）
4. **159行目**: to-[--color-warning]/12 でグラデーション終端色（透明度12%）
5. **163行目**: data-[type=warning]:ring-[color:var(--color-warning)]/25 でリングカラーを適用

**注目点**: warningは他のタイプ（/18, /12, /8）より高い透明度（/30, /20, /12）を持つ

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

警告通知のテキストに適用される色を確認する。

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

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

#### Step 4: トースト呼び出し方法を理解する

警告通知を表示するための呼び出し方法を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | toast.tsx | `internal-packages/ui/components/toast.tsx` | _toast関数（104-120行目）でtype: "warning"を指定する方法 |

**主要処理フロー**:
- toast(message, { type: "warning" })で警告通知を表示
- 専用のwarning()ショートカット関数は定義されていない（info, errorのみ）

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

```
toast(message, { type: "warning" })
    |
    +-- _toast() (内部関数)
          |
          +-- upsertToastArray()
          |     |
          |     +-- { ...options, type: "warning" }
          |
          +-- setToasts()
                |
                +-- React State更新
                      |
                      +-- ToastPrimitive.Root再レンダリング
                            |
                            +-- data-type="warning"
                                  |
                                  +-- 黄色スタイル適用
                                  +-- 高透明度グラデーション
```

### データフロー図

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

toast(message, { type: "warning" }) ───> _toast()
                                              |
                                              v
                                    upsertToastArray()
                                              |
                                              v
                                    { id, message, type: "warning", ... }
                                              |
                                              v
                                    [React State: toasts[]]
                                              |
                                              v
                                    toasts.map(render)
                                              |
                                              v
                                    <ToastPrimitive.Root data-type="warning">
                                              |
                                              v
                                    bg-linear-to-b from-[--color-warning]/30
                                    via-[--color-warning]/20
                                    to-[--color-warning]/12
                                              |
                                              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） |
