# 機能設計書 52-ファイルダイアログ

## 概要

本ドキュメントは、Actual Budgetデスクトップアプリケーションにおけるファイルダイアログ機能の設計を記述する。この機能は、Electronのネイティブダイアログを使用してファイルの選択・保存操作を提供する。

### 本機能の処理概要

Actual BudgetのElectronデスクトップアプリケーションにおいて、ユーザーがファイルを開く・保存するためのネイティブファイルダイアログを提供する機能である。CSVインポート、バックアップの保存・復元、エクスポート機能など、様々な場面で使用される。

**業務上の目的・背景**：ユーザーが外部ファイル（CSV、QIF、OFX等）から取引をインポートしたり、予算データをエクスポート・バックアップしたりする際に、OSネイティブのファイル選択ダイアログを使用することで、直感的で一貫したユーザー体験を提供する。

**機能の利用シーン**：
- 取引データのCSV/QIF/OFXインポート時
- 予算ファイルのエクスポート時
- バックアップファイルの保存・復元時
- YNAB4/YNAB5形式のインポート時

**主要な処理内容**：
1. ファイル選択ダイアログの表示（open-file-dialog）
2. ファイル保存ダイアログの表示と内容の書き込み（save-file-dialog）
3. フィルタ条件（拡張子）の適用
4. 選択結果のレンダラープロセスへの返却

**関連システム・外部連携**：OSのネイティブファイルシステムとの連携。Electron APIを介してOSのファイルダイアログを呼び出す。

**権限による制御**：OSレベルでのファイルアクセス権限に依存。アプリケーション内での権限制御はない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 7 | ウェルカム画面 | 参照画面 | インポート用ファイル選択 |
| 40 | 設定画面 | 参照画面 | バックアップの保存・復元、エクスポート |
| 12 | 口座一覧画面（デスクトップ） | 参照画面 | 取引インポート/エクスポート |

## 機能種別

ファイル操作 / ダイアログ表示

## 入力仕様

### 入力パラメータ（ファイル選択ダイアログ）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| properties | OpenDialogSyncOptions['properties'] | No | ダイアログのプロパティ（openFile, openDirectory等） | - |
| filters | OpenDialogSyncOptions['filters'] | No | ファイルフィルタ（拡張子指定） | - |

### 入力パラメータ（ファイル保存ダイアログ）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| title | string | No | ダイアログのタイトル | - |
| defaultPath | string | No | デフォルトのファイル名/パス | - |
| fileContents | string \| Buffer | Yes | 保存するファイル内容 | - |

### 入力データソース

レンダラープロセスからのIPC呼び出し

## 出力仕様

### 出力データ（ファイル選択ダイアログ）

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | string[] \| undefined | 選択されたファイルパスの配列 |

### 出力データ（ファイル保存ダイアログ）

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | void | 成功時はvoid、エラー時は例外 |

### 出力先

- レンダラープロセスへのIPC応答
- ファイルシステム（保存ダイアログの場合）

## 処理フロー

### 処理シーケンス（ファイル選択）

```
1. open-file-dialog IPCイベント受信
   └─ ipcMain.handleでの処理

2. パラメータの展開
   └─ filters, propertiesの取得

3. ネイティブダイアログの表示
   └─ dialog.showOpenDialogSync呼び出し

4. 結果の返却
   └─ 選択されたファイルパス配列を返却
```

### 処理シーケンス（ファイル保存）

```
1. save-file-dialog IPCイベント受信
   └─ ipcMain.handleでの処理

2. パラメータの展開
   └─ title, defaultPath, fileContentsの取得

3. 保存ダイアログの表示
   └─ dialog.showSaveDialog呼び出し

4. ファイルの書き込み
   └─ fs.writeFile実行

5. 完了通知
   └─ Promise解決
```

### フローチャート

