# 機能設計書 68-シークレット一覧取得

## 概要

本ドキュメントは、Giselleシステムにおける「シークレット一覧取得」機能の設計仕様を定義する。

### 本機能の処理概要

シークレット一覧取得機能は、指定されたワークスペースに関連付けられたシークレットの一覧を取得する機能である。オプションでタグによるフィルタリングも可能。

**業務上の目的・背景**：ワークフローの設定や実行時に、利用可能なシークレットを確認する必要がある。本機能により、ユーザーはワークスペースに登録されているシークレットの一覧を確認し、適切なシークレットを選択できる。

**機能の利用シーン**：
- APIキー管理画面でのシークレット一覧表示
- ワークフローエディタでのシークレット選択ドロップダウン
- シークレットの管理・削除操作の前提となる一覧取得

**主要な処理内容**：
1. 入力としてWorkspaceIdとオプションでタグを受け取る
2. ワークスペースシークレットインデックスからデータを取得
3. タグが指定されている場合はフィルタリング
4. SecretIndexの配列を返却

**関連システム・外部連携**：
- `@giselles-ai/storage`パッケージによるストレージ抽象化レイヤー

**権限による制御**：本機能自体には認証・認可チェックは含まれない。呼び出し元のAPIレイヤーにて適切な認可制御が行われることを前提とする。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 29 | APIキー管理画面 | 主機能 | チームのAPIキー一覧の取得 |

## 機能種別

データ取得（READ）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| context | `GiselleContext` | Yes | Giselleコンテキスト | - |
| workspaceId | `WorkspaceId` | Yes | シークレットを取得するワークスペースID | `wks_`プレフィックスで始まる文字列 |
| tags | `string[]` | No | フィルタリング用タグ | - |

### 入力データソース

- APIリクエストのパラメータとして受け取る
- ワークスペースIDはセッションコンテキストから取得

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| (戻り値) | `SecretIndex[]` | シークレットインデックスの配列 |

各SecretIndexには以下が含まれる：

| 項目名 | 型 | 説明 |
|--------|-----|------|
| id | `SecretId` | シークレットID |
| label | `string` | シークレットの表示名 |
| createdAt | `number` | 作成日時（ミリ秒タイムスタンプ） |
| workspaceId | `WorkspaceId` | （オプション）関連ワークスペースID |
| tags | `string[]` | （オプション）分類タグ |

注意：セキュリティ上の理由から、シークレットの値（value）はインデックスには含まれない。

### 出力先

- 呼び出し元への戻り値として返却

## 処理フロー

### 処理シーケンス

