# 機能設計書 56-国際化

## 概要

本ドキュメントは、OpenCodeの国際化（i18n）機能について、その設計仕様を記述するものである。

### 本機能の処理概要

国際化機能は、UIテキストの多言語対応を実現する機能である。17言語（英語、日本語、中国語簡体字/繁体字、韓国語、ドイツ語、スペイン語、フランス語、デンマーク語、ポーランド語、ロシア語、アラビア語、ノルウェー語、ポルトガル語、ボスニア語、タイ語）をサポートし、ブラウザ言語設定またはユーザー選択に基づいてテキストを切り替える。

**業務上の目的・背景**：OpenCodeはグローバルに利用されるツールであり、英語を母国語としないユーザーにとって、母国語でのUI表示は作業効率とユーザー体験を大きく向上させる。

**機能の利用シーン**：
- アプリケーション起動時のブラウザ言語自動検出
- 設定画面での言語切り替え
- エラーメッセージの多言語表示
- ツール名・ステータスメッセージの翻訳

**主要な処理内容**：
1. ブラウザ設定（navigator.languages）からロケール自動検出
2. 辞書ファイルの読み込みとフラット化
3. テンプレート文字列（{{key}}形式）の変数置換
4. 複数形対応（one/other）
5. ローカルストレージへの言語設定永続化
6. フォールバック（未翻訳時は英語表示）

**関連システム・外部連携**：ローカルストレージ、ブラウザ言語設定

**権限による制御**：特になし

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1-11 | 各種画面 | 主機能 | 画面内テキストの多言語対応 |
| 4 | レイアウト | 補助機能 | 言語切り替え機能 |

## 機能種別

UI国際化 / ローカライゼーション

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| key | string | Yes | 翻訳キー（ドット区切り形式） | 空文字不可 |
| params | Record<string, string \| number> | No | テンプレート変数 | - |
| locale | Locale | No | 言語コード | 有効なロケールコード |

### 入力データソース

- 辞書ファイル（*.ts）
- ローカルストレージ（保存済み言語設定）
- ブラウザ言語設定（navigator.languages）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| translatedText | string | 翻訳済みテキスト |
| locale | Locale | 現在の言語コード |

### 出力先

- UIコンポーネント（テキスト表示）
- ローカルストレージ（設定保存）

## 処理フロー

### 処理シーケンス

```
1. 言語初期化
   └─ initI18n(): ストアから保存済み言語を読み込み、なければブラウザ設定検出

2. 辞書構築
   └─ build(locale): ベース辞書（英語）に言語固有辞書をマージ

3. 翻訳関数呼び出し
   └─ t(key, params): キーに対応するテキストを取得

4. テンプレート解決
   └─ resolveTemplate: {{key}}形式の変数を置換

5. 言語変更
   └─ setLocale(): 辞書再構築、ストア保存、状態更新
```

### フローチャート