```mermaid
flowchart TD
    subgraph 選択ダイアログ
        A1[open-file-dialog IPC受信] --> B1[パラメータ展開]
        B1 --> C1[showOpenDialogSync呼び出し]
        C1 --> D1[ファイルパス配列を返却]
    end

    subgraph 保存ダイアログ
        A2[save-file-dialog IPC受信] --> B2[パラメータ展開]
        B2 --> C2[showSaveDialog呼び出し]
        C2 --> D2{ファイル選択?}
        D2 -->|Yes| E2[fileContentsを変換]
        E2 --> F2[fs.writeFile実行]
        F2 --> G2{書き込み成功?}
        G2 -->|Yes| H2[Promise解決]
        G2 -->|No| I2[エラーreject]
        D2 -->|No| H2
    end
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-52-1 | 同期ダイアログ | ファイル選択はshowOpenDialogSyncで同期的に実行 | ファイル選択時 |
| BR-52-2 | 非同期保存 | ファイル保存はshowSaveDialogで非同期実行 | ファイル保存時 |
| BR-52-3 | デフォルトプロパティ | propertiesが未指定の場合は['openFile']を使用 | ファイル選択時 |
| BR-52-4 | バイナリ変換 | Buffer型のfileContentsはUint8Arrayに変換して書き込み | ファイル保存時 |

### 計算ロジック

特になし

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

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

この機能はデータベース操作を行わない。ファイルシステム操作のみ。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ファイル書き込みエラー | 書き込み権限なし、ディスク容量不足等 | Promiseをrejectしエラーを伝播 |
| - | キャンセル | ユーザーがダイアログをキャンセル | undefinedまたは空で正常終了 |

### リトライ仕様

リトライは実装されていない。エラー時はユーザーに再操作を促す。

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

トランザクション処理なし（ファイルシステム操作のみ）

## パフォーマンス要件

- ダイアログ表示時間：OS依存
- ファイル書き込み時間：ファイルサイズ依存

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

- ファイルアクセスはOSの権限に従う
- ユーザーが明示的に選択したファイルのみアクセス可能
- サンドボックス外のファイルアクセスは制限される

## 備考

- Electron dialogモジュールを使用
- 同期/非同期APIの使い分けに注意

---

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

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

### 推奨読解順序

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

IPCイベントのペイロード型を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | index.ts | `packages/desktop-electron/index.ts` | 561-564行目：OpenFileDialogPayload型定義 |
| 1-2 | index.ts | `packages/desktop-electron/index.ts` | 576-580行目：SaveFileDialogPayload型定義 |

**読解のコツ**: Electron APIのOpenDialogSyncOptionsとSaveDialogOptionsの型を理解しておくと、パラメータの意味が把握しやすい。

#### Step 2: ファイル選択ダイアログを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.ts | `packages/desktop-electron/index.ts` | 566-574行目：open-file-dialog IPCハンドラ |

**主要処理フロー**:
1. **568行目**: filtersとpropertiesをパラメータから取得
2. **569行目**: dialog.showOpenDialogSync呼び出し
3. **570行目**: propertiesのデフォルト値設定
4. **571行目**: filtersの適用

#### Step 3: ファイル保存ダイアログを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.ts | `packages/desktop-electron/index.ts` | 582-603行目：save-file-dialog IPCハンドラ |

**主要処理フロー**:
- **586行目**: title, defaultPath, fileContentsをパラメータから取得
- **588行目**: dialog.showSaveDialogで非同期ダイアログ表示
- **590-591行目**: ファイル選択された場合の処理開始
- **592-595行目**: fileContentsの型に応じた変換処理
- **596行目**: fs.writeFileでファイル書き込み

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

```
ipcMain.handle('open-file-dialog')
    │
    └─ dialog.showOpenDialogSync()
           │
           └─ OSネイティブファイルダイアログ

ipcMain.handle('save-file-dialog')
    │
    ├─ dialog.showSaveDialog()
    │      │
    │      └─ OSネイティブ保存ダイアログ
    │
    └─ fs.writeFile()
           │
           └─ ファイルシステム
```

### データフロー図

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

レンダラープロセス ───▶ IPCイベント ───▶ Electronダイアログ
     │                                        │
     │                                        ▼
     │                              ユーザー操作（選択/保存）
     │                                        │
     ◀────────────────────────────────────────┘
     選択結果/完了通知

                                   [副作用]
                                      │
                                      ▼
                              ファイルシステム書き込み
                              （保存ダイアログのみ）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.ts | `packages/desktop-electron/index.ts` | ソース | ファイルダイアログIPCハンドラ実装 |
| preload.js | `packages/desktop-electron/preload.js` | ソース | IPC通信のブリッジ |
| Export.tsx | `packages/desktop-client/src/components/settings/Export.tsx` | ソース | エクスポート時のダイアログ呼び出し元 |
