# 画面設計書 12-口座一覧画面（デスクトップ）

## 概要

本ドキュメントは、Actual Budgetアプリケーションにおけるデスクトップ向け口座一覧・口座別取引一覧画面の設計仕様を定義する。

### 本画面の処理概要

口座一覧画面（デスクトップ）は、全口座または特定口座の取引一覧を表示・管理するメイン画面である。取引の追加・編集・削除、フィルタリング、検索、銀行同期、インポート/エクスポート、消込（Reconcile）など、取引管理に必要なほぼすべての機能を提供する。

**業務上の目的・背景**：個人の財務管理において、口座の取引履歴を正確に把握することは最も基本的かつ重要な機能である。本画面は、ユーザーが日々の取引を記録・確認し、口座残高を管理するための中心的なインターフェースを提供する。銀行同期機能と連携することで、手動入力の手間を削減し、正確な財務状況の把握を可能にする。

**画面へのアクセス方法**：サイドバーの「口座」セクションから口座名をクリック、または「All Accounts」「On Budget」「Off Budget」をクリックしてアクセスする。URLパターンは `/accounts/:id` の形式である。

**主要な操作・処理内容**：
1. 取引一覧の表示（ページング、フィルタ、ソート対応）
2. 取引の追加・編集・削除
3. 取引のバッチ操作（一括編集、一括削除、複製）
4. 銀行同期（Bank Sync）の実行
5. 取引データのインポート（QIF/OFX/CSV等）
6. 取引データのCSVエクスポート
7. 口座の消込（Reconcile）処理
8. 取引のフィルタリング・検索
9. ルールの実行と作成
10. 分割取引の作成・解除
11. スケジュール取引のリンク・リンク解除

**画面遷移**：
- 遷移元：サイドバー、予算画面、他画面
- 遷移先：スケジュール編集モーダル、ルール編集モーダル、インポートモーダル

**権限による表示制御**：特になし。認証済みユーザーであれば全機能を利用可能。銀行同期機能はサーバー接続時のみ有効。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 5 | 口座作成・編集・削除 | 補助機能 | 口座の作成・編集・削除処理 |
| 6 | 口座残高管理 | 主機能 | 口座残高の表示・更新処理 |
| 9 | 取引追加・編集・削除 | 主機能 | 取引の追加・編集・削除処理 |
| 10 | 取引インポート | 補助機能 | 外部ファイルからの取引インポート処理 |
| 11 | 取引エクスポート | 補助機能 | 取引データのCSVエクスポート処理 |
| 12 | 分割取引（Split Transactions） | 補助機能 | 取引の分割処理 |
| 13 | 取引検索・フィルタ | 補助機能 | 取引の検索・フィルタリング処理 |
| 14 | 取引ルール | API連携 | ルールに基づく取引の自動カテゴリ分け |
| 29 | 銀行同期バッチ処理 | API連携 | 銀行同期による取引自動取得 |
| 65 | 元に戻す・やり直し（Undo/Redo） | 補助機能 | 取引操作の取り消し・やり直し |

## 画面種別

一覧 / 編集

## URL/ルーティング

- `/accounts` - 全口座取引一覧
- `/accounts/:id` - 特定口座取引一覧
- `/accounts/onbudget` - 予算内口座取引一覧
- `/accounts/offbudget` - 予算外口座取引一覧
- `/accounts/uncategorized` - 未分類取引一覧

## 入出力項目

| 項目名 | 項目ID | 入力/出力 | 型 | 必須 | 説明 |
|--------|--------|----------|-----|------|------|
| 口座ID | id | 入力（URL） | string | No | 表示対象口座のID |
| 検索キーワード | search | 入力 | string | No | 取引検索用キーワード |
| フィルタ条件 | filterConditions | 入力 | RuleConditionEntity[] | No | フィルタリング条件 |

## 表示項目

| 項目名 | 説明 | データソース |
|--------|------|-------------|
| 口座名 | 画面タイトルに表示される口座名 | accounts.name |
| 口座残高 | 口座の現在残高 | balanceQuery |
| クリア済残高 | クリア済取引の残高合計 | extraBalances |
| 未クリア残高 | 未クリア取引の残高合計 | extraBalances |
| 取引一覧 | 取引のテーブル | transactions |
| 取引件数 | フィルタ後の取引件数 | transactionCount |

### 取引テーブル列

| 列名 | 説明 | ソート可能 |
|------|------|-----------|
| Date | 取引日 | Yes |
| Account | 口座名（全口座表示時） | Yes |
| Payee | 支払先 | Yes |
| Notes | メモ | Yes |
| Category | カテゴリ | Yes |
| Payment | 支出金額 | Yes |
| Deposit | 収入金額 | Yes |
| Balance | 残高（表示設定時） | No |
| Cleared | クリア状態 | Yes |

