# 画面設計書 25-銀行同期管理画面（デスクトップ）

## 概要

本ドキュメントは、Actual Budgetアプリケーションにおけるデスクトップ向け銀行同期管理画面の設計仕様を定義するものである。

### 本画面の処理概要

銀行口座との同期設定を管理するための画面である。GoCardless、SimpleFIN、PluggyAI の3つの銀行同期プロバイダーに対応し、各口座の同期状態の確認、同期設定の編集、未リンク口座の連携設定を行うことができる。

**業務上の目的・背景**：家計管理において、銀行取引の手動入力は時間のかかる作業である。本画面は、銀行APIを通じた自動取引取得機能の設定・管理を提供することで、取引入力の自動化を実現する。複数の銀行同期プロバイダーに対応することで、様々な金融機関との連携を可能にし、ユーザーの利便性を最大化している。口座ごとに同期プロバイダーをグループ化して表示することで、管理のしやすさを向上させている。

**画面へのアクセス方法**：サイドバーの「Bank Sync」メニュー、またはコマンドバーから `/bank-sync` ルートに遷移することでアクセスする。デスクトップ版では `BankSync` コンポーネントが表示される。

**主要な操作・処理内容**：
1. 同期プロバイダー別の口座一覧表示
2. 各口座の同期状態確認
3. 同期設定の編集（モーダルダイアログ）
4. 未リンク口座の銀行連携設定
5. 口座名、銀行名、最終同期日時の表示

**画面遷移**：
- 遷移元：サイドバー、コマンドバー
- 遷移先：同期口座設定モーダル、口座追加モーダル

**権限による表示制御**：特別な権限制御は設けられていない。予算ファイルにアクセスできるユーザーであれば銀行同期管理が可能。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 26 | GoCardless連携 | 主機能 | GoCardless APIによる銀行連携設定 |
| 27 | SimpleFIN連携 | 主機能 | SimpleFINプロトコルによる銀行連携設定 |
| 28 | PluggyAI連携 | 主機能 | PluggyAI APIによる銀行連携設定 |
| 29 | 銀行同期バッチ処理 | 補助機能 | 複数口座の一括同期処理 |

## 画面種別

一覧

## URL/ルーティング

`/bank-sync`

- デスクトップ・モバイル両対応（レスポンシブ）
- デスクトップ版では `BankSync` コンポーネント
- モバイル版では `MobileBankSyncPage` コンポーネント

## 入出力項目

| 項目名 | 項目ID | データ型 | 入力/出力 | 必須 | 説明 |
|--------|--------|----------|-----------|------|------|
| なし | - | - | - | - | この画面は表示専用で入力項目なし |

## 表示項目

| 項目名 | データ型 | 説明 |
|--------|----------|------|
| ヘッダータイトル | string | "Bank Sync" と表示 |
| プロバイダー名 | string | GoCardless / SimpleFIN / Pluggy.ai / Unlinked |
| 口座ヘッダー | component | 口座一覧のカラムヘッダー |
| 口座一覧 | list | 口座名、銀行名、最終同期日時、アクションボタン |
| 空状態メッセージ | text | 口座がない場合のガイダンス |

## イベント仕様

### 1-画面初期表示

画面表示時に口座一覧を取得し、同期プロバイダー別にグループ化して表示する。

**処理フロー**:
1. `useAccounts()` フックで口座一覧を取得
2. クローズされた口座をフィルタアウト
3. `account_sync_source` フィールドで同期プロバイダー別にグループ化
4. プロバイダー名でソート（Unlinked は最後）
5. プロバイダー別に `AccountsHeader` と `AccountsList` をレンダリング

### 2-口座同期設定編集

口座行の編集ボタン押下時に同期設定モーダルを開く。

**処理フロー**:
1. `onAction(account, 'edit')` を呼び出し
2. `pushModal('synced-account-edit', { account })` でモーダルを表示
3. フィールドマッピング、取引方向、オプション設定を編集

### 3-未リンク口座の連携設定

未リンク口座の「Link」ボタン押下時に銀行連携設定を開始する。

**処理フロー**:
1. `onAction(account, 'link')` を呼び出し
2. `pushModal('add-account', { upgradingAccountId: account.id })` でモーダルを表示
3. 銀行同期プロバイダーの選択・認証フローを開始

### 4-口座ホバー

口座行にマウスホバーした際にホバー状態を表示する。

**処理フロー**:
1. `onHover(id)` でホバー中の口座IDを設定
2. `hoveredAccount` ステートを更新
3. 該当行のスタイルを変更

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| なし | - | - | この画面からの直接的なDB更新なし（モーダル経由） |

### テーブル別更新項目詳細

本画面は表示専用であり、データベース更新はモーダルダイアログ経由で行われる。

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| MSG-001 | ガイダンス | "To use the bank syncing features, you must first add an account." | 口座が存在しない場合 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| 口座が存在しない | ガイダンスメッセージを表示 |

