# 画面設計書 6-サーバー設定画面

## 概要

本ドキュメントは、Actual Budget アプリケーションのサーバー設定画面の設計仕様を記述したものである。

### 本画面の処理概要

サーバー設定画面は、Actual Budget が接続する同期サーバーのURLを設定する画面である。Electron環境では内蔵サーバーの設定も可能で、Web環境では外部サーバーのURLを指定する。サーバーとの同期機能や銀行同期機能を利用するために必要な設定を行う。

**業務上の目的・背景**：Actual Budget はセルフホスト型のアプリケーションであり、データの同期や銀行連携機能を利用するためにはサーバーへの接続が必要である。この画面では、ユーザーが自身のサーバー環境に合わせた接続設定を行うことができる。Electronデスクトップアプリでは、内蔵同期サーバーを起動してローカルで完結する構成も選択可能。

**画面へのアクセス方法**：以下の方法でこの画面にアクセスする：
- 初回起動時にサーバーが未設定の場合の自動遷移
- 予算ファイル選択画面の設定メニューから「Server settings」を選択
- `/config-server` URLへの直接アクセス

**主要な操作・処理内容**：
1. 【内蔵サーバー（Electron）】ローカルサーバーのポート設定と起動
2. 【外部サーバー】サーバーURLの入力と接続検証
3. 自己署名証明書の選択（Electron環境）
4. 「Don't use a server」でサーバーなしモードに移行
5. 「Use current domain」でWeb環境の同一ドメインを使用

**画面遷移**：
- 遷移元：ブートストラップ処理（自動）、予算ファイル選択画面（メニュー経由）、ウェルカム画面
- 遷移先：ルート画面（`/`）→ ログイン画面または予算ファイル選択画面

**権限による表示制御**：この画面は認証状態に関わらずアクセス可能。サーバー変更時は既存セッションがログアウトされる。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 53 | 同期サーバー | 主機能 | サーバーURL設定・接続設定の変更処理 |
| 54 | ヘルスチェック | 補助機能 | 設定変更後のサーバー接続確認 |

## 画面種別

設定画面

## URL/ルーティング

`/config-server`

## 入出力項目

### 内蔵サーバー設定（Electron環境）

| 項目名 | 項目ID | 入出力 | 必須 | データ型 | 最大長 | 備考 |
|--------|--------|--------|------|----------|--------|------|
| ドメイン | domain | 表示 | - | string | - | "localhost"固定 |
| ポート | port | 入力 | 必須 | number | 5桁 | 1-65535の範囲 |

### 外部サーバー設定

| 項目名 | 項目ID | 入出力 | 必須 | データ型 | 最大長 | 備考 |
|--------|--------|--------|------|----------|--------|------|
| サーバーURL | url | 入力 | 必須 | string | - | https://で始まるURL |

## 表示項目

| 項目名 | 表示内容 | 備考 |
|--------|----------|------|
| タイトル（内蔵） | "Configure your server" | Electron内蔵サーバー設定時 |
| タイトル（外部） | "Where's the server?" | 外部サーバー設定時 |
| 説明文 | サーバー設定の説明・ガイド | 状況に応じた説明文 |
| エラーメッセージ | 接続エラーの詳細 | 条件付き表示 |

## イベント仕様

### 1-内蔵サーバー起動/設定保存（Start/Saveボタン押下）

1. ポート番号の検証（1-65535の範囲）
2. グローバルプリファレンスにサーバー設定を保存
3. 既存サーバーを停止し、新しい設定でサーバーを起動
4. `http://localhost:{port}` をサーバーURLとして設定
5. ルート画面（`/`）に遷移

### 2-外部サーバー接続（OKボタン押下）

1. URL形式の検証（http://またはhttps://プレフィックス）
2. `setServerUrl` でサーバーURLを設定・検証
3. 成功時：`signOut` アクションをdispatchしてルート画面に遷移
4. 失敗時：エラーメッセージを表示

### 3-サーバーなしモード（Don't use a serverボタン押下）

1. サーバーURLを `null` に設定
2. `loggedIn` アクションをdispatchしてルート画面に遷移
3. （Electron）内蔵サーバーが起動中の場合は停止

### 4-現在のドメイン使用（Use current domainボタン押下）

1. `window.location.origin` をURL入力欄に設定
2. ユーザーがOKボタンを押して接続

### 5-自己署名証明書選択（Electron環境）

1. ファイル選択ダイアログを表示（.crt, .pemファイル）
2. 選択された証明書パスをグローバルプリファレンスに保存
3. Electronを再起動して証明書を適用

### 6-外部サーバー設定に切り替え（Use an external serverボタン押下）

1. `serverConfigView` stateを 'external' に変更
2. 外部サーバー設定UIを表示

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| サーバー設定保存 | global_prefs（ローカル） | UPDATE | サーバーURLとポート設定を保存 |
| 証明書設定 | global_prefs（ローカル） | UPDATE | 自己署名証明書パスを保存 |

### テーブル別更新項目詳細

#### global_prefs（ローカル）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | serverURL | 入力されたURL | サーバー接続先 |
| UPDATE | syncServerConfig.port | 入力されたポート番号 | 内蔵サーバーポート |
| UPDATE | syncServerConfig.autoStart | true | 自動起動フラグ |
| UPDATE | serverSelfSignedCert | 証明書ファイルパス | 自己署名証明書 |

## メッセージ仕様

