# 通知設計書 8-スキーマファイルパス保存成功

## 概要

本ドキュメントは、Liamアプリケーションにおけるスキーマファイルパス保存成功時のUI通知（トースト）の設計仕様を定義する。ブランチ詳細画面でスキーマファイルのパスと形式を設定し、正常に保存された場合に表示される成功通知について、表示仕様、トリガー条件、処理フローを詳細に記載する。

### 本通知の処理概要

スキーマファイルパス保存成功通知は、ブランチ詳細画面でスキーマファイルのパスとフォーマットを設定し、保存処理が正常に完了した際に表示されるトースト通知である。

**業務上の目的・背景**：スキーマファイルパスの設定は、ERD（Entity Relationship Diagram）の自動生成やスキーマ解析の基盤となる重要な設定である。設定が正常に保存されたことをユーザーに明確にフィードバックすることで、次のステップ（スキーマ解析やERD表示）にスムーズに進めることを保証する。

**通知の送信タイミング**：ブランチ詳細画面のスキーマファイルパス設定フォームで、パスを入力しフォーマットを選択して「Save」ボタンを押下した後、サーバーアクション`saveSchemaFilePath`が正常に完了した時点で表示される。

**通知の受信者**：スキーマファイルパス設定操作を実行したユーザー本人。現在表示しているブランチ詳細画面上でトースト通知が表示される。

**通知内容の概要**：「Saved」というタイトルと「Schema file path saved successfully」という説明文が、成功（success）ステータスのトースト通知として表示される。

**期待されるアクション**：ユーザーはスキーマファイルパスの保存が完了したことを確認し、スキーマ解析やERD表示などの次のステップに進む。

## 通知種別

UI通知（トースト）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（サーバーアクション完了後に即座に表示） |
| 優先度 | 中 |
| リトライ | なし（UI表示のため不要） |

### 送信先決定ロジック

スキーマファイルパス設定操作を実行したユーザーの現在のページ上でトースト通知を表示する。

## 通知テンプレート

### UI通知の場合

| 項目 | 内容 |
|-----|------|
| タイトル | Saved |
| 説明文 | Schema file path saved successfully |
| ステータス | success |
| 表示位置 | header（ヘッダー下部） |

### 本文テンプレート

```
タイトル: Saved
説明: Schema file path saved successfully
```

### 添付ファイル

| ファイル名 | 形式 | 条件 | 説明 |
|----------|------|------|------|
| なし | - | - | UI通知のため添付ファイルなし |

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| なし | - | - | 固定文言のため変数なし（descriptionはサーバーアクションのmessageを使用） |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 画面操作 | スキーマファイルパス保存ボタン押下 | saveSchemaFilePathが成功 | state.successがtrueかつstate.messageが存在 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| 保存失敗時 | state.errorが存在する場合は表示しない（エラートースト表示） |
| 初期状態 | state.successがfalseまたはstate.messageがnullの場合は表示しない |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[ユーザーがSaveボタン押下] --> B[saveSchemaFilePath実行]
    B --> C[フォームデータバリデーション]
    C -->|バリデーション成功| D[組織ID取得]
    C -->|バリデーション失敗| E[エラーレスポンス返却]
    D -->|成功| F[schema_file_pathsテーブルUPSERT]
    D -->|失敗| E
    F -->|成功| G[成功レスポンス返却]
    F -->|失敗| E
    G --> H[state更新 success=true, message=...]
    E --> I[state更新 error=メッセージ]
    H --> J[useEffect検知]
    I --> K[useEffect検知]
    J --> L[成功トースト表示]
    K --> M[エラートースト表示]
    L --> N[終了]
    M --> N
