• #tax-assistant
  • #database
  • #api
  • #vue
  • #codex-review
開発tax-assistantメモ

勘定科目マスターDB化の実装記録

概要

tax-assistantプロジェクトで、勘定科目をDBで管理する機能を実装した。これまでフロントエンドにハードコードしていた勘定科目一覧を、マネーフォワード会計のCSVエクスポートからインポートできるようにした。

実装の背景

以前の実装では勘定科目の選択肢がフロントエンドに固定で埋め込まれていた。クライアントごとに使う勘定科目は異なるし、同じ勘定科目でも税区分が違うケースもある。運用を続けていく上でDB管理は必須だった。

Phase 1: DBスキーマ作成

account_categoriesテーブル

CREATE TABLE IF NOT EXISTS account_categories (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL,
    sub_account TEXT,
    tax_type TEXT NOT NULL,
    category_type TEXT NOT NULL,
    mf_category TEXT,
    display_order INTEGER DEFAULT 0,
    is_active INTEGER DEFAULT 1,
    created_at TEXT DEFAULT CURRENT_TIMESTAMP,
    updated_at TEXT DEFAULT CURRENT_TIMESTAMP,
    UNIQUE(name, sub_account, tax_type)
);

設計のポイント

UNIQUE制約を (name, sub_account, tax_type) の3カラムに設定した理由

当初は (name, sub_account) で一意にしようとした。しかし実務では「会議費・課税10%」と「会議費・非課税」を両方使うケースがある。同じ勘定科目名・補助科目でも税区分違いで複数登録できないと困る。

Codexレビューで「税区分の違いで同名科目を分ける運用は想定していますか?」と聞かれて気づいた。

category_typeの分類

pl_expense   ... 損益計算書・費用
pl_revenue   ... 損益計算書・収益
bs_asset     ... 貸借対照表・資産
bs_liability ... 貸借対照表・負債
bs_equity    ... 貸借対照表・純資産(その他)

個人事業主の場合、「純資産」より「その他」と呼んだほうが実態に近い。事業主貸・事業主借などが入る。

mf_categoryカラム

マネーフォワードの「分類」(現金及び預金、売上債権、有価証券...)をそのまま保持する。UIのミラーカラムで中項目として使うため。

CSVインポート元

C:\Users\numbe\Git_repo\tax-assistant\apps\ledger-viewer\data\indiv_items_download_ex01.csv

マネーフォワード会計からエクスポートしたサンプル美容室の勘定科目マスター。カラム構造は以下の通り。

カラム内容
決算書科目貸借対照表 or 損益計算書
分類現金及び預金、売上債権など
勘定科目勘定科目名
補助科目補助科目名(空の場合あり)
税区分課税10%、非課税など
並び順表示順(1か空が多い)

display_orderの扱い

元CSVの「並び順」は1か空ばかりで連番になっていなかった。CSVの行順(読み込み順)をそのままdisplay_orderとして使用。これで「現金」から始まる自然な並び順になる。

Phase 2: API実装

エンドポイント

メソッドパス用途
GET/api/account-categories/dropdownドロップダウン選択用一覧
GET/api/account-categories/{id}詳細取得
DELETE/api/account-categories/{id}物理削除

ドロップダウン用APIはフィルタ・ソートに対応。?category_type=pl_expense のようにカテゴリで絞り込める。

削除の方針

当初は論理削除(is_active=0)で設計していた。しかし実装中に「無効科目も表示」のチェックボックスが必要になり、UIが複雑になる。

結局、無効科目は取り込まない方針に変更。削除は物理削除とした。マスターデータは再インポートすれば復元できるので問題ない。

Phase 3: MatrixView.vueの改修

月次推移表でPL科目とBS科目を表示している。これまではハードコードで分類していたが、APIから取得した勘定科目マスターのcategory_typeで動的に分類するよう変更。

// 勘定科目マスターを取得
const { data: accountCategories } = await useFetch('/api/account-categories/dropdown')

// category_typeでPL/BS分類
const plCategories = computed(() =>
  accountCategories.value?.filter(c =>
    c.category_type === 'pl_expense' || c.category_type === 'pl_revenue'
  ) ?? []
)

Phase 4: WebUI実装

ミラーカラムスタイルのレイアウト

4カラム構成を採用。

カラム内容
1列目大分類(BS / PL)
2列目中分類(資産/負債/その他 or 収益/費用)
3列目小分類(MFの分類をそのまま使用)
4列目勘定科目一覧

勘定科目一覧の表示形式

マネーフォワードのUIを参考に、同じ勘定科目名をグループ化して縦に連結表示。補助科目がある場合はL字型の連結線で接続。

┌──────────────────────────────────────────┐
│ 勘定科目    税区分      補助科目    削除 │
├──────────────────────────────────────────┤
│ 普通預金    対象外      -           🗑    │
│     └──────────────── みずほ銀行   🗑    │
│     └──────────────── 住信SBI     🗑    │
│ 売掛金      課税10%     -           🗑    │
└──────────────────────────────────────────┘

キーボードナビゲーション

←→キーで小分類を順番に巡回できる。「1/23」のような位置表示付きのナビゲーションバーも実装。

/import-accounting-master スラッシュコマンド

Claude Codeから直接インポートを実行できるスラッシュコマンドを作成。

# 使用例
/import-accounting-master

実行すると、指定のCSVファイルを読み込んでaccount_categoriesテーブルにUPSERT。既存データは上書きされる。

Codexレビュー12回の経緯

計画段階でCodex(GPT-5.2)にレビューを依頼した。12回のレビューを経て計画品質を向上させた。

主な指摘と対応

CriticalHigh主な指摘
102入出金の管理方法、WebUIでの設定変更可否
312テナントスコープがない(個人用アプリなので不要と回答)
93-tax_typeをNOT NULLに、初期投入をPhase 1に
1200Critical/High解消

印象的だった指摘

「税区分の違いで同名科目を分ける運用は想定していますか?」

これはCodexの確認質問だったが、実務では普通にある。会議費で課税10%と非課税を使い分けるケースなど。UNIQUE制約を (name, sub_account, tax_type) に変更するきっかけになった。

「direction(入金/出金)と必須勘定科目の整合性をAPIバリデーションで担保すべき」

帳票タイプマスター(別計画)との連携で、入金時と出金時でデフォルト勘定科目が異なる。Pydanticのバリデーションでこれを担保する設計を追加。

実装で修正したファイル

ファイル内容
sql/account_categories.sqlテーブル定義
src/migrations.pyマイグレーション追加
src/db/account_categories.pyDB操作関数
src/server/routers/account_categories.pyAPIルーター
scripts/import_account_master.pyCSVインポートスクリプト
.claude/commands/import-accounting-master.mdスラッシュコマンド
frontend/app/api.tsAPI型定義追加
frontend/app/components/MatrixView.vue動的分類対応
frontend/app/components/AccountMasterView.vueマスター管理UI
tests/test_account_categories.pyユニットテスト

テスト

CSVインポートのユニットテストとAPIフィルタ/ソートのテスト、キーボードナビゲーションのテストを作成。全59テストがパス。

今後の課題

  • 帳票タイプマスター(document_typesテーブル)との連携
  • 勘定科目マスターを使った仕訳ルールの自動提案

勘定科目マスターDB化が完了したことで、帳票タイプマスター管理機能の実装に着手できる状態になった。