| メッセージID | メッセージ内容 | 種別 | 表示条件 |
|-------------|---------------|------|----------|
| network-failure | "Server is not running at this URL. Make sure you have HTTPS set up properly." | エラー | ネットワーク接続失敗時 |
| default | "Server does not look like an Actual server. Is it set up correctly?" | エラー | サーバー検証失敗時 |
| port-error | "Ports must be within range 1 - 65535" | エラー | ポート番号が範囲外の場合 |
| config-error | "Failed to configure sync server" | エラー | サーバー設定失敗時 |

## 例外処理

| 例外ケース | 処理内容 |
|------------|----------|
| サーバー接続失敗 | エラーメッセージを表示し、自己署名証明書の選択を促す（Electron） |
| ポート番号範囲外 | "Ports must be within range 1 - 65535" エラーメッセージを表示 |
| サーバー起動失敗 | "Failed to configure sync server" エラーメッセージを表示 |
| 無効なURL | サーバー検証エラーメッセージを表示 |

## 備考

- Electron環境では内蔵サーバーと外部サーバーの両方を選択可能
- Web環境では外部サーバー設定のみ表示
- サーバーを変更すると既存のセッションはログアウトされる
- 開発環境（isNonProductionEnvironment）では「Create test file」ボタンが追加表示

---

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

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

### 推奨読解順序

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

サーバー設定の保存形式を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | prefsSlice.ts | `packages/desktop-client/src/prefs/prefsSlice.ts` | グローバルプリファレンスの型定義 |

**読解のコツ**: `syncServerConfig` の型構造（port, autoStart）を確認する

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

メインコンポーネントの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ConfigServer.tsx | `packages/desktop-client/src/components/manager/ConfigServer.tsx` | メインコンポーネントの実装 |

**主要処理フロー**:
1. **289-396行目**: ConfigServer関数の初期化、状態管理
2. **325-349行目**: onSubmit関数で外部サーバーURL設定
3. **371-381行目**: onSkip関数でサーバーなしモード移行
4. **387-395行目**: serverConfigView stateで表示切り替え
5. **32-287行目**: ElectronServerConfig コンポーネント（内蔵サーバー設定）

#### Step 3: 内蔵サーバー設定を理解する

Electron環境固有の設定を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ElectronServerConfig | `packages/desktop-client/src/components/manager/ConfigServer.tsx` (32-287行目) | 内蔵サーバー設定UI |

**主要処理フロー**:
- **58-99行目**: onConfigureSyncServer関数でサーバー起動
- **101-108行目**: initElectronSyncServerRunningStatus でサーバー状態確認
- **114-122行目**: dontUseSyncServer関数でサーバー停止

#### Step 4: サーバーコンテキストを理解する

サーバーURL管理の仕組みを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | ServerContext.tsx | `packages/desktop-client/src/components/ServerContext.tsx` | useSetServerURL hookの実装 |

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

```
ConfigServer (ConfigServer.tsx)
    │
    ├─ [serverConfigView === 'internal'] (Electron)
    │      └─ ElectronServerConfig
    │             ├─ onConfigureSyncServer
    │             │      ├─ saveGlobalPrefs({ syncServerConfig })
    │             │      ├─ Actual.stopSyncServer()
    │             │      ├─ Actual.startSyncServer()
    │             │      ├─ setServerUrl(`http://localhost:${port}`)
    │             │      └─ navigate('/')
    │             │
    │             └─ dontUseSyncServer
    │                    ├─ setSyncServerConfig(null)
    │                    ├─ Actual.stopSyncServer()
    │                    └─ onDoNotUseServer()
    │
    └─ [serverConfigView === 'external']
           ├─ onSubmit
           │      ├─ setServerUrl(httpUrl) [検証付き]
           │      ├─ dispatch(signOut())
           │      └─ navigate('/')
           │
           ├─ onSkip
           │      ├─ setServerUrl(null)
           │      ├─ dispatch(loggedIn())
           │      └─ navigate('/')
           │
           └─ onSelectSelfSignedCertificate
                  └─ setServerSelfSignedCert(path)
```

### データフロー図

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

【内蔵サーバー】
ポート入力 ──────────────▶ ElectronServerConfig ─────────▶ state.electronServerPort
                              │
                              ▼
                    saveGlobalPrefs() ───────────────────▶ global_prefs更新
                              │
                              ▼
                    Actual.startSyncServer() ────────────▶ ローカルサーバー起動
                              │
                              ▼
                    setServerUrl() ──────────────────────▶ ServerContext更新
                              │
                              ▼
                       navigate('/') ────────────────────▶ ルート画面

【外部サーバー】
URL入力 ─────────────────▶ ConfigServer ─────────────────▶ state.url
                              │
                              ▼
                         setServerUrl()
                              │
                              ▼
                     [サーバー接続検証]
                              │
          ┌───────────────────┴───────────────────┐
          ▼                                       ▼
     [成功]                                   [失敗]
          │                                       │
          ├─ dispatch(signOut())              setError() ──▶ エラー表示
          └─ navigate('/') ──▶ ルート画面
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ConfigServer.tsx | `packages/desktop-client/src/components/manager/ConfigServer.tsx` | ソース | メインコンポーネント |
| ManagementApp.tsx | `packages/desktop-client/src/components/manager/ManagementApp.tsx` | ソース | ルーティング定義 |
| ServerContext.tsx | `packages/desktop-client/src/components/ServerContext.tsx` | ソース | サーバーURL管理 |
| prefsSlice.ts | `packages/desktop-client/src/prefs/prefsSlice.ts` | ソース | グローバルプリファレンス管理 |
| usersSlice.ts | `packages/desktop-client/src/users/usersSlice.ts` | ソース | signOut, loggedIn アクション |
| budgetfilesSlice.ts | `packages/desktop-client/src/budgetfiles/budgetfilesSlice.ts` | ソース | createBudget アクション |