```mermaid
flowchart TD
    A[アプリ起動] --> B[initI18n]
    B --> C[Store.load]
    C --> D{保存済み言語あり?}
    D -->|Yes| E[保存済み言語設定]
    D -->|No| F[detectLocale]
    F --> G[navigator.languages解析]
    G --> H[言語コード抽出]
    E --> I[build]
    H --> I
    I --> J[ベース辞書+言語固有辞書]
    J --> K[state.dict設定]
    K --> L[translator生成]
    L --> M[t関数利用可能]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | デフォルト言語 | 英語（en）をデフォルトとして使用 | 言語検出失敗時 |
| BR-02 | フォールバック | 翻訳が存在しない場合は英語テキストを表示 | 翻訳未定義時 |
| BR-03 | 中国語判定 | zh-Hantは繁体字、それ以外は簡体字 | 中国語検出時 |
| BR-04 | ノルウェー語判定 | no/nb/nnはすべてnoにマップ | ノルウェー語検出時 |
| BR-05 | 複数形対応 | .one/.otherサフィックスで単複形を区別 | 数量表示時 |

### 計算ロジック

- 言語検出: `navigator.languages`を先頭から順にチェックし、最初に一致したロケールを使用
- 辞書マージ: `{ ...base, ...i18n.flatten(appLang), ...i18n.flatten(desktopLang) }`

## データベース操作仕様

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | データベースは使用しない |

### テーブル別操作詳細

ローカルストレージを使用:
- `opencode.global.dat` → `language`: 言語設定

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ストア読み込み失敗 | ストレージアクセス不可 | デフォルト言語使用 |
| - | 翻訳キー未発見 | 存在しないキー指定 | キー文字列をそのまま返す |

### リトライ仕様

リトライは行わない。エラー時はフォールバック処理。

## トランザクション仕様

該当なし

## パフォーマンス要件

- 翻訳関数: O(1)のオブジェクト参照
- 辞書構築: 起動時に1回のみ実行

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

- テンプレート変数のエスケープ（XSS対策）

## 備考

- 対応言語数: 17言語
- 翻訳キー形式: ドット区切り（例: "ui.common.cancel"）
- テンプレート形式: {{variable}}

---

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

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

### 推奨読解順序

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

UIコンポーネント用の辞書構造を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | en.ts | `packages/ui/src/i18n/en.ts` | 英語辞書（ベース辞書）の構造 |
| 1-2 | ja.ts | `packages/ui/src/i18n/ja.ts` | 日本語辞書の例 |

**読解のコツ**:
- キー形式: `"ui.カテゴリ.項目"` の階層構造
- テンプレート変数: `{{count}}`、`{{limit}}`等
- 複数形: `.one`、`.other`サフィックス

#### Step 2: デスクトップアプリの国際化を理解する

Tauriデスクトップアプリ固有の国際化を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.ts | `packages/desktop/src/i18n/index.ts` | 言語検出、辞書構築、t関数 |

**主要処理フロー**:
1. **36-51行目**: `Locale`型定義（15言語）
2. **74-104行目**: `detectLocale()` - ブラウザ言語検出
3. **140-156行目**: `build(locale)` - 辞書構築
4. **166-170行目**: `t(key, params)` - 翻訳関数
5. **172-191行目**: `initI18n()` - ストアからの初期化

#### Step 3: Webアプリの国際化を理解する

Web UIでの言語コンテキストを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | language.tsx | `packages/app/src/context/language.tsx` | LanguageProvider、useLanguage |

**読解のコツ**:
- SolidJSのcreateContextパターン
- リアクティブな言語切り替え

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

```
アプリ起動
    │
    ├─ [デスクトップ]
    │      │
    │      └─ initI18n() (desktop/src/i18n/index.ts)
    │             │
    │             ├─ Store.load("opencode.global.dat")
    │             │
    │             ├─ pickLocale(value)
    │             │
    │             └─ build(locale)
    │                    │
    │                    └─ i18n.flatten(dict)
    │
    └─ [Web]
           │
           └─ LanguageProvider (app/src/context/language.tsx)
                  │
                  ├─ detectLocale()
                  │
                  └─ t(key, params)
                         │
                         └─ translator(dict, resolveTemplate)
```

### データフロー図

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

ブラウザ設定
  navigator.languages ──▶ detectLocale() ──────────────▶ Locale
     │
ストレージ
  language設定 ─────────▶ initI18n() ──────────────────▶ state.locale
     │                          │
     │                          ▼
辞書ファイル                   build(locale)
  en.ts + xx.ts ───────▶ i18n.flatten ────────────────▶ Dictionary
     │                          │
     │                          ▼
翻訳リクエスト                 translator()
  t(key, params) ───────────────────────────────────────▶ 翻訳テキスト
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| en.ts | `packages/ui/src/i18n/en.ts` | ソース | UIベース辞書（英語） |
| ja.ts | `packages/ui/src/i18n/ja.ts` | ソース | UI日本語辞書 |
| zh.ts | `packages/ui/src/i18n/zh.ts` | ソース | UI中国語簡体字辞書 |
| zht.ts | `packages/ui/src/i18n/zht.ts` | ソース | UI中国語繁体字辞書 |
| ko.ts | `packages/ui/src/i18n/ko.ts` | ソース | UI韓国語辞書 |
| de.ts | `packages/ui/src/i18n/de.ts` | ソース | UIドイツ語辞書 |
| es.ts | `packages/ui/src/i18n/es.ts` | ソース | UIスペイン語辞書 |
| fr.ts | `packages/ui/src/i18n/fr.ts` | ソース | UIフランス語辞書 |
| index.ts | `packages/desktop/src/i18n/index.ts` | ソース | デスクトップ国際化エントリー |
| language.tsx | `packages/app/src/context/language.tsx` | ソース | Web言語コンテキスト |
