Files
jarca-ledger-mcp/docs/data-model.md
T

12 KiB

계좌 평가 이력과 자산 마감 데이터 모델

목적과 범위

계좌 평가 증거, 수동 자산, append-only 자산 마감과 기존 ledger entities의 실제 SQLite 정본을 기록한다.

  • 포함 범위: accounts, transactions, manual_assets, account_valuations, asset_snapshots, asset_snapshot_runs, reconciliation_sessions, review_decisions, import_batches, schema_meta
  • 제외 범위: auth cookie/session, external price/FX store, inferred transactions, actual credentials/data

정본 엔터티

accounts — 기존 계좌

  • 책임: 계좌 identity/current display balance와 account type/liquidity metadata
  • 식별자: id
  • 생명 주기: 기존 CRUD; valuation history는 별도 append-only

필드

필드 타입 필수 여부 기본값 허용 값·형식 단위·정밀도 민감정보
id TEXT 필수 없음 generated account id 식별자 아니오
name TEXT 필수 없음 non-empty 없음 아니오
type TEXT 필수 bank bank/card/cash/investment/loan/other enum 아니오
currency TEXT 필수 KRW supported currency ISO code 아니오
last_balance INTEGER 선택 NULL exact integer currency unit 아니오
last_balance_basis_date TEXT 선택 '' YYYY-MM-DD or unknown date of the evidence represented by last_balance; empty/unknown is explicit 아니오
last_synced_at TEXT 선택 '' ISO date/time timestamp 아니오
statement_status TEXT 필수 unknown existing status enum 없음 아니오
liquidity_bucket TEXT 필수 other cash/deposit/investment/real_estate/other/loan enum 아니오
account_number_masked TEXT 필수 '' masked only redacted 민감 가능

account-valuations — 기준일 계좌 평가

  • 책임: 날짜가 지정된 평가 evidence와 선택/correction provenance. investment principal은 reported principal amount이고 loan principal은 outstanding principal이다.
  • 식별자: id
  • 생명 주기: insert-only; correction은 supersedes_id child

필드

필드 타입 필수 여부 기본값 허용 값·형식 단위·정밀도 민감정보
id TEXT 필수 없음 generated valuation id 식별자 아니오
account_id TEXT FK 필수 없음 accounts.id 관계 아니오
basis_date TEXT 필수 없음 YYYY-MM-DD date 아니오
amount INTEGER 필수 없음 exact signed integer currency unit 아니오
currency TEXT 필수 KRW supported currency ISO code 아니오
valuation_kind TEXT 필수 balance balance/cash_balance/total_value/loan/loan_balance purpose 아니오
source_type TEXT 필수 manual manual/import/account_write/reconciliation/snapshot enum 아니오
source_ref TEXT 필수 '' source/hash/reference opaque 민감 가능
verification_status TEXT 필수 unverified verified/unverified/rejected enum 아니오
recorded_at TEXT 필수 없음 ISO timestamp timestamp 아니오
memo TEXT 필수 '' operator note 없음 synthetic only
idempotency_key TEXT 필수 '' caller key opaque 아니오
supersedes_id TEXT FK 선택 NULL parent valuation one child 아니오
correction_reason TEXT 필수 '' required for correction 없음 아니오
as_of_at/timezone TEXT 함께 선택 NULL timezone-aware ISO + IANA timestamp/zone 아니오
cost_basis,net_contributed,profit,principal,interest,fee INTEGER 선택 NULL exact integer; NULL distinct from 0 currency unit 아니오
reported_principal_kind,reported_principal_label,return_basis TEXT 선택 NULL source-declared 없음 아니오
return_rate REAL 선택 NULL finite number ratio 아니오
representative_liability_definition TEXT loan 필수 NULL principal_only/principal_interest_fees enum 아니오

manual-assets — 수동 자산/부채

  • 책임: transaction이 아닌 평가 source
  • 식별자: id
  • 생명 주기: update/deactivate; closed snapshot은 별도 immutable copy

필드

필드 타입 필수 여부 기본값 허용 값·형식 단위·정밀도 민감정보
id TEXT 필수 없음 generated asset id 식별자 아니오
name TEXT 필수 없음 non-empty 없음 아니오
liquidity_bucket TEXT 필수 other normalized bucket enum 아니오
valuation_amount INTEGER 선택 NULL exact integer; NULL unvalued currency unit 아니오
valuation_date TEXT 필수 '' YYYY-MM-DD date 아니오
currency TEXT 필수 KRW supported currency ISO code 아니오
source_note,memo TEXT 필수 '' synthetic/redacted note 없음 민감 가능
active INTEGER 필수 1 0/1 boolean 아니오

asset-snapshots — closed snapshot rows

  • 책임: basis-date historical immutable item copy
  • 식별자: id
  • 생명 주기: insert-only; correction run creates new rows

필드

필드 타입 필수 여부 기본값 허용 값·형식 단위·정밀도 민감정보
id,basis_date,source_type,name,created_at TEXT 필수 없음 generated/date/account/manual_asset identity/date 아니오
source_id,currency,liquidity_bucket,valuation_source,source_note,memo TEXT 필수 ''/KRW/other source metadata 없음 가능
amount INTEGER 선택 NULL exact integer currency unit 아니오
snapshot_run_id TEXT 필수 '' asset_snapshot_runs.id relation 아니오
correction_of_run_id,correction_reason TEXT 필수 '' prior run/reason provenance 아니오
is_correction INTEGER 필수 0 0/1 boolean 아니오
closed_at TEXT 필수 '' ISO timestamp timestamp 아니오
valuation_id,selection_policy,verification_status,evidence_kind,exclusion_reason TEXT additive empty/exact/unverified/applied/empty provenance enum 없음 아니오

