feat: implement asset snapshot and manual asset read model
This commit is contained in:
+104
@@ -0,0 +1,104 @@
|
||||
# BAT-008 Implementation
|
||||
|
||||
## Plan summary
|
||||
|
||||
BAT-008 implemented the new valuation authority model in `service.py`/`db.py`, exposed read-only MCP tools in `server.py`, aligned the Streamlit overview with the shared valuation helper, and updated baseline docs to match the confirmed Discovery/REQ scope.
|
||||
|
||||
## Changed files
|
||||
|
||||
- `jarca_ledger_mcp/db.py`
|
||||
- `SCHEMA_VERSION` → `9`
|
||||
- additive/idempotent tables: `manual_assets`, `asset_snapshots`
|
||||
- migration path updated so existing DBs create the new tables safely
|
||||
- `jarca_ledger_mcp/service.py`
|
||||
- shared valuation helpers for account/manual-asset/snapshot authority sources
|
||||
- new service APIs: `create_manual_asset`, `list_manual_assets`, `create_asset_snapshot`, `get_asset_snapshot_report`, `get_net_worth_timeseries`
|
||||
- `get_asset_liquidity_report` aligned to the same valuation policy while preserving REQ-005 fallback semantics
|
||||
- `jarca_ledger_mcp/server.py`
|
||||
- new read MCP tools: `list_manual_assets`, `get_asset_snapshot_report`, `get_net_worth_timeseries`
|
||||
- `get_asset_liquidity_report` contract text updated for shared valuation source behavior
|
||||
- `dashboard/app.py`
|
||||
- overview asset section now explains the valuation authority source and shows `manual_assets` rows when present
|
||||
- existing account-only fallback remains when new tables are empty
|
||||
- Documentation
|
||||
- `docs/data-model.md`
|
||||
- `docs/interface-contract.md`
|
||||
- `docs/runtime-flows.md`
|
||||
- `docs/project-structure.md`
|
||||
- Tests
|
||||
- new: `tests/test_asset_snapshots.py`
|
||||
- adjusted: `tests/test_service.py`
|
||||
|
||||
## Execution log
|
||||
|
||||
- 2026-06-30 21:26 KST: BAT-008 standard batch scaffold created from approved REQ-009/REQ-010.
|
||||
- 2026-06-30 21:3x~21:4x KST: implementation landed in `db.py`, `service.py`, `server.py`, `dashboard/app.py`, docs, and regression tests via `jarcaledgerdev` handoff + local verification orchestration.
|
||||
- 2026-06-30 21:40 KST: targeted compile/test validation passed.
|
||||
- 2026-06-30 21:41 KST: MCP stdio contract smoke check passed and discovered the three new read tools.
|
||||
- 2026-06-30 21:42 KST: synthetic end-to-end service probe confirmed live-authority fallback, snapshot read behavior, and net-worth timeseries output.
|
||||
|
||||
## Validation
|
||||
|
||||
### Command 1
|
||||
```bash
|
||||
cd /root/projects/jarca-ledger-mcp
|
||||
source .venv/bin/activate
|
||||
python -m py_compile jarca_ledger_mcp/*.py dashboard/app.py
|
||||
pytest tests/test_asset_snapshots.py tests/test_service.py tests/test_contract_regression.py -q
|
||||
```
|
||||
|
||||
Result:
|
||||
- `................. [100%]`
|
||||
- exit code `0`
|
||||
|
||||
### Command 2
|
||||
```bash
|
||||
cd /root/projects/jarca-ledger-mcp
|
||||
source .venv/bin/activate
|
||||
hermes mcp test jarca-ledger
|
||||
```
|
||||
|
||||
Result:
|
||||
- stdio connection success
|
||||
- tools discovered: `51`
|
||||
- new BAT-008 read tools discovered:
|
||||
- `list_manual_assets`
|
||||
- `get_asset_snapshot_report`
|
||||
- `get_net_worth_timeseries`
|
||||
|
||||
### Command 3
|
||||
```bash
|
||||
cd /root/projects/jarca-ledger-mcp
|
||||
source .venv/bin/activate
|
||||
python - <<'PY'
|
||||
from tempfile import TemporaryDirectory
|
||||
from pathlib import Path
|
||||
from jarca_ledger_mcp import service
|
||||
|
||||
with TemporaryDirectory() as td:
|
||||
db_path = str(Path(td) / 'ledger.sqlite3')
|
||||
service.create_ledger_account('현금', last_balance=1000000, last_synced_at='2026-06-30', liquidity_bucket='cash', db_path=db_path)
|
||||
service.create_ledger_account('투자', type='investment', last_balance=2000000, liquidity_bucket='investment', db_path=db_path)
|
||||
service.create_manual_asset('전세보증금', 300000000, '2026-06-30', 'real_estate', source_note='synthetic appraisal', db_path=db_path)
|
||||
service.create_manual_asset('주담대', 120000000, '2026-06-30', 'loan', source_note='synthetic loan balance', db_path=db_path)
|
||||
print(service.list_manual_assets(db_path=db_path))
|
||||
print(service.get_asset_snapshot_report('2026-06-30', db_path=db_path))
|
||||
service.create_asset_snapshot('2026-05-31', 'account', 'acct-a', '현금', 1000000, 'cash', source_note='synthetic', db_path=db_path)
|
||||
service.create_asset_snapshot('2026-05-31', 'manual_asset', 'manual-home', '부동산', 200000000, 'real_estate', source_note='synthetic', db_path=db_path)
|
||||
service.create_asset_snapshot('2026-05-31', 'manual_asset', 'manual-loan', '대출', 80000000, 'loan', source_note='synthetic', db_path=db_path)
|
||||
print(service.get_asset_snapshot_report('2026-05-31', db_path=db_path))
|
||||
print(service.get_net_worth_timeseries(start_date='2026-05-01', end_date='2026-06-30', db_path=db_path))
|
||||
PY
|
||||
```
|
||||
|
||||
Key result excerpts:
|
||||
- `list_manual_assets` returned `count=2` and `authority_source='manual_assets'`
|
||||
- live fallback snapshot report returned `source='live_authority'`, `total_assets=303000000`, `total_liabilities=120000000`, `net_worth=183000000`
|
||||
- stored snapshot report returned `source='asset_snapshots'`, `snapshot_count=3`, `net_worth=121000000`
|
||||
- timeseries returned `points[0].basis_date='2026-05-31'`, `points[0].net_worth=121000000`
|
||||
|
||||
## Remaining risks / follow-up notes
|
||||
|
||||
- Snapshot creation is intentionally service-only in BAT-008. MCP mutation exposure remains future scope by Discovery decision.
|
||||
- Manual-asset edit/delete workflows and month-end operator UX are still procedural/document-driven rather than exposed as first-class CRUD flows.
|
||||
- QC gate still needs to confirm REQ Implemented promotion before commit-stage handoff.
|
||||
Reference in New Issue
Block a user