# 機能設計書 69-設定ファイル読み込み

## 概要

本ドキュメントは、Etherpadの設定ファイル読み込み機能の設計を記載する。この機能は、settings.jsonからアプリケーション設定を読み込み、環境変数による上書きにも対応する。

### 本機能の処理概要

設定ファイル読み込み機能は、Etherpadの起動時および動的再読み込み時にsettings.jsonから設定を読み込む機能である。JSONコメントの除去、環境変数の展開、設定値の型変換、および設定の検証を行う。

**業務上の目的・背景**：Etherpadは多くの設定オプションを持ち、デプロイ環境に応じた柔軟な設定が必要である。settings.jsonによるファイルベースの設定と、環境変数による上書き機能により、開発・本番環境の切り替えやコンテナ環境での運用が容易になる。

**機能の利用シーン**：
- Etherpadサーバー起動時
- 管理画面からサーバー再起動した時
- 設定ファイルを変更して反映させる時
- 環境変数で設定を上書きする時

**主要な処理内容**：
1. settings.jsonファイルの読み込み
2. JSONコメント（// や /* */）の除去
3. 環境変数プレースホルダー（${ENV_VAR}）の展開
4. 設定値の型変換（文字列→数値/ブール値）
5. 設定の検証と警告出力
6. デフォルト値のマージ

**関連システム・外部連携**：
- ファイルシステム（settings.json読み込み）
- 環境変数（設定上書き）
- log4js（ログ設定）

**権限による制御**：設定ファイルの読み込みはサーバープロセスの権限で行われる。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 8 | 設定管理画面 | 主機能 | settings.jsonから現在の設定を読み込み表示 |

## 機能種別

設定読み込み / ファイル操作

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| settingsFilename | string | No | 設定ファイルパス | デフォルト: settings.json |
| --settings | string | No | コマンドライン引数 | ファイルパス |

### 入力データソース

- settings.json（メイン設定ファイル）
- 環境変数（EP_で始まる設定）
- コマンドライン引数（--settings）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| settings | SettingsType | 設定オブジェクト |

### 出力先

- グローバル設定オブジェクト（settings）

## 処理フロー

### 処理シーケンス

```
1. 設定ファイルパスの決定
   └─ コマンドライン引数 > デフォルト(settings.json)
2. ファイル読み込み
   └─ fs.readFileSync()
3. JSONコメント除去
   └─ jsonminify()
4. JSON解析
   └─ JSON.parse()
5. 環境変数展開
   └─ lookupEnvironmentVariables()
6. 設定値のマージ
   └─ storeSettings()
7. 設定の検証
   └─ スキン名、DB設定、SSL設定等の検証
8. ログ設定の初期化
   └─ initLogging()
```

### フローチャート

