# 機能設計書 46-実験的機能管理

## 概要

本ドキュメントは、Actualの「実験的機能管理」機能の設計内容を記載する。ベータ版機能の有効/無効を切り替える設定について、処理内容とUIコンポーネントの仕様を定義する。

### 本機能の処理概要

実験的機能管理は、開発中またはテスト段階の新機能を有効/無効に切り替えるフィーチャーフラグ管理機能である。ユーザーは警告を確認した上でこれらの機能を有効化できる。

**業務上の目的・背景**：新機能を段階的にリリースし、早期採用者からのフィードバックを得るため、フィーチャーフラグ機構を提供する。本番環境でもユーザーが自己責任で新機能を試用でき、問題が発生した場合は無効化できる柔軟性を確保する。

**機能の利用シーン**：新機能を試したい場合、特定の実験的機能が必要な場合、実験的機能が問題を起こした場合に無効化する場合に利用される。

**主要な処理内容**：
1. 実験的機能一覧の表示（展開/折りたたみUI）
2. 各フィーチャーフラグの有効/無効切り替え
3. フィードバックリンクの提供（GitHub Issues）
4. 同期設定への保存
5. サーバー設定フラグの管理（管理者向け）

**関連システム・外部連携**：GitHub（フィードバック用）

**権限による制御**：一部のサーバー設定フラグは管理者権限が必要（OpenID有効時）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 40 | 設定画面 | 主機能 | ベータ版機能の有効/無効切り替え |

## 機能種別

設定・フィーチャーフラグ管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| flags.{flagName} | string | No | 各フィーチャーフラグの状態 | 'true' / 'false' |

### 現在サポートされているフラグ

| フラグ名 | 説明 | フィードバックURL |
|---------|------|-----------------|
| goalTemplatesEnabled | ゴールテンプレート機能 | - |
| goalTemplatesUIEnabled | ゴールテンプレートUI（サブ機能） | - |
| actionTemplating | ルールアクションテンプレート | issues/3606 |
| formulaMode | Excel数式モード | issues/5949 |
| currency | 通貨サポート | issues/5191 |
| crossoverReport | クロスオーバーレポート | issues/6134 |
| customThemes | カスタムテーマ | issues/6607 |
| budgetAnalysisReport | 予算分析レポート | pull/6137 |

### 入力データソース

- 画面入力（チェックボックス）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| flags.{flagName} | string | フラグの状態 |

### 出力先

- 同期設定（SyncedPrefs）- デバイス間で同期される

## 処理フロー

### 処理シーケンス

```
1. 設定画面のExperimentalFeaturesコンポーネント表示
   ├─ 初期状態では折りたたみ（警告テキスト表示）
   └─ "I understand the risks..."リンククリックで展開

2. フィーチャーフラグ一覧表示
   ├─ FeatureToggleコンポーネントで各フラグを表示
   └─ ServerFeatureToggleで管理者向けフラグを表示（条件付き）

3. フラグ切り替え
   ├─ Checkboxの変更検知
   ├─ setFlagPref(String(!enabled))呼び出し
   └─ 同期設定に保存

4. サブ機能の条件付き表示
   └─ goalTemplatesEnabledが有効かつdevEnableGoalTemplatesUI='true'の場合のみ
       goalTemplatesUIEnabledを表示
```

### フローチャート

```mermaid
flowchart TD
    A[設定画面表示] --> B{実験的機能展開済み?}

    B -->|No| C[警告テキスト表示]
    C --> D{リンククリック?}
    D -->|Yes| E[setExpanded true]
    D -->|No| C

    B -->|Yes| F[フィーチャーフラグ一覧表示]
    E --> F

    F --> G[各フラグのCheckbox表示]
    G --> H{Checkbox変更?}

    H -->|Yes| I[setFlagPref呼び出し]
    H -->|No| G

    I --> J[saveSyncedPrefs dispatch]
    J --> K[同期設定に保存]
    K --> G
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-46-01 | 初期非表示 | 実験的機能一覧は初期状態で非表示 | 画面初期表示時 |
| BR-46-02 | 警告確認 | ユーザーは警告を確認してから機能一覧を表示 | 展開操作時 |
| BR-46-03 | データ損失リスク | 一部の実験的機能はデータ損失を引き起こす可能性がある | 常時 |
| BR-46-04 | サブ機能表示条件 | goalTemplatesUIEnabledは親機能有効かつdevフラグ時のみ表示 | 該当条件時 |
| BR-46-05 | 管理者制限 | ServerFeatureToggleはOIDC有効時に管理者のみ表示 | OIDC有効かつ管理者 |

### フラグ依存関係

```
goalTemplatesEnabled
    └─ goalTemplatesUIEnabled (サブ機能)
       └─ 条件: goalTemplatesEnabled && localStorage.devEnableGoalTemplatesUI === 'true'
