# 通知設計書 6-Color scheme

## 概要

本ドキュメントは、OpenCodeアプリケーションにおける「Color scheme（カラースキーム切り替え）」トースト通知の設計を記述します。アプリケーションのカラースキーム（System/Light/Dark）が切り替わった際に、ユーザーに対してアプリ内トースト通知を表示する機能です。

### 本通知の処理概要

**業務上の目的・背景**：OpenCodeはSystem（システム設定に従う）、Light（ライトモード）、Dark（ダークモード）の3つのカラースキームをサポートしています。カラースキーム変更はアプリ全体の配色に影響するため、変更が適用されたことをユーザーに明確にフィードバックする必要があります。この通知により、ユーザーはカラースキーム変更が正常に完了したことを確認できます。

**通知の送信タイミング**：ユーザーがカラースキームを切り替えた時（cycleColorScheme関数実行時）に即座に送信されます。キーボードショートカット（mod+shift+s）またはコマンドパレットからの選択で発火します。

**通知の受信者**：カラースキームを切り替えたユーザー本人。設定による制御はなく、常に表示されます。

**通知内容の概要**：通知タイトル「Color scheme」と、切り替え先のスキーム名（System/Light/Dark）が説明として表示されます。

**期待されるアクション**：ユーザーは通知で新しいカラースキーム名を確認し、意図したスキームに切り替わったことを認識します。

## 通知種別

アプリ内トースト通知（一時的）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（ユーザーアクション直後） |
| 優先度 | 低 |
| リトライ | なし |

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

1. ユーザーがカラースキーム切り替えアクションを実行
2. theme.setColorScheme()でスキームを変更
3. 変更完了後、showToast()でトースト表示

## 通知テンプレート

### アプリ内トースト通知の場合

| 項目 | 内容 |
|-----|------|
| タイトル | `toast.scheme.title`（"Color scheme"） |
| 説明 | スキーム名（System/Light/Dark の翻訳済み文字列） |
| 永続性 | なし（自動消去） |
| アクション | なし |

### 本文テンプレート

```
タイトル: Color scheme
説明: {schemeName} (System / Light / Dark)
```

### 添付ファイル

| ファイル名 | 形式 | 条件 | 説明 |
|----------|------|------|------|
| なし | - | - | 添付ファイルは使用されません |

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| schemeName | スキームの表示名 | colorSchemeLabel(scheme) | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| ユーザーアクション | キーボードショートカット（mod+shift+s） | 常に | カラースキームサイクル実行時 |
| ユーザーアクション | コマンドパレットからスキーム選択 | 常に | スキーム設定時 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| なし | 抑止条件はありません |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[カラースキーム切り替えアクション] --> B[現在のスキーム取得]
    B --> C[次のスキームIndex計算]
    C --> D[theme.setColorScheme実行]
    D --> E[スキーム名取得]
    E --> F[showToast呼び出し]
    F --> G[トースト表示]
    G --> H[自動消去]
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| colorSchemeOrder | スキーム順序定義 | ローカル定数 |

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

#### colorSchemeOrder

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| scheme | スキーム値 | "system" / "light" / "dark" |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| なし | - | 通知自体は状態更新を行わない |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| なし | スキームは固定3種類のため発生しない | - |

### リトライ仕様

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

## 配信設定

### レート制限

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

### 配信時間帯

制限なし（24時間配信可能）

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

- スキーム名はシステム定義（system/light/dark）のため、セキュリティリスクは低い
- ユーザー入力を含まない

## 備考

- スキームはsystem → light → dark → system の順でサイクル
- colorSchemeOrder配列で順序を定義
- colorSchemeLabel関数で多言語対応のスキーム名を取得
- テーマ切り替えとは独立した機能（テーマ内でスキームを選択）

---

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

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

### 推奨読解順序

#### Step 1: データ定義を理解する

カラースキームの定義を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | layout.tsx | `packages/app/src/pages/layout.tsx` | colorSchemeOrder配列（116行目）でスキーム順序を理解 |
| 1-2 | layout.tsx | `packages/app/src/pages/layout.tsx` | colorSchemeKey/colorSchemeLabel（117-122行目）で翻訳キー定義を理解 |

**読解のコツ**: ColorScheme型は"system" | "light" | "dark"の3値。

#### Step 2: トリガー処理を理解する

カラースキーム切り替え関数を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | layout.tsx | `packages/app/src/pages/layout.tsx` | cycleColorScheme関数（250-261行目）でサイクルロジックを理解 |

**主要処理フロー**:
1. **251行目**: theme.colorScheme()で現在のスキーム取得
2. **252-254行目**: 次のインデックス計算（モジュロ演算）
3. **255行目**: 次のスキーム取得
4. **256行目**: theme.setColorScheme()で設定
5. **257-260行目**: showToast()でトースト表示

#### Step 3: コマンド登録を理解する

スキーム関連コマンドの登録を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | layout.tsx | `packages/app/src/pages/layout.tsx` | theme.scheme.cycle（1025-1031行目）を確認 |
| 3-2 | layout.tsx | `packages/app/src/pages/layout.tsx` | theme.scheme.{scheme}（1033-1044行目）を確認 |

**主要処理フロー**:
- **1029行目**: keybind: "mod+shift+s"でサイクル実行
- **1038行目**: 個別スキーム選択時はtheme.commitPreview()で確定

#### Step 4: i18nキーを理解する

通知テキストの多言語対応を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | en.ts | `packages/app/src/i18n/en.ts` | toast.scheme.title（398行目）を確認 |
| 4-2 | en.ts | `packages/app/src/i18n/en.ts` | theme.scheme.*（20-22行目）でスキーム名を確認 |

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

```
キーボードショートカット (mod+shift+s)
    │
    └─ cycleColorScheme (layout.tsx:250)
           │
           ├─ theme.colorScheme() - 現在スキーム取得
           │
           ├─ colorSchemeOrder[nextIndex] - 次スキーム取得
           │
           ├─ theme.setColorScheme(next) - スキーム設定
           │
           └─ showToast (toast.tsx:118)
                  ├─ title: "Color scheme"
                  └─ description: colorSchemeLabel(next)

コマンドパレット選択
    │
    └─ theme.scheme.{scheme} コマンド
           │
           ├─ onHighlight: theme.previewColorScheme(scheme) - プレビュー
           │
           └─ onSelect: theme.commitPreview() - 確定
```

### データフロー図

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

ユーザーアクション          Layout - cycleColorScheme
mod+shift+s      ────▶    スキームIndex計算  ─────────────▶   トースト通知
                          theme.setColorScheme()              UI更新
                               │
                               ▼
                          showToast({
                            title: "Color scheme",
                            description: "System" | "Light" | "Dark"
                          })
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| layout.tsx | `packages/app/src/pages/layout.tsx` | ソース | cycleColorScheme関数・コマンド登録 |
| context.tsx | `packages/ui/src/theme/context.tsx` | ソース | ThemeContext・カラースキーム状態管理 |
| toast.tsx | `packages/ui/src/components/toast.tsx` | ソース | showToast関数 |
| en.ts | `packages/app/src/i18n/en.ts` | 設定 | 翻訳キー定義 |