```mermaid
flowchart TD
    A[reloadSettings呼び出し] --> B[parseSettings]
    B --> C[ファイル読み込み]
    C --> D{ファイル存在?}
    D -->|No| E[警告出力・デフォルト使用]
    D -->|Yes| F[jsonminify]
    F --> G[JSON.parse]
    G --> H[lookupEnvironmentVariables]
    H --> I[storeSettings]
    I --> J[設定検証]
    J --> K[ログ設定初期化]
    K --> L[スキン検証]
    L --> M[DB設定検証]
    M --> N[その他検証]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-69-01 | 環境変数展開 | ${ENV_VAR}形式でプレースホルダーを環境変数値に置換 | 設定値が文字列の場合 |
| BR-69-02 | デフォルト値指定 | ${ENV_VAR:default}形式でデフォルト値を指定可能 | 環境変数未設定の場合 |
| BR-69-03 | 型変換 | "true"/"false"は真偽値、数値文字列は数値に変換 | 環境変数展開時 |
| BR-69-04 | 設定名規則 | 設定名は小文字で始まる必要がある | 設定読み込み時 |
| BR-69-05 | EP_プレフィックス | EP_で始まる環境変数はツリー構造で設定に展開 | 環境変数処理時 |

### 計算ロジック

環境変数展開:
```typescript
const match = value.match(/^\$\{([^:]*)(:((.|\n)*))?\}$/);
if (match) {
  const envVarName = match[1];
  const envVarValue = process.env[envVarName];
  const defaultValue = match[3];
  // ...
}
```

型変換:
```typescript
const coerceValue = (stringValue: string) => {
  if (isNumeric(stringValue)) return +stringValue;
  switch (stringValue) {
    case 'true': return true;
    case 'false': return false;
    // ...
  }
}
```

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

本機能はデータベースを操作しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ファイル未検出 | settings.jsonが存在しない | 警告出力、デフォルト値使用 |
| - | JSON解析エラー | 無効なJSON形式 | エラー出力、プロセス終了 |
| - | 未知の設定 | 定義されていない設定名 | 警告出力、無視 |

### リトライ仕様

エラー時は自動リトライなし。

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

ファイル読み込みのため、トランザクション制御は不要。

## パフォーマンス要件

- 設定読み込み: 起動時に1回、または再起動時のみ

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

- 設定ファイルには機密情報（APIキー等）が含まれる可能性
- credentials.jsonで機密情報を分離管理可能
- 環境変数での上書きにより機密情報をファイルに残さない運用が可能

## 備考

- settings.json.templateがテンプレートとして提供されている
- 設定変更後はサーバー再起動が必要な項目がある

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Settings.ts | `src/node/utils/Settings.ts` | SettingsType型定義（159-296行目） |

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

#### Step 2: デフォルト値を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Settings.ts | `src/node/utils/Settings.ts` | settingsオブジェクト初期値（298-658行目） |

**主要処理フロー**:
- **298-658行目**: デフォルト設定値の定義
- **300行目**: rootパス（Etherpadルートディレクトリ）
- **301-302行目**: 設定ファイル・認証ファイルのパス決定

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Settings.ts | `src/node/utils/Settings.ts` | reloadSettings関数（940-1088行目） |
| 3-2 | Settings.ts | `src/node/utils/Settings.ts` | parseSettings関数（92-131行目） |

**主要処理フロー**:
- **940-944行目**: reloadSettings関数 - 設定と認証情報の解析
- **92-131行目**: parseSettings関数 - ファイル読み込みとJSON解析
- **118行目**: jsonminifyでコメント除去
- **124行目**: lookupEnvironmentVariablesで環境変数展開

#### Step 4: 環境変数展開を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Settings.ts | `src/node/utils/Settings.ts` | lookupEnvironmentVariables関数（815-936行目） |
| 4-2 | Settings.ts | `src/node/utils/Settings.ts` | coerceValue関数（754-777行目） |

**主要処理フロー**:
- **815-936行目**: lookupEnvironmentVariables関数 - 再帰的な環境変数展開
- **857行目**: ${ENV_VAR:default}パターンのマッチング
- **754-777行目**: coerceValue関数 - 型変換

#### Step 5: 設定検証処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | Settings.ts | `src/node/utils/Settings.ts` | reloadSettings内の検証処理（955-1088行目） |

**主要処理フロー**:
- **955-959行目**: skinName検証
- **961-964行目**: socketTransportProtocols検証
- **967-997行目**: スキンパス検証
- **999-1011行目**: abiword存在検証
- **1013-1026行目**: soffice存在検証

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

```
Etherpad起動 / 管理画面からの再起動
    │
    └─ reloadSettings()
           │
           ├─ parseSettings(settingsFilename, true)
           │      │
           │      ├─ fs.readFileSync()
           │      ├─ jsonminify()
           │      ├─ JSON.parse()
           │      └─ lookupEnvironmentVariables()
           │             │
           │             ├─ replaceEnvs() [再帰処理]
           │             ├─ coerceValue()
           │             └─ SettingsNode [EP_変数のツリー化]
           │
           ├─ parseSettings(credentialsFilename, false)
           │
           ├─ storeSettings(settingsParsed)
           │      └─ 各設定値のマージ
           │
           ├─ storeSettings(credentials)
           │
           ├─ initLogging(logconfig)
           │
           └─ 各種検証処理
```

### データフロー図

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

settings.json ───▶ parseSettings()
                         │
                         ▼
                  jsonminify()
                         │
                         ▼
                  JSON.parse()
                         │
                         ▼
           lookupEnvironmentVariables()
                         │
    ┌────────────────────┼────────────────────┐
    │                    │                    │
    ▼                    ▼                    ▼
環境変数         デフォルト値          型変換
    │                    │                    │
    └────────────────────┼────────────────────┘
                         │
                         ▼
               storeSettings()
                         │
                         ▼
                   settings ───▶ グローバル設定オブジェクト
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Settings.ts | `src/node/utils/Settings.ts` | ソース | 設定管理本体 |
| SettingsTree.ts | `src/node/utils/SettingsTree.ts` | ソース | EP_変数のツリー処理 |
| Cli.ts | `src/node/utils/Cli.ts` | ソース | コマンドライン引数解析 |
| AbsolutePaths.ts | `src/node/utils/AbsolutePaths.ts` | ソース | パス解決 |
| settings.json | ルートディレクトリ | 設定 | メイン設定ファイル |
| settings.json.template | ルートディレクトリ | テンプレート | 設定ファイルテンプレート |