## イベント仕様

### 1-取引追加（Add New）

「Add New」ボタン押下またはキーボードショートカット「T」で、新規取引入力行がテーブル上部に表示される。

### 2-銀行同期（Bank Sync）

「Bank Sync」ボタン押下またはCtrl+B/Cmd+Bで、口座の銀行同期を実行する。同期中はローディングアニメーションが表示される。

### 3-インポート（Import）

「Import」ボタン押下またはCtrl+I/Cmd+Iで、ファイル選択ダイアログが開き、QIF/OFX/QFX/CSV/TSV/XML形式のファイルをインポートできる。

### 4-検索

検索フィールドへの入力（Ctrl+F/Cmd+Fでフォーカス）で、150ms debounce後に取引検索が実行される。

### 5-フィルタ適用

「Filter」ボタンから条件を追加し、取引をフィルタリングする。複数条件をAND/ORで組み合わせ可能。

### 6-ソート

テーブルヘッダーをクリックすると、該当列でソートされる。再クリックで昇順/降順を切り替え。

### 7-消込（Reconcile）

消込ボタン（錠前アイコン）押下で消込メニューが開き、目標残高を入力して消込を開始する。

### 8-バッチ操作

複数取引選択後、バッチ操作メニューから一括編集、一括削除、複製、ルール作成等を実行できる。

### 9-口座メニュー

三点リーダーメニューから、残高表示切替、エクスポート、口座リンク/アンリンク、口座クローズ/再オープンを実行できる。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 取引追加 | transactions | INSERT | 新規取引レコードを作成 |
| 取引編集 | transactions | UPDATE | 既存取引レコードを更新 |
| 取引削除 | transactions | DELETE | 取引レコードを削除（tombstone） |
| 消込完了 | transactions | UPDATE | reconciled フラグを更新 |
| 消込完了 | accounts | UPDATE | last_reconciled を更新 |
| 銀行同期 | transactions | INSERT/UPDATE | 同期された取引を追加/更新 |
| バッチ編集 | transactions | UPDATE | 選択された取引を一括更新 |
| ルール実行 | transactions | UPDATE | ルール適用結果で取引を更新 |

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

#### transactions

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | id | uuidv4() | 新規UUID生成 |
| INSERT | account | 選択された口座ID | 必須 |
| INSERT | date | ユーザー入力または現在日 | YYYY-MM-DD形式 |
| INSERT | amount | ユーザー入力金額 | 整数（cents） |
| INSERT | payee | ユーザー選択 | PayeeのID |
| INSERT | category | ユーザー選択 | CategoryのID |
| INSERT | notes | ユーザー入力 | テキスト |
| INSERT | cleared | false | デフォルト値 |
| INSERT | reconciled | false | デフォルト値 |
| UPDATE | reconciled | true | 消込処理時 |

#### accounts

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | last_reconciled | 現在タイムスタンプ | 消込完了時 |
| UPDATE | name | ユーザー入力 | 口座名変更時 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|---------|
| M001 | 情報 | No transactions | 取引が存在しない場合 |
| M002 | 情報 | All Accounts | 全口座表示時のタイトル |
| M003 | 情報 | On Budget Accounts | 予算内口座表示時のタイトル |
| M004 | 情報 | Off Budget Accounts | 予算外口座表示時のタイトル |
| M005 | 情報 | Bank Sync Offline | サーバーオフライン時 |
| M006 | エラー | Failed to apply rules to transactions | ルール実行失敗時 |
| M007 | エラー | Formula errors in rules | ルール数式エラー時 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| 口座が存在しない | `/accounts` にリダイレクト |
| 口座が0件 | AccountEmptyMessageコンポーネントで口座追加を促す |
| 銀行同期エラー | エラー通知を表示 |
| ルール実行エラー | エラー通知を表示、処理続行 |
| インポートエラー | インポートモーダルでエラー表示 |

## 備考

- 取引データは150件単位でページング読み込み（pagedQuery）
- Undo/Redoはundo-eventをリッスンして対応
- 同期イベントでtransactions/category_mapping/payee_mappingテーブルに変更があった場合は自動リフレッシュ
- 口座切替時はsort/filter/searchがリセットされる
- モーダル表示から戻った際は100ms後に自動リフレッシュ

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | models/index.d.ts | `packages/loot-core/types/models/` | AccountEntity, TransactionEntityの型定義 |
| 1-2 | transactions.ts | `packages/loot-core/shared/transactions.ts` | 取引のグループ化/アングループ化ロジック |