asset-snapshot-runs — close 실행 증거

  • 책임: approval, selection, applied/excluded/carried evidence와 run identity
  • 식별자: id
  • 생명 주기: insert-only; correction points to prior run

필드

필드 타입 필수 여부 기본값 허용 값·형식 단위·정밀도 민감정보
id,basis_date,close_status TEXT 필수 없음 complete_exact/incomplete_draft/conditional identity/date/status 아니오
selection_policy TEXT 필수 exact exact/as_of enum 아니오
idempotency_key TEXT 필수 '' unique when non-empty opaque 아니오
approved_by,approved_at,approval_reason,approval_reference TEXT 필수 empty explicit approval metadata provenance 아니오
correction_of_run_id,correction_reason TEXT 필수 empty prior run/reason provenance 아니오
applied_evidence,excluded_evidence,carried_evidence TEXT JSON 필수 [] redacted evidence arrays JSON 가능
created_at TEXT 필수 없음 ISO timestamp timestamp 아니오

transactions, import-batches, reconciliation-sessions, review-decisions, schema-meta — 기존 entities

기존 필드와 관계를 보존한다. import는 거래를 기록할 수 있지만 balance valuation candidate는 dated unverified row만 추가한다. reconciliation은 calculated balance provenance와 VALUATION_MANAGED 상태를 보존하며 investment valuation 때문에 transaction을 생성하지 않는다. schema_meta.schema_version은 12다.

현재 계좌 잔액 캐시와 기준일

  • last_balance is the current cache value: it is the latest current balance observed by an import or account write, not a historical valuation and not opening evidence.
  • last_balance_basis_date is the basis field for the evidence represented by that cache. It is a date when known; legacy or date-less writes store unknown/NULL and must not be inferred from last_synced_at or a valuation row.
  • last_synced_at is the execution/sync timestamp: when the import or account write advanced the cache, not the evidence basis date.
  • imports and account writes advance the account cache; they may also append a dated account_valuations candidate, but updating the cache does not rewrite historical rows.
  • account_valuations is the historical authority. A dated valuation remains append-only evidence even when it is older than the current cache; older evidence never rolls back the current cache.

관계와 불변조건

관계

출발 엔터티 관계 대상 엔터티 카디널리티 필수 여부 소유권 삭제 규칙
accounts has valuations account-valuations 1:N required account service no cascade/history preserved
account-valuations supersedes account-valuations 0..1 child optional valuation service append-only
asset-snapshot-runs contains asset-snapshots 1:N/possibly zero required snapshot service no delete
account-valuations evidence for asset-snapshots 0..N optional snapshot run copy only
import-batches produces candidate account-valuations 0..N optional import service candidate preserved
accounts has reconciliation reconciliation-sessions 1:N optional reconciliation service no valuation side effect

불변조건

  • idx_account_valuations_single_correction ensures one direct child; correction parent scope is same account/date/currency/purpose. Cyclic or self parent, second child, missing reason, and conflict are no-write failures.
  • source_ref is account-scoped evidence identity even when an explicit key is supplied; key/source mismatch conflicts. This is evidence idempotency. There is no generic label; only source-declared reported_principal_kind and reported_principal_label are physical fields.
  • only verified leaves are authority; unknown/future/unverified are excluded or warning evidence. last_balance is external current comparison, not opening evidence; missing balance_after/opening evidence is INCOMPLETE_CALCULATION.
  • preview does not insert; close inserts run and rows atomically; latest run is report authority. Reports expose actual valuation_date, age, carry, verification, run, approval, correction, warnings, and exclusions across close response, live, closed, timeseries, and monthly.
  • monthly_source_snapshot_id is a read-model alias of snapshot_run_id, not a persistence field. Investment unavailable and unavailable investment, loan purpose/definition/ambiguity, and reconciliation completeness remain explicit; no fake writes.
  • asset_buckets - loan is the net-worth formula; representative loan only, no fake transactions.

저장과 마이그레이션

  • 저장 위치: resolved SQLite path from jarca_ledger_mcp.infrastructure.sqlite.connection
  • 직렬화 형식: SQLite tables; evidence arrays JSON UTF-8
  • 스키마 버전: schema 11 → schema 12 additive
  • 기존 데이터 처리: migrate_db() creates missing tables/columns/indexes; this is an additive migration with no guessed migration or deletion. legacy rows with unknown basis remain unknown; no inference is permitted.
  • 하위 호환성: existing ledger/auth/menu/MCP contracts and legacy rows remain readable
  • 롤백 조건: pre-migration backup restore boundary; do not down-migrate or delete valuation history in application code

검증

  • 정상 데이터: tests/test_account_valuations.py, tests/test_asset_snapshots.py
  • 경계 데이터: NULL/0, stale carry-forward, correction, empty snapshot tables
  • 오류 데이터: invalid currency/kind, missing loan definition, idempotency/correction conflict
  • 저장 후 재조회: service list/select/report and contract regression tests
  • 마이그레이션: test_*schema* tests plus python -m pytest tests/test_account_valuations.py tests/test_asset_snapshots.py