# 機能設計書 29-銀行同期バッチ処理

## 概要

本ドキュメントは、Actual Budget における銀行同期バッチ処理機能の設計仕様を記述する。この機能は、複数の口座に対して銀行同期を一括実行し、取引データをまとめて取得することを目的とする。

### 本機能の処理概要

銀行同期バッチ処理機能は、GoCardless、SimpleFIN、PluggyAIなどのサードパーティサービスを通じて、連携された銀行口座から取引データを一括取得する。単一口座または全口座を対象に同期を実行し、取得した取引をActualの台帳に登録する。

**業務上の目的・背景**：複数の銀行口座を管理している場合、個別に同期を実行するのは非効率である。バッチ処理により、ワンクリックで全口座の取引を更新でき、日常の家計管理が効率化される。

**機能の利用シーン**：
- 毎日の取引確認時に全口座を一括同期
- 特定の口座のみを選択して同期
- スケジュール実行による自動同期

**主要な処理内容**：
1. 同期対象口座の特定：指定されたaccountIdまたは全連携口座
2. サービス別に取引取得：GoCardless/SimpleFIN/PluggyAIから取引データ取得
3. 取引のインポート：取得した取引をActualの取引として登録
4. 結果の返却：同期結果（成功/エラー）を返却

**関連システム・外部連携**：
- GoCardless連携（No.26）
- SimpleFIN連携（No.27）
- PluggyAI連携（No.28）
- 取引管理機能（No.9）

**権限による制御**：予算ファイルにアクセスできるユーザーが実行可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 12 | 口座一覧画面（デスクトップ） | API連携 | 銀行同期による取引自動取得 |
| 25 | 銀行同期管理画面（デスクトップ） | 補助機能 | 複数口座の一括同期処理 |
| 27 | 銀行同期口座編集画面（モバイル） | 主機能 | モバイルでの同期口座設定編集 |

## 機能種別

バッチ処理 / データ連携

## 入力仕様

### 入力パラメータ

#### runBankSync

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| accountId | string | No | 同期対象の口座ID | UUID形式、省略時は全口座 |

### 入力データソース

- ローカルDB（accounts、account_bankテーブル）
- サードパーティサービス（GoCardless、SimpleFIN、PluggyAI）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| status | string | 処理結果（ok/error） |
| accounts | object[] | 各口座の同期結果 |

### 出力先

- クライアント：同期結果通知
- ローカルDB：取得した取引の登録

## 処理フロー

### 処理シーケンス

```
1. 同期対象の特定
   └─ accountIdが指定されていれば単一口座
   └─ 指定されていなければ銀行連携設定のある全口座

2. 各口座の同期
   └─ 口座の連携サービスを判定（GoCardless/SimpleFIN/PluggyAI）
   └─ 対応するサービスAPIで取引を取得
   └─ 取引をActualの形式に変換
   └─ 取引をインポート

3. 結果の集約
   └─ 各口座の成功/エラー状態を集約
   └─ 結果をクライアントに返却
```

### フローチャート

```mermaid
flowchart TD
    A[runBankSync呼び出し] --> B{accountId指定?}
    B -->|Yes| C[単一口座取得]
    B -->|No| D[全連携口座取得]
    C --> E[同期対象リスト]
    D --> E
    E --> F[各口座をループ]
    F --> G{連携サービス?}
    G -->|GoCardless| H[GoCardless API]
    G -->|SimpleFIN| I[SimpleFIN API]
    G -->|PluggyAI| J[PluggyAI API]
    H --> K[取引取得]
    I --> K
    J --> K
    K --> L[取引変換・インポート]
    L --> M{次の口座?}
    M -->|Yes| F
    M -->|No| N[結果集約]
    N --> O[レスポンス返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-29-1 | 連携口座のみ対象 | 銀行連携が設定されている口座のみ同期対象 | 全口座同期時 |
| BR-29-2 | 個別エラー継続 | 1口座のエラーは他口座の同期に影響しない | 複数口座同期時 |
| BR-29-3 | 重複取引スキップ | 既存の取引IDと一致する取引はスキップ | 取引インポート時 |

### 計算ロジック

同期期間の決定:
- 通常は前回同期日から現在日まで
- 初回は設定された期間（例：過去90日）

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 口座取得 | accounts | SELECT | 同期対象口座の取得 |
| 連携情報取得 | account_bank | SELECT | 銀行連携設定の取得 |
| 取引インポート | transactions | INSERT | 取得した取引の登録 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| NO_ACCOUNTS | 処理スキップ | 同期対象口座なし | 口座を連携設定 |
| SERVICE_ERROR | サービスエラー | サードパーティAPIエラー | 各サービスのエラー処理に従う |

### リトライ仕様

- 個別口座のエラーは記録し、他口座の処理を継続
- サービス全体のエラー時はエラーメッセージを返却

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

- 各口座の取引インポートは個別トランザクション
- 1口座のロールバックは他口座に影響しない

## パフォーマンス要件

- 1口座あたり：サードパーティAPIの応答時間に依存（通常10秒以内）
- 全口座同期：口座数に比例

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

- APIキー等はサーバー側で管理
- ユーザー認証済みセッションでのみ実行可能

## 備考

- 各サードパーティサービスのレート制限に注意
- 大量の取引がある場合、インポートに時間がかかる場合がある

---

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

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

### 推奨読解順序

#### Step 1: API定義を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | methods.ts | `packages/api/methods.ts` | runBankSync API定義 |

**読解のコツ**:
- **61-65行目**: `runBankSync`関数
  - accountIdはオプション（省略時は全口座）
  - `send('api/bank-sync', args)`でハンドラを呼び出し

#### Step 2: ハンドラ実装を理解する

バックエンドの同期処理実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | api-handlers.ts | `packages/loot-core/src/server/`（推測） | api/bank-syncハンドラ |

**読解のコツ**:
- accountIdの有無で単一/全口座を分岐
- 各口座の連携サービスに応じたAPI呼び出し

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

```
Client
    │
    └─ runBankSync({ accountId? })
            │
            └─ send('api/bank-sync', args)
                    │
                    └─ Bank Sync Handler
                            │
                            ├─ 口座一覧取得
                            │       │
                            │       └─ SELECT * FROM accounts WHERE ...
                            │
                            └─ 各口座の同期
                                    │
                                    ├─ GoCardless連携口座
                                    │       └─ POST /gocardless/transactions
                                    │
                                    ├─ SimpleFIN連携口座
                                    │       └─ POST /simplefin/transactions
                                    │
                                    └─ PluggyAI連携口座
                                            └─ POST /pluggyai/transactions
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| methods.ts | `packages/api/methods.ts` | ソース | runBankSync API定義 |
| app-gocardless.js | `packages/sync-server/src/app-gocardless/app-gocardless.js` | ソース | GoCardless取引取得 |
| app-simplefin.js | `packages/sync-server/src/app-simplefin/app-simplefin.js` | ソース | SimpleFIN取引取得 |
| app-pluggyai.js | `packages/sync-server/src/app-pluggyai/app-pluggyai.js` | ソース | PluggyAI取引取得 |
