# 機能設計書 72-データストア更新

## 概要

本ドキュメントは、Giselleワークフローシステムにおけるデータストア更新機能の設計を記述する。この機能は、既存のデータストア（外部PostgreSQLデータベース接続）の設定情報を更新する。

### 本機能の処理概要

**業務上の目的・背景**：ワークフロー運用中にデータストアの接続設定を変更する必要が生じる場合がある。例えば、接続先データベースの認証情報の更新、タイムアウト設定の変更、スキーマの変更などである。この機能は、既存のデータストア設定を安全に更新し、ワークフローの継続的な運用を支援する。

**機能の利用シーン**：データストア設定画面において、既存の接続設定を変更する際に利用される。具体的には、接続文字列の更新、オプション設定の変更、プロバイダ固有パラメータの調整などの場面で使用される。

**主要な処理内容**：
1. 入力されたデータストアIDからストレージパスを生成
2. ストレージ上にデータストア設定ファイルが存在するか確認（存在しない場合はエラー）
3. 既存の設定を読み込み、新しい設定とマージ
4. マージ結果をプロバイダスキーマでバリデーション
5. バリデーション済みの設定をストレージに保存
6. 更新後のDataStoreオブジェクトを返却

**関連システム・外部連携**：
- GiselleStorageを介したファイルストレージとの連携
- @giselles-ai/data-store-registryによるプロバイダ固有スキーマのバリデーション

**権限による制御**：本機能自体には直接的な権限チェックは含まれないが、呼び出し元のAPI層でワークスペースへのアクセス権限および編集権限が確認される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 33 | データストア設定画面 | 主機能 | データストア設定の更新処理 |

## 機能種別

データ更新処理（Update操作）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| context | GiselleContext | Yes | Giselleの実行コンテキスト | - |
| dataStoreId | DataStoreId | Yes | 更新対象のデータストアID | `ds-`プレフィックス形式の文字列 |
| configuration | DataStore["configuration"] | Yes | 更新する設定内容（部分更新可） | プロバイダスキーマに適合すること |

### 入力データソース

- 画面（データストア設定画面）からの入力
- ストレージ（GiselleStorage）から既存設定を読み込み

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| DataStore | DataStore | 更新後のデータストア設定オブジェクト |
| DataStore.id | DataStoreId | データストアの一意識別子（変更なし） |
| DataStore.provider | DataStoreProvider | プロバイダ種別（変更なし） |
| DataStore.configuration | Record<string, unknown> | 更新後のプロバイダ固有設定 |

### 出力先

- ストレージ（GiselleStorage）に `data-stores/{dataStoreId}/data-store.json` として保存
- 呼び出し元関数への戻り値として返却

## 処理フロー

### 処理シーケンス

