feat: implement asset snapshot and manual asset read model

This commit is contained in:
Jarca
2026-06-30 22:04:52 +09:00
parent 7fd1b45bd5
commit beddff7661
20 changed files with 1232 additions and 61 deletions
+15 -5
View File
@@ -5,7 +5,7 @@
- Status: draft
- Owner: Jarca / project maintainer
- Last Updated (KST): 2026-06-30
- Source Discovery / Batch: bootstrap-baseline, BAT-006, BAT-007
- Source Discovery / Batch: bootstrap-baseline, BAT-006, BAT-007, BAT-008
- Primary Runtime: mixed
## Project Summary
@@ -48,9 +48,10 @@
## Flow: `Dashboard operations hub overview`
1. Operator opens the `요약` page.
2. Dashboard resolves the KST current month and calls `get_monthly_cashflow_report(month)` using `transactions.transaction_date` and `ledger_categories.cashflow_kind` semantics.
3. Dashboard calls `get_asset_liquidity_report`, which groups active accounts by `accounts.liquidity_bucket` and uses only `accounts.last_balance` for asset/liability values.
4. Dashboard renders sections in REQ-005 priority order: this-month actual income/expense/net/savings rate, asset liquidity, asset composition, budget/spend, operational warnings.
5. Missing `last_balance` account rows are excluded from asset totals and surfaced as warnings; transaction sums are not used to estimate non-transaction assets.
3. Dashboard calls `get_asset_liquidity_report`, which uses the shared valuation helper: account-backed assets from `accounts.last_balance` plus active `manual_assets` rows when present.
4. If `manual_assets` and `asset_snapshots` are empty, the report keeps the REQ-005 account-only fallback and preserves existing totals/keys.
5. Dashboard renders sections in REQ-005 priority order: this-month actual income/expense/net/savings rate, asset liquidity, asset composition, budget/spend, operational warnings.
6. Missing `last_balance` or `manual_assets.valuation_amount` values are excluded from asset totals and surfaced as warnings; transaction sums are not used to estimate non-transaction assets.
## Flow: `CI validation gates`
1. GitHub Actions starts `.github/workflows/ci.yml` on `pull_request`, `push` to `main`, or `workflow_dispatch`.
@@ -63,6 +64,14 @@
8. Any required job failure fails the workflow. Stable required-check job names are `pytest-regression`, `dashboard-app-test`, `dashboard-http-smoke`, `db-safety-smoke`, `contract-regression`, and `lint`; actual branch protection toggle enforcement is configured outside the repository.
9. CI logs are status-oriented and synthetic-data-only; they must not contain real account identifiers, raw payloads, statement filenames, balances from the operating DB, or passwords.
## Flow: `Asset snapshot and net-worth read model`
1. Month-end manual close records item-level rows in `asset_snapshots` from the live authority sources: account `last_balance` rows and `manual_assets` valuations. BAT-008 stores the schema and service helper but does not expose snapshot creation as an MCP mutation.
2. `get_asset_snapshot_report(basis_date)` first checks for snapshot rows on the requested basis date.
3. If snapshot rows exist, the report computes bucket totals, total assets, total liabilities, and net worth from the stored rows.
4. If no snapshot rows exist, the report falls back to live authority sources (`accounts.last_balance` + active `manual_assets`) and marks `source='live_authority'`.
5. `get_net_worth_timeseries(start_date, end_date, months)` reads distinct stored snapshot basis dates and applies the same asset-buckets-minus-loan formula to every point.
6. `list_manual_assets` exposes current manual asset/liability rows for read-only MCP consumers. Manual asset CRUD and snapshot creation MCP tools remain future scope.
## Flow: `Import preview and import`
1. Operator chooses or supplies a supported source file: KB Bank PDF, Toss Bank PDF, Toss Securities PDF, SeoulPay XLSX, or CSV.
2. Preview function parses the file and reports counts, sample rows, duplicate status, and classification preview.
@@ -121,7 +130,8 @@
- CI gates must use synthetic/temp DBs only. The default operating DB path (`~/.local/share/jarca/ledger.sqlite3`) is forbidden for AppTest, HTTP smoke, and DB safety smoke wrappers.
- Contract regression must use synthetic/temp DBs only and must not expose runtime contract-version fields in MCP success payloads unless a future approved REQ changes the policy.
- Branch protection required-check drift should be audited against the six stable workflow job names documented in `docs/interface-contract.md`; changing a job name requires an explicit REQ/BAT note because it can break external repository settings.
- Dashboard asset liquidity calculations must use `accounts.liquidity_bucket` and `accounts.last_balance`; `loan` is excluded from the asset composition denominator and reflected as debt/net-worth only.
- Dashboard and MCP asset valuation reports must use the shared service valuation policy: `accounts.last_balance` plus `manual_assets`, asset buckets minus loan, and missing valuation exclusion.
- Snapshot read tools are read-only in BAT-008. Snapshot creation and manual asset CRUD MCP mutation tools require a future REQ.
- Sensitive passwords are runtime inputs and must not be committed.
## Current Gaps / Planned Changes