# 機能設計書 62-設定管理

## 概要

本ドキュメントは、Etherpadの設定管理機能の設計を記載する。この機能により、管理者はWebインターフェースを通じてsettings.jsonの内容を表示・編集し、サーバーを再起動することができる。

### 本機能の処理概要

設定管理機能は、Etherpadの動作を制御するsettings.jsonファイルをブラウザから直接編集できるようにする機能である。管理者は設定ファイルを変更し、変更を保存し、必要に応じてサーバーを再起動してその変更を適用することができる。

**業務上の目的・背景**：Etherpadの設定はsettings.jsonファイルで管理されており、通常はサーバーにSSHアクセスして編集する必要がある。この機能により、管理者はブラウザからリモートで設定変更が可能となり、運用効率が大幅に向上する。また、設定ミスのリスクを軽減するためのJSON構文チェック機能も提供される。

**機能の利用シーン**：
- データベース接続設定を変更する場合
- 認証・認可設定を調整する場合
- パッドのデフォルト設定を変更する場合
- プラグイン固有の設定を調整する場合
- パフォーマンス関連の設定を最適化する場合

**主要な処理内容**：
1. Socket.IOを通じて設定ファイルの読み込み
2. テキストエリアでの設定ファイル編集
3. JSON構文の検証
4. 設定ファイルの保存
5. サーバー再起動トリガー

**関連システム・外部連携**：
- ファイルシステム（settings.json読み書き）
- プラグインシステム（restartServerフック）

**権限による制御**：管理者権限（is_admin: true）を持つユーザーのみが設定管理機能にアクセスできる。また、showSettingsInAdminPage設定がfalseの場合は設定表示が無効化される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 8 | 設定管理画面 | 主画面 | settings.jsonの内容を表示・編集・保存 |

## 機能種別

CRUD操作 / ファイル操作

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| settings | string | Yes | 編集された設定ファイルの内容 | 有効なJSON形式 |

### 入力データソース

- 管理画面のテキストエリアからの入力
- 管理者セッション情報

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| results | string | 設定ファイルの内容またはNOT_ALLOWED |
| saveprogress | string | 保存完了通知（"saved"） |

### 出力先

- Socket.IOによるクライアントへのリアルタイム送信
- settings.json（ファイル書き込み）

## 処理フロー

### 処理シーケンス

```
1. クライアントがSocket.IOで/settingsに接続
   └─ 管理者権限の確認（is_admin: true）
2. 設定読み込みリクエスト（load）
   └─ settings.settingsFilenameからファイル読み込み
   └─ showSettingsInAdminPageをチェック
3. 設定ファイル内容をクライアントに送信
   └─ settings イベントで送信
4. 設定保存リクエスト（saveSettings）
   └─ クライアント側でJSON構文チェック
   └─ ファイルに書き込み
   └─ saveprogress: 'saved' を送信
5. サーバー再起動リクエスト（restartServer）
   └─ reloadSettings() 実行
   └─ plugins.update() 実行
   └─ loadSettings フック呼び出し
   └─ restartServer フック呼び出し
```

### フローチャート