```
1. ストレージパス生成
   └─ dataStorePath(dataStoreId)を呼び出し

2. ファイル存在確認
   └─ context.storage.exists(path)で対象ファイルの存在をチェック

3. 存在しない場合の処理
   └─ Error("DataStore not found: {dataStoreId}")をスロー

4. 既存設定の読み込み
   └─ context.storage.getJson({path, schema: DataStore})

5. 設定のマージ
   └─ 既存のconfigurationに新しいconfigurationをスプレッド構文でマージ

6. プロバイダスキーマでバリデーション
   └─ parseConfiguration(provider, mergedConfiguration)

7. DataStoreオブジェクトの構築
   └─ 既存オブジェクトにバリデーション済み設定を適用

8. ストレージへの保存
   └─ context.storage.setJson({path, data, schema: DataStore})

9. 更新後オブジェクトの返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[ストレージパス生成]
    B --> C{ファイル存在確認}
    C -->|存在しない| D[Error: DataStore not found]
    C -->|存在する| E[既存設定読み込み]
    E --> F[設定マージ]
    F --> G[プロバイダスキーマでバリデーション]
    G --> H[DataStoreオブジェクト構築]
    H --> I[ストレージへ保存]
    I --> J[更新後オブジェクト返却]
    D --> K[終了]
    J --> K
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 存在必須 | 更新対象のデータストアが存在しない場合はエラーとする | 常時 |
| BR-02 | 部分更新 | configurationは部分更新をサポートし、既存設定とマージする | 常時 |
| BR-03 | プロバイダ不変 | プロバイダ種別は更新不可（既存値を維持） | 常時 |
| BR-04 | スキーマ検証 | マージ後の設定はプロバイダ固有スキーマで検証される | 常時 |

### 計算ロジック

設定マージロジック：
```typescript
const mergedConfiguration = {
    ...existingDataStore.configuration,
    ...configuration,  // 新しい値で上書き
};
```

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

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

本機能はデータベースを直接操作しない。ストレージ（ファイルシステムまたはオブジェクトストレージ）への読み書きを行う。

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

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

該当なし（ストレージファイルアクセスのみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | DataStore not found | 指定されたデータストアIDが存在しない | 正しいIDを指定 |
| - | バリデーションエラー | 設定がプロバイダスキーマに適合しない | 設定値を確認・修正 |
| - | ストレージ書き込みエラー | ストレージへの保存に失敗 | ストレージ設定・権限を確認 |

### リトライ仕様

本関数自体にはリトライロジックは含まれない。ストレージアクセスエラーの場合は呼び出し元でのリトライを検討。

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

本機能はファイルストレージを使用するため、データベースレベルのトランザクション管理は行わない。読み込み→書き込みの間に競合が発生する可能性があるが、現在の設計ではオプティミスティックロックは実装されていない。

## パフォーマンス要件

- 単一JSONファイルの読み込み・書き込みのため、通常200ms以内に完了すること
- プロバイダスキーマのバリデーションは同期処理で高速に完了すること

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

- 接続文字列のシークレットIDを更新する場合、新しいシークレットが適切に暗号化されていることを前提とする
- 本機能は設定メタデータの更新のみを行い、実際の接続文字列は別途シークレット管理機能で管理される
- 呼び出し元でワークスペースへの編集権限確認が必要

## 備考

- 部分更新をサポートするため、変更したいフィールドのみを指定可能
- プロバイダ種別を変更する場合は、削除→再作成のフローを使用する必要がある

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | index.ts | `packages/protocol/src/data-store/index.ts` | DataStore型定義 |

**読解のコツ**: configurationフィールドが`Record<string, unknown>`として定義されており、プロバイダ固有の設定を柔軟に保持できる構造になっている点を理解する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | update-data-store.ts | `packages/giselle/src/data-stores/update-data-store.ts` | メイン関数の全体構造 |

**主要処理フロー**:
1. **6-14行目**: 関数シグネチャ - context、dataStoreId、configurationを受け取る
2. **15行目**: dataStorePath関数でストレージパスを生成
3. **17-19行目**: ファイル存在確認、存在しない場合はErrorをスロー
4. **22-25行目**: 既存設定の読み込み
5. **28-31行目**: 既存設定と新設定のマージ
6. **32-35行目**: parseConfigurationでプロバイダスキーマバリデーション
7. **37-40行目**: DataStoreオブジェクトの構築
8. **42-46行目**: ストレージへの保存
9. **48行目**: 更新後オブジェクトの返却

#### Step 3: プロバイダ設定のバリデーションを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | data-store-registry | `packages/data-store-registry/src/index.ts` | parseConfiguration関数 |

**読解のコツ**: プロバイダごとに異なるスキーマが定義されており、parseConfigurationがプロバイダ種別に応じた適切なバリデーションを実行する。

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

```
updateDataStore()
    │
    ├─ dataStorePath(dataStoreId)
    │      └─ パス文字列を生成
    │
    ├─ context.storage.exists(path)
    │      └─ ファイル存在確認
    │
    ├─ context.storage.getJson({path, schema})
    │      └─ 既存設定読み込み
    │
    ├─ parseConfiguration(provider, mergedConfig)
    │      └─ プロバイダスキーマでバリデーション
    │
    └─ context.storage.setJson({path, data, schema})
           └─ 更新後設定の保存
```

### データフロー図

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

dataStoreId ────────▶ dataStorePath() ────────▶ ストレージパス
                                                        │
                                                        ▼
                                          context.storage.exists()
                                                        │
                                          ┌─────────────┴─────────────┐
                                          │                           │
                                     [存在しない]                 [存在する]
                                          │                           │
                                          ▼                           ▼
                                     Error thrown      context.storage.getJson()
                                                                      │
configuration ──────────────────────────────────────▶ マージ処理 ◀────┘
                                                            │
                                                            ▼
                                          parseConfiguration(provider, merged)
                                                            │
                                                            ▼
                                          context.storage.setJson() ───▶ ストレージ
                                                            │
                                                            ▼
                                                   DataStoreオブジェクト
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| update-data-store.ts | `packages/giselle/src/data-stores/update-data-store.ts` | ソース | メイン関数 |
| paths.ts | `packages/giselle/src/data-stores/paths.ts` | ソース | ストレージパス生成 |
| index.ts | `packages/protocol/src/data-store/index.ts` | ソース | DataStore型定義 |
| index.ts | `packages/data-store-registry/src/index.ts` | ソース | parseConfiguration関数 |