```

## データベース参照・更新仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| なし | - | 直接参照なし（組織IDはセッションから取得） |

### テーブル別参照項目詳細

該当なし。

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| schema_file_paths | UPSERT | スキーマファイルパス情報の保存/更新 |

#### schema_file_paths

| 操作 | 項目（カラム名） | 更新値 | 備考 |
|-----|-----------------|-------|------|
| UPSERT | project_id | フォームから取得 | onConflict: 'project_id' |
| UPSERT | path | フォームから取得（トリム処理済み） | 必須 |
| UPSERT | format | フォームから取得 | schemarb/postgres/prisma/tbls |
| UPSERT | organization_id | セッションから取得 | 必須 |
| UPSERT | updated_at | 現在時刻 | ISO文字列形式 |

#### 送信ログテーブル

| 操作 | 項目（カラム名） | 更新値 | 備考 |
|-----|-----------------|-------|------|
| - | - | - | UI通知のため送信ログなし |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| なし | - | 成功通知のためエラーケースなし |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | なし（UI表示のため制限不要） |
| 1日あたり上限 | なし |

### 配信時間帯

特に制限なし。ユーザー操作に応じて即座に表示される。

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

- スキーマファイルパスの保存は認可されたユーザーのみ実行可能
- フォームデータはサーバーサイドでvalibotによりバリデーション
- パスはトリム処理され、不正な空白を除去
- 組織IDはセッションから取得し、不正なアクセスを防止

## 備考

- React 19のuseActionStateフックを使用してフォームの状態管理を実装
- useEffectでstateの変更を監視し、success時にトーストを表示
- UPSERT操作により、既存のパスがあれば更新、なければ新規作成
- revalidatePathでページキャッシュを無効化し、最新データを反映

---

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

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

### 推奨読解順序

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

まず、サーバーアクションの入力スキーマと状態型を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | saveSchemaFilePath.ts | `frontend/apps/app/components/BranchDetailPage/actions/saveSchemaFilePath.ts` | schemaFilePathSchema（8-12行目）で入力バリデーション、戻り値の型（16-23行目）を理解する |

**読解のコツ**: valibotのpicklistでフォーマット種別を限定している点に注目。

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

処理の起点となるUIコンポーネントを特定。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | SchemaFilePathForm.tsx | `frontend/apps/app/components/BranchDetailPage/components/SchemaFilePathForm/SchemaFilePathForm.tsx` | useActionState（27-31行目）とuseEffect（33-47行目）でフォーム状態管理とトースト表示を理解する |

**主要処理フロー**:
1. **27-31行目**: useActionStateでsaveSchemaFilePathをラップ
2. **33-47行目**: useEffectでstateを監視
3. **34-39行目**: state.success && state.message時に成功トースト表示
4. **40-45行目**: state.error時にエラートースト表示

#### Step 3: サーバーアクションを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | saveSchemaFilePath.ts | `frontend/apps/app/components/BranchDetailPage/actions/saveSchemaFilePath.ts` | バリデーション（30-37行目）、組織ID取得（41-48行目）、UPSERT処理（54-68行目）を理解する |

**主要処理フロー**:
- **30-37行目**: valibotでフォームデータをバリデーション
- **41-48行目**: getOrganizationIdで組織ID取得
- **57-68行目**: Supabaseでschema_file_pathsテーブルにUPSERT
- **78-82行目**: 成功レスポンス返却

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

```
SchemaFilePathForm.tsx
    │
    ├─ useActionState(saveSchemaFilePath)
    │      │
    │      └─ action (formに渡す)
    │
    └─ useEffect([state])
           │
           ├─ [success時] toast({ title: 'Saved', ... })
           │
           └─ [error時] toast({ title: 'Error', ... })

saveSchemaFilePath
    │
    ├─ v.safeParse() [Validation]
    │
    ├─ getOrganizationId()
    │
    ├─ supabase.from('schema_file_paths').upsert()
    │
    └─ revalidatePath()
```

### データフロー図

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

フォーム送信             ───▶ saveSchemaFilePath          ───▶ state更新
(projectId, path,             │                               │
 format)                      │                               ▼
                              ├─▶ バリデーション          useEffect検知
                              │                               │
                              ├─▶ 組織ID取得              トースト表示
                              │                           (成功/失敗)
                              └─▶ DB UPSERT
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| SchemaFilePathForm.tsx | `frontend/apps/app/components/BranchDetailPage/components/SchemaFilePathForm/SchemaFilePathForm.tsx` | ソース | スキーマパス設定UI・フォーム管理 |
| saveSchemaFilePath.ts | `frontend/apps/app/components/BranchDetailPage/actions/saveSchemaFilePath.ts` | ソース | スキーマパス保存サーバーアクション |
| FormatSelectDropdown.tsx | `frontend/apps/app/features/sessions/components/shared/FormatSelectDropdown/FormatSelectDropdown.tsx` | ソース | フォーマット選択ドロップダウン |
| Toast.tsx | `frontend/packages/ui/src/components/Toast/Toast.tsx` | ソース | トースト通知UIコンポーネント |
| useToast.tsx | `frontend/packages/ui/src/components/Toast/useToast.tsx` | ソース | トーストフック |
