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
@@ -0,0 +1,99 @@
# REQ-009 Asset snapshot/manual assets valuation model
- Status: Implemented
- Type: Data
- Priority: High
- Owner: 렛저장인
- Source Discovery: `docs/discovery/dcy-008_20260630_asset-snapshot-manual-valuation-system.md`
- Batch: BAT-008
- Created At (KST): 2026-06-30 21:17 KST
- Approved At (KST): 2026-06-30 21:24 KST
- Implemented At (KST): 2026-06-30 22:05 KST
## 1. 배경
REQ-005는 `accounts.liquidity_bucket` + `last_balance` 기반 자산 유동성/순자산 표시를 구현했지만, 시점별 자산 평가 이력과 비거래 자산/부채의 독립 모델은 의도적으로 제외했다. dcy-008 confirmed Discovery에 따라 자산 스냅샷 이력과 수기 자산 모델을 별도 테이블로 도입하고, 계좌 `last_balance` + 수기 자산 보강을 단일 평가 권위 소스로 정립해 기준일별 순자산 재현과 후속 MCP 조회 기능의 데이터 기반을 마련해야 한다.
## 2. Intent
자산 평가 모델을 계좌 한 줄의 최신 값에서 벗어나, 기준일별 스냅샷과 비거래 자산/부채의 명시적 엔티티로 분리한다. 이 REQ의 목적은 `asset_snapshots`/`manual_assets` 데이터 모델, 순자산 산식, 권위 소스 우선순위, 월말 수동 스냅샷 정책을 구현 가능한 저장 계층 요구사항으로 고정하는 것이다.
## 3. 범위
### In Scope
- `asset_snapshots`와 `manual_assets`를 별도 additive/idempotent 테이블로 도입한다.
- 비거래 자산/부채의 필수 속성(이름, 평가값, 기준일, `liquidity_bucket`, 출처 메모)을 정의한다.
- 자산 스냅샷의 필수 속성(기준일, 평가 대상, 평가 금액, `liquidity_bucket`, 출처/메모)을 정의한다.
- 자산성 합계 − `loan` 차감, 미평가 제외 규칙을 저장/집계 계층 기준으로 고정한다.
- 월말 수동 스냅샷 생성 정책과 항목 단위 수용 구조를 반영한다.
- `docs/data-model.md`에 위 모델과 권위 소스 규칙을 반영한다.
### Out of Scope
- 외부 시세/부동산 자동 평가 연동.
- 실시간 자동 스냅샷 생성 스케줄러.
- 수익률/세금/리밸런싱 계산.
- 조회성 MCP 응답 shape 정의 자체(별도 Interface REQ에서 다룸).
## 4. Requirement
### FR-1. Manual assets data model
- `manual_assets`는 거래로 산출되지 않는 비거래 자산/부채를 저장해야 한다.
- 각 항목은 최소한 이름, 자산/부채 구분 또는 `liquidity_bucket`, 평가값, 기준일, 출처 메모를 가져야 한다.
- 허용 `liquidity_bucket` 값은 `cash`, `investment`, `deposit`, `real_estate`, `loan`, `other`다.
- 사용자 입력 기반 평가값이 권위 소스가 되는 항목은 계좌 모델과 혼합 저장하지 않고 별도 엔티티로 유지해야 한다.
### FR-2. Asset snapshots history model
- `asset_snapshots`는 기준일 시점의 자산 평가 결과를 누적 저장해야 한다.
- 스냅샷은 계좌와 수기 자산 항목을 모두 담을 수 있는 항목 단위 구조를 수용해야 한다.
- 기존 스냅샷은 파괴적으로 덮어쓰지 않고 신규 행으로 누적해야 한다.
- 각 행은 최소한 기준일, 평가 대상 식별자, 평가 금액, `liquidity_bucket`, 평가 출처/메모를 보존해야 한다.
### FR-3. Valuation authority source rule
- 계좌 기반 자산은 기존 `accounts.last_balance`를 기본 평가 권위 소스로 사용해야 한다.
- 거래로 산출되지 않는 비거래 자산/부채는 `manual_assets`를 권위 소스로 사용해야 한다.
- 스냅샷은 위 권위 소스를 기준일 시점에 고정한 기록층이어야 하며, 실시간 권위 소스를 대체하는 별도 1차 입력원이 되어서는 안 된다.
- 동일 자산이 중복 집계되지 않도록 계좌 항목과 수기 자산 항목의 책임 경계를 정의해야 한다.
### FR-4. Net worth formula and exclusion policy
- 순자산은 자산성 버킷(`cash`, `investment`, `deposit`, `real_estate`, `other`) 합계에서 `loan` 부채를 차감해 계산해야 한다.
- 평가값이 없는 항목은 임의 거래 합계로 추정하지 않고 제외해야 한다.
- 제외된 항목은 후속 화면/응답 계층에서 설명 가능하도록 상태 또는 근거를 남길 수 있어야 한다.
### FR-5. Manual month-end snapshot policy
- 초기 운영 정책은 월말 수동 스냅샷 생성이어야 한다.
- 스냅샷 생성 흐름은 월말 마감 시점에 계좌 `last_balance`와 수기 자산 평가값을 함께 고정할 수 있어야 한다.
- 자동 생성/스케줄링은 후속 범위로 남긴다.
### FR-6. Baseline documentation alignment
- `docs/data-model.md`는 `asset_snapshots`, `manual_assets`, 권위 소스 우선순위, 순자산 산식을 반영해야 한다.
- 필요 시 `docs/project-structure.md`와 `docs/runtime-flows.md`에 데이터 모델 책임과 월말 스냅샷 흐름을 참조 수준으로 반영해야 한다.
## 5. Acceptance Criteria
- AC-1: 신규 DB/기존 DB 모두에서 `asset_snapshots`, `manual_assets`가 additive/idempotent migration으로 생성된다.
- AC-2: `manual_assets`는 이름, 평가값, 기준일, `liquidity_bucket`, 출처 메모를 저장할 수 있다.
- AC-3: `asset_snapshots`는 기준일, 평가 대상, 평가 금액, `liquidity_bucket`, 출처/메모를 누적 저장할 수 있다.
- AC-4: 계좌 기반 자산은 `last_balance`, 비거래 자산/부채는 `manual_assets`를 권위 소스로 사용하는 규칙이 구현/문서에 반영된다.
- AC-5: 순자산 계산이 자산성 합계 − `loan` 차감, 미평가 제외 규칙을 따른다.
- AC-6: 빈 신규 테이블 상태에서도 기존 `REQ-005` 대시보드 흐름이 깨지지 않는다.
- AC-7: `docs/data-model.md`와 필요 baseline 문서가 본 REQ 범위를 반영한다.
## 6. Impacted Area
- `jarca_ledger_mcp/db.py`
- `jarca_ledger_mcp/service.py`
- `docs/data-model.md`
- 필요 시 `docs/project-structure.md`
- 필요 시 `docs/runtime-flows.md`
## 7. Notes
- 이 REQ는 저장 구조/권위 소스/순자산 산식 같은 데이터 모델 책임을 다루므로 `Data` 타입으로 관리한다.
- 조회성 MCP 응답 계약과 대시보드 노출 shape는 `REQ-010`에서 다룬다.
- 실제 초기 수기 자산 목록은 구현 전 사용자가 입력해야 하며, 본 REQ는 그 입력 포맷과 저장 규칙을 다루는 수준으로 제한한다.
## 8. Change Log
- 2026-06-30 21:17 KST: dcy-008 confirmed 범위를 바탕으로 Proposed 초안을 생성.
- 2026-06-30 21:24 KST: dcy-008 confirmed 결정사항과 Acceptance Criteria를 재검토해 Approved로 전환.
- 2026-06-30 22:05 KST: BAT-008 구현·검증 evidence와 jarcaledgerqc PASS gate를 근거로 Implemented로 전환.