```mermaid
flowchart TD
    A[Socket.IO接続] --> B{管理者権限?}
    B -->|No| C[接続拒否]
    B -->|Yes| D[load リクエスト]
    D --> E{showSettingsInAdminPage?}
    E -->|No| F[NOT_ALLOWED返却]
    E -->|Yes| G[ファイル読み込み]
    G --> H[設定内容送信]
    H --> I[編集待機]
    I --> J{ユーザー操作}
    J -->|保存| K[saveSettings]
    J -->|再起動| L[restartServer]
    K --> M[ファイル書き込み]
    M --> N[保存完了通知]
    L --> O[reloadSettings]
    O --> P[plugins.update]
    P --> Q[フック呼び出し]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-62-01 | 設定表示制御 | showSettingsInAdminPageがfalseの場合は設定表示不可 | 設定読み込み時 |
| BR-62-02 | JSON構文チェック | 保存前にクライアント側でJSON構文を検証 | 保存時 |
| BR-62-03 | コメント除去 | 表示時にJSONコメントを除去して表示 | 設定表示時 |

### 計算ロジック

クライアント側JSON検証:
```typescript
const isJSONClean = (settings: string): boolean => {
  try {
    JSON.parse(settings);
    return true;
  } catch (e) {
    return false;
  }
}
```

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

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

本機能はデータベースを直接操作しない。ファイルシステム操作のみ。

| 操作 | 対象ファイル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 読み込み | settings.json | READ | 設定ファイル内容の取得 |
| 保存 | settings.json | WRITE | 設定ファイル内容の更新 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 読み込みエラー | settings.jsonが存在しないまたは読み取り不可 | エラーログ出力 |
| - | 書き込みエラー | ファイル書き込み権限がない | エラーログ出力 |
| - | JSON構文エラー | 無効なJSON形式 | クライアント側でエラー表示 |

### リトライ仕様

ファイル操作のエラー時は自動リトライなし。

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

ファイルシステム操作のため、トランザクション制御は行わない。書き込み中のクラッシュでファイルが破損する可能性がある。

## パフォーマンス要件

- 設定読み込み: 1秒以内
- 設定保存: 1秒以内
- サーバー再起動: 設定内容による

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

- 管理者認証必須（is_admin: true）
- showSettingsInAdminPageでアクセス制御可能
- 設定ファイルには機密情報（APIキー等）が含まれる可能性があるため注意
- credentials.jsonは本機能では編集不可

## 備考

- 設定変更後はサーバー再起動が必要な場合がある
- settings.jsonにはコメントを記載可能（jsonminifyで除去）
- 環境変数による設定上書きは本機能の対象外

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Settings.ts | `src/node/utils/Settings.ts` | SettingsType型定義で設定項目を確認 |
| 1-2 | store.ts | `admin/src/store/store.ts` | フロントエンドの状態管理を確認 |

**読解のコツ**: SettingsTypeの各プロパティがsettings.jsonの設定項目に対応する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | adminsettings.ts | `src/node/hooks/express/adminsettings.ts` | Socket.IOハンドラの実装 |

**主要処理フロー**:
1. **21-22行目**: Socket.IO名前空間`/settings`でのリスナー登録
2. **24-25行目**: 管理者権限チェック
3. **27-40行目**: loadハンドラ - 設定ファイル読み込み
4. **42-49行目**: saveSettingsハンドラ - 設定ファイル保存
5. **307-313行目**: restartServerハンドラ - サーバー再起動

#### Step 3: フロントエンド実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | SettingsPage.tsx | `admin/src/pages/SettingsPage.tsx` | 設定編集UIの実装 |
| 3-2 | utils.ts | `admin/src/utils/utils.ts` | JSON検証・コメント除去関数 |

**主要処理フロー**:
- **SettingsPage.tsx 18-33行目**: 保存ボタンクリック時のJSON検証と送信
- **SettingsPage.tsx 35-38行目**: 再起動ボタンクリック時の処理

#### Step 4: 設定読み込み処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Settings.ts | `src/node/utils/Settings.ts` | reloadSettings関数の実装 |

**主要処理フロー**:
- **940-1088行目**: reloadSettings関数 - 設定ファイル再読み込みと検証

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

```
SettingsPage.tsx (フロントエンド)
    │
    ├─ settingsSocket.emit('load')
    │      │
    │      └─ adminsettings.ts: socket.on('load')
    │             └─ fsp.readFile(settings.settingsFilename)
    │             └─ socket.emit('settings', {results: data})
    │
    ├─ settingsSocket.emit('saveSettings', settings)
    │      │
    │      └─ adminsettings.ts: socket.on('saveSettings')
    │             └─ fsp.writeFile(settings.settingsFilename)
    │             └─ socket.emit('saveprogress', 'saved')
    │
    └─ settingsSocket.emit('restartServer')
           │
           └─ adminsettings.ts: socket.on('restartServer')
                  └─ reloadSettings()
                  └─ plugins.update()
                  └─ hooks.aCallAll('loadSettings')
                  └─ hooks.aCallAll('restartServer')
```

### データフロー図

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

管理者操作 ───▶ Socket.IO ───▶ adminsettings.ts
     │                              │
     │                              ▼
     │                      ファイルシステム
     │                     ┌───────────────┐
     │                     │ settings.json │
     │                     └───────────────┘
     │                              │
     │                              ▼
     │                      Settings.ts
     │                     reloadSettings()
     │                              │
     └─────────────────────────────▶ クライアント画面
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| adminsettings.ts | `src/node/hooks/express/adminsettings.ts` | ソース | Socket.IOハンドラ |
| Settings.ts | `src/node/utils/Settings.ts` | ソース | 設定管理モジュール |
| SettingsPage.tsx | `admin/src/pages/SettingsPage.tsx` | ソース | フロントエンドUI |
| utils.ts | `admin/src/utils/utils.ts` | ソース | ユーティリティ関数 |
| store.ts | `admin/src/store/store.ts` | ソース | Zustand状態管理 |
| settings.json | ルートディレクトリ | 設定 | メイン設定ファイル |
| settings.json.template | ルートディレクトリ | テンプレート | 設定ファイルテンプレート |