```

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

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

本機能はSyncedPrefsを通じて設定を保存する。

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| フラグ変更 | prefs | UPDATE | flags.{flagName}を更新 |

### 設定キー詳細

| キー | 型 | 説明 |
|-----|-----|------|
| flags.goalTemplatesEnabled | string | ゴールテンプレート有効化 |
| flags.actionTemplating | string | アクションテンプレート有効化 |
| flags.formulaMode | string | 数式モード有効化 |
| flags.currency | string | 通貨サポート有効化 |
| flags.crossoverReport | string | クロスオーバーレポート有効化 |
| flags.customThemes | string | カスタムテーマ有効化 |
| flags.budgetAnalysisReport | string | 予算分析レポート有効化 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | 通常のチェックボックス操作のため発生しない | - |

### リトライ仕様

なし

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

設定変更は個別に保存される。

## パフォーマンス要件

- フラグ切替: 即座に反映（100ms以内）
- 機能有効化後、該当機能のUI更新は次回レンダリング時

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

- 実験的機能は十分にテストされていない可能性があり、セキュリティリスクを伴う可能性がある
- サーバーフラグ（ServerFeatureToggle）は管理者のみが変更可能
- ユーザーは明示的に警告を確認してから機能を有効化する

## 備考

- 実験的機能は予告なく変更・削除される可能性がある
- 各機能にはGitHub Issuesへのフィードバックリンクが設定されている
- devEnableGoalTemplatesUI等の開発者フラグはlocalStorageで管理

---

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

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

### 推奨読解順序

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

フィーチャーフラグで使用されるデータ型を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | prefs.d.ts | `packages/loot-core/src/types/prefs.d.ts` | FeatureFlag型の定義 |

**読解のコツ**: FeatureFlag型はフラグ名のユニオン型として定義されている。SyncedPrefsのflags.{flagName}としてアクセスされる。

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

実験的機能設定UIのエントリーポイントを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Experimental.tsx | `packages/desktop-client/src/components/settings/Experimental.tsx` | ExperimentalFeaturesコンポーネント全体の構造（152-253行目） |

**主要処理フロー**:
1. **153行目**: expanded状態の管理（useState）
2. **155-160行目**: goalTemplatesUIの表示条件判定
3. **166-252行目**: 展開/非展開のUI分岐
4. **168-226行目**: 各FeatureToggleコンポーネントの配置

#### Step 3: フラグ切り替えコンポーネントを理解する

FeatureToggleとServerFeatureToggleの実装を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Experimental.tsx | `packages/desktop-client/src/components/settings/Experimental.tsx` | FeatureToggle（33-77行目）とServerFeatureToggle（87-150行目） |

**主要処理フロー**:
- **40-41行目**: useFeatureFlagとuseSyncedPrefでフラグ状態を管理
- **47-48行目**: Checkbox変更時にsetFlagPref(String(!enabled))
- **94-101行目**: ServerFeatureToggleではuseServerPrefを使用
- **96-101行目**: サーバー接続状態と権限のチェック

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

```
ExperimentalFeatures (Experimental.tsx)
    │
    ├─ useState(expanded) → 展開状態管理
    │
    ├─ useFeatureFlag('goalTemplatesEnabled')
    ├─ useFeatureFlag('goalTemplatesUIEnabled')
    │
    └─ 展開時
           │
           ├─ FeatureToggle (flag: 'goalTemplatesEnabled')
           │      ├─ useFeatureFlag(flagName)
           │      ├─ useSyncedPref(`flags.${flagName}`)
           │      └─ Checkbox onChange → setFlagPref(String(!enabled))
           │
           ├─ FeatureToggle (flag: 'actionTemplating')
           ├─ FeatureToggle (flag: 'formulaMode')
           ├─ FeatureToggle (flag: 'currency')
           ├─ FeatureToggle (flag: 'crossoverReport')
           ├─ FeatureToggle (flag: 'customThemes')
           ├─ FeatureToggle (flag: 'budgetAnalysisReport')
           │
           └─ ServerFeatureToggle (prefName: 'flags.plugins')
                  ├─ useServerPref(prefName)
                  ├─ useSyncServerStatus()
                  ├─ useAuth() → hasPermission(ADMINISTRATOR)
                  └─ useLoginMethod() / useMultiuserEnabled()
```

### データフロー図

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

警告確認リンク           setExpanded(true)
クリック ─────────────▶                    ─────────────▶ UI展開

フラグCheckbox           FeatureToggle
変更 ───────────────────▶ setFlagPref(String(!enabled))
                               │
                               ▼
                          saveSyncedPrefs() ────────────▶ SyncedPrefs
                                                          (flags.{flagName})

サーバーフラグ           ServerFeatureToggle
Checkbox変更 ──────────▶ setEnabled(value)
                               │
                               ├─ 権限チェック
                               │    ├─ OIDC有効時: 管理者のみ
                               │    └─ マルチユーザー無効時: 全員
                               │
                               └─ useServerPref ─────────▶ サーバー設定
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Experimental.tsx | `packages/desktop-client/src/components/settings/Experimental.tsx` | ソース | 実験的機能設定UIコンポーネント |
| useFeatureFlag.ts | `packages/desktop-client/src/hooks/useFeatureFlag.ts` | ソース | フィーチャーフラグ取得フック |
| useSyncedPref.ts | `packages/desktop-client/src/hooks/useSyncedPref.ts` | ソース | 同期設定読み書きフック |
| useServerPref.ts | `packages/desktop-client/src/hooks/useServerPref.ts` | ソース | サーバー設定読み書きフック |
| UI.tsx | `packages/desktop-client/src/components/settings/UI.tsx` | ソース | 設定画面共通UIコンポーネント |
| AuthProvider.tsx | `packages/desktop-client/src/auth/AuthProvider.tsx` | ソース | 認証・権限プロバイダー |
| Link.tsx | `packages/desktop-client/src/components/common/Link.tsx` | ソース | 外部リンクコンポーネント |