## 備考

- 同期プロバイダーは `goCardless`, `simpleFin`, `pluggyai` の3種類
- `account_sync_source` が null の口座は「Unlinked」として表示
- クローズされた口座（`closed: true`）は表示対象外
- 実際の同期設定編集は `synced-account-edit` モーダルで行う
- 銀行連携の初期設定は `add-account` モーダルで行う

---

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

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

### 推奨読解順序

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

口座データと銀行同期プロバイダーの型定義を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | models/index.d.ts | `packages/loot-core/src/types/models/index.d.ts` | AccountEntity型、BankSyncProviders型の定義 |

**読解のコツ**: AccountEntityの `account_sync_source` フィールドが同期プロバイダーを示す。null の場合は未リンク。

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

画面コンポーネントの全体構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | banksync/index.tsx | `packages/desktop-client/src/components/banksync/index.tsx` | メインコンポーネント。グループ化ロジック、onAction処理 |

**主要処理フロー**:
1. **26-37行目**: useSyncSourceReadable関数（プロバイダー名の表示用変換）
2. **39-47行目**: コンポーネント定義とフック初期化
3. **49-51行目**: hoveredAccountステート
4. **53-79行目**: groupedAccounts計算（useMemo）
5. **81-108行目**: onAction関数（edit/link処理）
6. **110-112行目**: onHover関数
7. **114-152行目**: JSXレンダリング

#### Step 3: 口座一覧コンポーネントを理解する

口座の表示と操作UIを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | AccountsHeader.tsx | `packages/desktop-client/src/components/banksync/AccountsHeader.tsx` | ヘッダー行（unlinkedプロパティで表示切替） |
| 3-2 | AccountsList.tsx | `packages/desktop-client/src/components/banksync/AccountsList.tsx` | 口座一覧行のレンダリング |

#### Step 4: 同期設定モーダルを理解する

同期設定編集の詳細を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | useBankSyncAccountSettings.ts | `packages/desktop-client/src/components/banksync/useBankSyncAccountSettings.ts` | 設定の読み込み・保存フック |

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

```
BankSync
    │
    ├─ useAccounts()
    │      └─ Redux store から口座一覧取得
    │
    ├─ useSyncSourceReadable()
    │      └─ プロバイダー名の日本語化
    │
    ├─ groupedAccounts (useMemo)
    │      ├─ filter(a => !a.closed)
    │      ├─ reduce by account_sync_source
    │      └─ sort (unlinked は最後)
    │
    ├─ AccountsHeader
    │      └─ カラムヘッダー表示
    │
    ├─ AccountsList
    │      └─ 各口座行の表示
    │             ├─ 口座名
    │             ├─ 銀行名
    │             ├─ 最終同期日時
    │             └─ Edit/Link ボタン
    │
    └─ onAction()
           ├─ 'edit': pushModal('synced-account-edit')
           └─ 'link': pushModal('add-account')
```

### データフロー図

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

Redux Store ─────────▶ useAccounts() ────────────────────▶ accounts
(accounts)                 │
                           ▼
                     filter(closed)
                           │
                           ▼
                     groupBy(sync_source) ───────────────▶ groupedAccounts
                           │
                           ▼
                     sort(providers)
                           │
                           ▼
                     AccountsList
                           │
Edit ボタン ─────────▶ onAction('edit') ──────────────────▶ synced-account-edit モーダル
                           │
Link ボタン ─────────▶ onAction('link') ──────────────────▶ add-account モーダル
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.tsx | `packages/desktop-client/src/components/banksync/index.tsx` | ソース | メインコンポーネント |
| AccountsHeader.tsx | `packages/desktop-client/src/components/banksync/AccountsHeader.tsx` | ソース | ヘッダーコンポーネント |
| AccountsList.tsx | `packages/desktop-client/src/components/banksync/AccountsList.tsx` | ソース | 口座一覧コンポーネント |
| useBankSyncAccountSettings.ts | `packages/desktop-client/src/components/banksync/useBankSyncAccountSettings.ts` | ソース | 設定管理フック |
| BankSyncCheckboxOptions.tsx | `packages/desktop-client/src/components/banksync/BankSyncCheckboxOptions.tsx` | ソース | 同期オプションチェックボックス |
| FieldMapping.tsx | `packages/desktop-client/src/components/banksync/FieldMapping.tsx` | ソース | フィールドマッピング設定 |
| useAccounts.ts | `packages/desktop-client/src/hooks/useAccounts.ts` | ソース | 口座取得フック |
| Page.tsx | `packages/desktop-client/src/components/Page.tsx` | ソース | ページレイアウトコンポーネント |
| FinancesApp.tsx | `packages/desktop-client/src/components/FinancesApp.tsx` | ソース | ルーティング定義（299行目） |
| models/index.d.ts | `packages/loot-core/src/types/models/index.d.ts` | 型定義 | AccountEntity, BankSyncProviders型 |
