# 機能設計書 8-オフバジェット口座

## 概要

本ドキュメントは、Actual Budget における予算に含めない口座（投資口座など）の管理機能の設計を記述する。

### 本機能の処理概要

**業務上の目的・背景**：すべての口座が予算管理の対象になるわけではない。投資口座、退職金口座、住宅ローンなど、日常の予算管理とは別に追跡したい口座がある。本機能は、これらの口座を「オフバジェット」として管理し、予算計算から除外しながらも総資産の把握には含めることを可能にする。

**機能の利用シーン**：
- 投資口座（証券口座）を追跡するが予算には含めない
- 住宅ローン口座を負債として追跡する
- 退職金口座を資産として追跡する
- 車のローンを負債として管理する

**主要な処理内容**：
1. 口座のオフバジェット設定
2. オフバジェット口座の取引管理
3. 純資産計算へのオフバジェット口座の包含
4. オフバジェット口座の一覧表示

**関連システム・外部連携**：口座管理機能、レポート機能（純資産）

**権限による制御**：特別な権限制御なし

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 12 | 口座一覧画面（デスクトップ） | 主画面 | オフバジェット口座の管理 |
| 13 | 口座一覧画面（モバイル） | 主画面 | モバイルでのオフバジェット口座管理 |

## 機能種別

設定変更 / フラグ管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| id | string | Yes | 口座ID | 存在する口座ID |
| offbudget | boolean | Yes | オフバジェットフラグ | true/false |

### 入力データソース

- 画面入力：口座作成時のオプション、口座編集
- API経由：account の offbudget フィールド

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| offbudget | boolean | オフバジェット状態 |

### 出力先

- データベース：accounts テーブルの offbudget フラグ
- 画面表示：サイドバーで別グループに表示

## 処理フロー

### 処理シーケンス

```
1. 口座作成/編集時にオフバジェットを設定
   └─ offbudget: true/false を指定

2. api/account-create または api/account-update
   └─ offbudget フラグを保存

3. 口座一覧表示
   └─ オンバジェット口座とオフバジェット口座を別グループで表示

4. 取引作成時
   └─ オフバジェット口座の取引はカテゴリなし（null）
   └─ 予算計算から除外

5. 純資産計算
   └─ オフバジェット口座も含めて総資産を計算
```

### フローチャート

```mermaid
flowchart TD
    A[口座設定] --> B{offbudget?}
    B -->|Yes| C[オフバジェット口座として保存]
    B -->|No| D[オンバジェット口座として保存]
    C --> E[サイドバーでオフバジェットグループに表示]
    D --> F[サイドバーでオンバジェットグループに表示]
    E --> G[取引はカテゴリなし]
    F --> H[取引はカテゴリ必須]
    G --> I[純資産に含む]
    H --> J[予算計算に含む]
    J --> I
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | カテゴリ不要 | オフバジェット口座の取引はカテゴリ指定不要 | offbudget = true |
| BR-002 | 予算除外 | オフバジェット口座は予算計算から除外 | offbudget = true |
| BR-003 | 純資産包含 | オフバジェット口座は純資産計算に含む | 常時 |
| BR-004 | 別グループ表示 | サイドバーで別グループに表示 | 常時 |

### 計算ロジック

```
// 純資産計算
netWorth = SUM(onBudgetAccounts.balance) + SUM(offBudgetAccounts.balance)

// 予算計算（オンバジェットのみ）
budgetBalance = SUM(onBudgetAccounts.balance)

// オフバジェット取引のカテゴリ
if (account.offbudget) {
  transaction.category = null
}
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 設定変更 | accounts | UPDATE | offbudget フラグを更新 |

### テーブル別操作詳細

#### accounts

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | offbudget | 0/1 | オフバジェットフラグ |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ACCOUNT_NOT_FOUND | データ不整合 | 存在しない口座ID | エラーを返す |

### リトライ仕様

- 同期エラー時は自動リトライ

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

- 単一レコード更新のためトランザクション不要

## パフォーマンス要件

- 設定変更は即座に反映

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

- 特別なセキュリティ考慮なし

## 備考

- YNAB4インポート時に onBudget フラグを offbudget に変換

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | api-models.ts | `packages/loot-core/src/server/api-models.ts` | APIAccountEntity の offbudget フィールド |

#### Step 2: API層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | methods.ts | `packages/api/methods.ts` | createAccount, updateAccount での offbudget 設定 |

**主要処理フロー**:
- **172-177行目**: `createAccount` で offbudget を含む account オブジェクトを渡す

#### Step 3: インポート時の変換を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ynab4.ts | `packages/loot-core/src/server/importers/ynab4.ts` | onBudget から offbudget への変換 |

**主要処理フロー**:
- **31行目**: `offbudget: account.onBudget ? false : true` で変換

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

```
口座作成/編集
    │
    ├─ createAccount({ ..., offbudget: true/false })
    │      │
    │      └─ api/account-create
    │             │
    │             └─ accounts INSERT (offbudget = 0/1)
    │
    └─ updateAccount(id, { offbudget: true/false })
           │
           └─ api/account-update
                  │
                  └─ accounts UPDATE (offbudget = 0/1)

サイドバー表示
    │
    └─ accounts 取得
           │
           ├─ offbudget = 0 → オンバジェットグループ
           └─ offbudget = 1 → オフバジェットグループ
```

### データフロー図

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

offbudget設定     ───▶   createAccount /
(true/false)             updateAccount           ───▶  accounts.offbudget
                              │
                              ▼
                         サイドバー表示          ───▶  グループ分け
                              │
                              ▼
                         取引作成時              ───▶  category = null (if offbudget)
                              │
                              ▼
                         純資産計算              ───▶  全口座含む
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| methods.ts | `packages/api/methods.ts` | ソース | 口座API（offbudget パラメータ） |
| ynab4.ts | `packages/loot-core/src/server/importers/ynab4.ts` | ソース | YNAB4インポート時の変換 |
| AccountsPage.tsx | `packages/desktop-client/src/components/mobile/accounts/AccountsPage.tsx` | ソース | モバイル口座一覧 |
| OffBudgetAccountTransactions.tsx | `packages/desktop-client/src/components/mobile/accounts/OffBudgetAccountTransactions.tsx` | ソース | オフバジェット取引 |
| OnBudgetAccountTransactions.tsx | `packages/desktop-client/src/components/mobile/accounts/OnBudgetAccountTransactions.tsx` | ソース | オンバジェット取引 |