```
1. インデックスパス生成
   └─ workspaceSecretIndexPath関数でsecrets/byWorkspace/{workspaceId}.jsonパスを生成

2. インデックスデータ取得
   └─ getWorkspaceIndex()でインデックスを取得
   └─ インデックスが存在しない場合は空配列を返却

3. タグフィルタリング（オプション）
   └─ tagsが指定されている場合、すべてのタグを持つシークレットのみに絞り込み

4. 結果返却
   └─ SecretIndex配列を返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[workspaceSecretIndexPathでパス生成]
    B --> C[getWorkspaceIndexでインデックス取得]
    C --> D{tags指定あり?}
    D -->|Yes| E[tagsでフィルタリング]
    D -->|No| F[そのまま返却]
    E --> G{すべてのtagを含む?}
    G -->|Yes| H[結果に含める]
    G -->|No| I[結果から除外]
    H --> F
    I --> F
    F --> J[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-68-01 | インデックス不在時 | インデックスが存在しない場合は空配列を返却 | 常時 |
| BR-68-02 | タグフィルタ | 指定されたすべてのタグを持つシークレットのみを返却 | tags指定時 |
| BR-68-03 | AND条件 | タグフィルタリングはAND条件で適用される | tags指定時 |
| BR-68-04 | 値非公開 | シークレットの値（value）はインデックスに含まれない | 常時 |

### 計算ロジック

タグフィルタリングロジック：
```typescript
secrets.filter((secret) => {
  const secretTags = secret.tags ?? [];
  return tags?.every((tag) => secretTags.includes(tag));
});
```

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

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

本機能はBlobストレージのみを使用し、リレーショナルデータベースへの直接アクセスは行わない。

| 操作 | 対象ストレージ | 操作種別 | 概要 |
|-----|-------------|---------|------|
| インデックス取得 | Blob Storage | GET | ワークスペースシークレットインデックスを取得 |

### ストレージ操作詳細

#### Blobストレージ

| 操作 | パス | データ形式 | 備考 |
|-----|------|----------|------|
| GET | secrets/byWorkspace/{workspaceId}.json | JSON | SecretIndex配列 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | (なし) | インデックスが存在しない | 空配列を返却（エラーではない） |
| - | StorageError | ストレージからの取得失敗 | ストレージ接続を確認 |

### リトライ仕様

ストレージアクセス失敗時のリトライは、ストレージドライバ層で実装される。アプリケーション層でのリトライは行わない。

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

読み取り専用操作のため、トランザクション管理は不要。

## パフォーマンス要件

- レスポンス時間: 100ms以内（ストレージレイテンシを含む）
- 同時リクエスト: ストレージの制限に依存

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

- 認証・認可: API呼び出し元で実装（本機能では未実装）
- データ保護: シークレットの値（value）はインデックスに含まれないため、一覧取得時に機密情報が漏洩しない

## 備考

- インデックスにはシークレットの値（暗号化されたvalue）は含まれない
- 値が必要な場合は別途シークレット取得APIを使用

---

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

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

### 推奨読解順序

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

まず、シークレット関連の型定義を理解することが重要である。

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

**読解のコツ**:
- **19-26行目**: SecretIndexはSecretからid, label, createdAt, workspaceId, tagsをpick
- valueは含まれないことに注目

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

処理の起点となるファイル・関数を特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | get-workspace-secrets.ts | `packages/giselle/src/secrets/get-workspace-secrets.ts` | getWorkspaceSecrets関数の実装 |

**主要処理フロー**:
1. **6-10行目**: 関数シグネチャと引数定義
2. **11行目**: 引数の分割代入
3. **12-16行目**: getWorkspaceIndexでインデックスを取得
4. **18-20行目**: tagsが未指定または空の場合、そのまま返却
5. **22-25行目**: tagsでフィルタリング（すべてのタグを持つもののみ）

#### Step 3: ユーティリティ関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | paths.ts | `packages/giselle/src/secrets/paths.ts` | workspaceSecretIndexPathの定義 |
| 3-2 | workspace-index.ts | `packages/giselle/src/utils/workspace-index.ts` | getWorkspaceIndexの実装 |

**主要処理フロー**:
- **7-9行目（paths.ts）**: `secrets/byWorkspace/{workspaceId}.json`パスを生成
- **32-49行目（workspace-index.ts）**:
  - インデックスの存在確認
  - 存在しない場合は空配列を返却
  - 存在する場合はJSONを取得して返却

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

```
Giselle.getWorkspaceSecrets (giselle.ts:327-331)
    │
    └─ getWorkspaceSecrets (get-workspace-secrets.ts:6-26)
           │
           ├─ workspaceSecretIndexPath(workspaceId) (paths.ts:7-9)
           │
           ├─ getWorkspaceIndex({context, indexPath, itemSchema})
           │      │       (workspace-index.ts:32-49)
           │      │
           │      ├─ context.storage.exists(indexPath)
           │      │
           │      └─ context.storage.getJson({path, schema})
           │
           └─ filter by tags (if specified)
```

### データフロー図

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

WorkspaceId ───▶ workspaceSecretIndexPath() ───▶ Index Path
                        │                    "secrets/byWorkspace/..."
                        ▼
                 getWorkspaceIndex()
                        │
                        ▼
                 SecretIndex[] (all secrets)
                        │
tags? ─────────────────┼───▶ filter()
                        │    (AND condition for all tags)
                        ▼
                 SecretIndex[] (filtered)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| get-workspace-secrets.ts | `packages/giselle/src/secrets/get-workspace-secrets.ts` | ソース | メイン処理の実装 |
| index.ts | `packages/protocol/src/secret/index.ts` | ソース | SecretIndex型定義 |
| paths.ts | `packages/giselle/src/secrets/paths.ts` | ソース | パス生成ユーティリティ |
| workspace-index.ts | `packages/giselle/src/utils/workspace-index.ts` | ソース | インデックス取得ユーティリティ |
| giselle.ts | `packages/giselle/src/giselle.ts` | ソース | Giselleクラスのエントリーポイント |