**読解のコツ**: TransactionEntityのis_parent, parent_id, subtransactionsフィールドが分割取引の構造を決定する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Account.tsx | `packages/desktop-client/src/components/accounts/Account.tsx` | Accountコンポーネント（行1964-2047）でプロバイダとフックの設定 |

**主要処理フロー**:
1. **行1964-1966**: useParams, useLocationでURL情報取得
2. **行1968-2000**: 各種フック・設定の初期化
3. **行2007-2045**: SchedulesProvider, SplitsExpandedProvider, AccountHackでラップ

#### Step 3: 内部コンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | AccountInternal | 同上（行292-1922） | PureComponentによるステート管理と主要メソッド |

**主要処理フロー**:
- **行329-395**: componentDidMount - リスナー設定、取引フェッチ、Undo処理
- **行449-458**: fetchTransactions - クエリ構築と実行
- **行466-529**: updateQuery - pagedQueryの設定とデータ変換
- **行551-572**: onSearch - 検索処理（150ms debounce）
- **行686-745**: onRunRules - ルール実行処理
- **行991-1043**: onDoneReconciling - 消込完了処理

#### Step 4: ヘッダーコンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Header.tsx | `packages/desktop-client/src/components/accounts/Header.tsx` | AccountHeaderコンポーネント |

**主要処理フロー**:
- **行138-195**: props定義 - 多数のコールバック関数
- **行236-276**: キーボードショートカット設定（useHotkeys）
- **行278-589**: レンダリング - 残高、ボタン群、フィルタスタック

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

```
Account (エントリーポイント)
    |
    +-- SchedulesProvider (スケジュールコンテキスト)
    |
    +-- SplitsExpandedProvider (分割展開状態)
    |
    +-- AccountHack (フック接続)
            |
            +-- AccountInternal (メインロジック)
                    |
                    +-- AllTransactions (プレビュー取引統合)
                    |       +-- useAccountPreviewTransactions
                    |
                    +-- SelectedProviderWithItems (選択状態管理)
                    |
                    +-- AccountHeader
                    |       +-- Balances (残高表示)
                    |       +-- BalanceHistoryGraph (グラフ)
                    |       +-- Search (検索)
                    |       +-- FilterButton (フィルタ)
                    |       +-- SelectedTransactionsButton (バッチ操作)
                    |       +-- ReconcileMenu (消込)
                    |       +-- AccountMenu (口座メニュー)
                    |
                    +-- TransactionList (取引テーブル)
                            +-- 取引行レンダリング
                            +-- ソート・編集機能
```

### データフロー図

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

URL params        --->  Account                    --->  画面表示設定
(accountId)             (コンポーネント初期化)

accounts store    --->  useAccounts                --->  口座情報
                        (口座フック)

DB transactions   --->  pagedQuery                 --->  取引一覧
                        (150件ページング)                  (ungroupTransactions)

schedules DB      --->  useAccountPreviewTransactions --> プレビュー取引
                        (スケジュール取得)

User input        --->  onSearch (150ms debounce)  --->  フィルタ済取引
(search/filter)         onApplyFilter

User action       --->  send('transactions-batch-update') --> DB更新
(add/edit/delete)       (サーバー送信)

Bank Sync         --->  syncAndDownload            --->  同期取引
                        (API呼び出し)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Account.tsx | `packages/desktop-client/src/components/accounts/Account.tsx` | ソース | メインコンポーネント |
| Header.tsx | `packages/desktop-client/src/components/accounts/Header.tsx` | ソース | ヘッダーコンポーネント |
| Balance.tsx | `packages/desktop-client/src/components/accounts/Balance.tsx` | ソース | 残高表示 |
| Reconcile.tsx | `packages/desktop-client/src/components/accounts/Reconcile.tsx` | ソース | 消込機能 |
| TransactionList.tsx | `packages/desktop-client/src/components/transactions/TransactionList.tsx` | ソース | 取引テーブル |
| SelectedTransactionsButton.tsx | `packages/desktop-client/src/components/transactions/SelectedTransactionsButton.tsx` | ソース | バッチ操作ボタン |
| pagedQuery.ts | `packages/desktop-client/src/queries/pagedQuery.ts` | ソース | ページングクエリ |
| queries.ts | `packages/desktop-client/src/queries.ts` | ソース | 取引クエリ定義 |
| accountsSlice.ts | `packages/desktop-client/src/accounts/accountsSlice.ts` | ソース | 口座Redux |
| transactionsSlice.ts | `packages/desktop-client/src/transactions/transactionsSlice.ts` | ソース | 取引Redux |
