계좌 기준일 평가 이력(account_valuations) 구현 및 월정산 연동 — 원금 정보·정정 이력 포함 #12

Closed
opened 2026-10-06 03:56:41 +00:00 by genichin · 1 comment
Owner

요약

계좌의 최신 표시값과 특정 기준일의 평가 근거를 분리하고, 기준일 평가 이력의 등록·조회·정정 및 기존 자산 마감·월정산·잔고 대사·Dashboard 연결을 구현한다. Issue #12가 제안한 account_valuations와 원금성 선택 필드를 검토한 결과, 현재 계좌 평가 이력에 해당하는 구조는 없으며 기존 asset_snapshots는 마감 결과 보존 계층으로 재사용할 수 있다. 새로운 평가 근거 계층과 기존 마감 계층의 책임을 분리하되 공통 선택 로직으로 조회 정책을 일원화한다.

이 문서는 Discovery 초안이며 구현 승인이 아니다. 사용자가 선택한 세 정책을 반영했다. 대출 대표 부채 정의는 평가 기록마다 필수로 명시하고 추정하지 않는다. 기본 as_of는 확인된 유효 자료만 선택하며 미확인 자료는 경고/후보로만 반환한다. 조건부 마감은 누락 제외와 확인된 과거값의 명시적 이월만 별도 승인으로 허용한다. 미해결 질문은 없다.

문제

  • 원본 Issue는 preview_asset_snapshot_close(basis_date="2026-09-30")에 2026-10-05 IRP 평가값과 오래된 계좌 잔고가 포함됐다고 보고했다. 실제 운영 DB는 조사하지 않았으며 금액·계좌번호를 수집하지 않았다.
  • 고정 소스에서 _account_valuation_items는 accounts.last_balance를 읽고 last_synced_at을 valuation_date로 표시한다. _snapshot_preview_from_conn은 요청 기준일과 무관하게 이 현재값을 합산하고 과거 자료에만 stale_valuation 경고를 붙인다. 미래값 제외와 exact 선택 검증이 없다.
  • get_asset_snapshot_report는 해당 날짜의 마감 행이 없으면 현재 계좌·수기 자산값으로 fallback한다. is_closed_snapshot=False는 반환하지만 기준일 이하의 근거만 선택하지는 않는다.
  • _account_balance_row는 balance_after가 없으면 시작잔고 없는 거래 순증감을 계산값으로 사용한다. get_balance_reconciliation_report는 이를 외부 잔고와 비교하므로 거래 없는 투자 계좌도 REVIEW_NEEDED가 될 수 있다.
  • 현재 스키마에는 기준일별 계좌 평가 근거, 원금 정의, 확인 상태, 평가 정정 체인이 없다. 기존 마감의 append-only correction run은 있으나 평가 근거 ID·누락 및 이월·조건부 승인 근거를 충분히 고정하지 않는다.

포함 범위

  • 평가 근거 이력: 계좌 FK, basis_date, 대표 amount, currency, valuation_kind, source_type, source_ref, verification_status, recorded_at, memo, supersedes_id, correction_reason 및 증빙/idempotency 식별자를 저장한다. 기준일과 등록일을 분리하고 날짜 자료에 임의 확인 시각을 만들지 않는다. 시간 자료를 지원하는 경우에만 실제 as_of_at과 시간대를 보존한다.
  • 정확한 금액과 지표: 기존 원화 정수 원 단위를 보존하고 통화 최소단위 정수 또는 정확한 decimal로 저장한다. NULL과 실제 0을 구분한다. 취득원가 cost_basis_amount, 누적 순납입액 net_contributed_amount, 기관 표시 reported_principal_amount·reported_principal_kind·원문 명칭, 표시 손익·수익률 및 return_basis를 각각 선택 정보로 관리한다. 정의 미확인은 unknown으로 보존한다. 대출 잔여 원금·미납 이자·수수료를 분리한다. 평가 기록마다 대표 부채가 원금만인지 원금+이자+수수료인지 필수로 명시하며 기본값으로 추정하지 않는다. 구성 금액 미확인도 그대로 표시하고 대표 금액과 구성 금액을 중복 합산하지 않는다.
  • 공통 선택: exact는 요청일과 일치하는 확인된 유효 대표값만 사용하고 누락은 미확인으로 반환한다. 월마감 기본은 exact다. as_of는 요청일 이하의 최신 유효값을 선택하고 실제 평가일·경과 일수·확인 상태·이월 여부를 반환한다. 기본 as_of도 확인된 유효 자료만 선택한다. 미확인 자료는 별도 경고/후보로 반환하되 합산하지 않으며 더 최근 미확인 기록이 확인된 후보를 대체하지 않는다. 미래 자료는 두 정책 모두 제외하고 계좌·통화·평가 목적별 유효 정정본 하나만 합산한다.
  • 현재값과 과거값: 뒤늦은 과거 자료 등록이 최신 표시값을 과거로 되돌리지 않아야 한다. 기존 계좌 수정·import 경로의 최신값 쓰기와 새 이력의 권위 관계를 연결하고, 기준일 미상 값을 과거 보고·마감의 확정 자료로 사용하지 않는다. 현재값 호환 표시가 남더라도 출처와 기준일 확인 여부를 명시한다.
  • 중복 및 정정: 동일 증빙/idempotency 재입력은 동일 기록을 재사용하고 내용이 다른 충돌은 거부한다. 실제 정정은 append-only로 대상·사유를 연결한다. 다른 계좌·통화·목적을 참조하는 정정, 순환 참조 및 동일 유효본에 대한 동시 분기 정정을 차단한다. UNIQUE(account_id, basis_date) 하나로 정정 행 추가를 막지 않는다.
  • 마감과 월정산: 기존 asset_snapshots·correction run을 보존·확장하여 기준일, 선택한 valuation_id, 적용 금액·통화·자산/부채 분류·출처·확인 상태, 누락/이월, 마감 버전과 정정 사유를 고정한다. 평가 최신값 변경·평가 정정·거래 추가로 기존 마감이 자동 변경되지 않으며 명시적인 재마감만 새 버전을 추가한다. 완전한 마감·미완료 초안·승인된 조건부 마감을 구분하고 승인 근거를 보존한다. 조건부 마감에서는 누락 항목을 제외하고 확인된 과거값의 명시적 as_of 이월을 별도 승인으로 허용한다. 미확인·미래·기준일 미상 자료는 합산하지 않으며 승인으로 우회할 수 없다. 별도 승인 없이는 미완료 초안에 머문다. 적용/제외 항목·이월 및 승인자/시각/사유/근거를 마감 버전에 보존하고 완전한 exact 마감과 구분한다.
  • 대사: 외부 확인값과 장부 계산값을 구분한다. 장부 계산은 검증된 시작잔고·기준시점·거래 포함 범위·완전성과 계산 근거를 표시한다. 투자 총평가액을 거래 순증감으로 대체하지 않고 거래 없는 수동 투자 계좌의 대사 불가·거래 미수입·평가 수동 관리 상태를 구분한다. 가짜 수입·지출·조정 거래를 만들지 않는다.
  • MCP·Dashboard: 평가 등록·조회·정정 기능과 기존 자산 보고·preview/close·대사·현재 자산 조회·월정산을 공통 선택 로직에 연결한다. Dashboard의 계좌·자산/마감·월정산 기존 화면 안에서 최신 평가액/실제 기준일, 이력 등록·조회·정정, 확인 잔고/확인 평가액/잔여 원금 명칭, 원금 정의 미확인 및 누락·이월·조건부 경고를 표시한다. 조회·렌더링은 쓰기를 실행하지 않고 명시적인 사용자 제출만 변경을 수행한다.
  • 이관 및 검증: 기준일이 증명된 기존 자료만 이력으로 이관하고 last_synced_at을 무조건 실제 기준일로 간주하지 않는다. 기준일 미상 자료는 임의 월말로 소급하지 않는다. 기존 마감과 개인정보 비노출을 보존하고 idempotent additive migration, 기존 API 및 Dashboard 회귀 테스트를 제공한다.

제외 범위

  • 증권사 자동 연동, 종목별 매매 원장, 정확한 투자 성과 계산 엔진은 원본 요청의 필수 범위가 아니다.
  • 자동 환율 수집·환산 엔진, 새로운 인증/RBAC, 별도 월정산 제품 또는 기존 금융 데이터의 자동 재작성은 추가하지 않는다. 서로 다른 통화를 근거 없이 같은 금액으로 합산하지 않는다.
  • 기존 수기 비계좌 자산 전체의 평가 이력 재설계는 확정 범위가 아니다. 기존 경로를 유지하되 preview/close에서 그 자료의 기준일·누락·이월 경고와 정책 적용을 누락하지 않는다.
  • Discovery 수행 중 코드·스키마·후속 문서 작성, PR 생성, label·assignee·state 변경은 하지 않는다.

제약 조건

  • 저장소 근거 revision은 main의 5813dd484196239ab1fac4ba066c5b4922fb33e6이다. 실제 운영 DB 관찰이나 기능 실행 결과를 소스 조사와 혼동하지 않는다.
  • SQLite schema version 11의 기존 데이터 및 additive/idempotent migration 원칙을 보존한다. 대표값과 모든 부가 원금 지표를 동시에 합산하지 않는다. loan 부채를 차감하는 기존 순자산 방향과 금액 정밀도를 유지한다.
  • 공통 서비스 계층을 MCP와 Streamlit gateway가 공유하는 구조를 유지한다. Dashboard의 기존 fail-closed 인증을 DB 접근보다 앞에 두고 REQ-001 cookie·logout 계약과 REQ-002 메뉴 label/order·공통 shell·명시적 금융 쓰기 계약을 유지한다. MCP에 Dashboard 인증이 적용된다고 주장하지 않는다.
  • 기존 success 및 실패의 error_code/error, 호출명·기존 인수·응답 필수 키/타입은 가능한 한 유지한다. 현재값을 과거값으로 합산하던 의미 오류는 보존할 계약이 아니다. 필수 변경이 생기면 명시적 호환성·버전 정책과 회귀 검증을 요구사항 및 인터페이스 계약에 기록한다.
  • 기존 legacy snapshot의 평가 근거를 추측하여 valuation_id를 생성하지 않는다. 기존 기록은 legacy 근거로 구분하고 신규 마감만 새 근거 계약을 충족하게 한다.
  • 실제 계좌번호, 평가액, 증빙 원문 및 credential을 로그·테스트·문서에 기록하지 않는다. 테스트는 synthetic 자료만 사용한다.
  • 사용자 선택으로 확정된 대출 정의 필수·기본 as_of 확인 자료 한정·조건부 누락 제외/확인 자료 이월 정책은 MCP, Dashboard, 공통 선택, 마감 저장/재조회에서 동일하게 적용한다. 미확인·미래·기준일 미상 자료의 합산은 조건부 승인으로도 허용하지 않는다. 이 결정은 새 코드의 구현·실행 성공을 의미하지 않는다.

확정된 결정

원본 Issue의 명시 요구와 현재 Discovery에서 사용자가 선택한 결정을 확정 범위로 기록한다. 선택되지 않은 대안은 채택하지 않으며 이 기록은 Discovery 승인이나 구현 handoff가 아니다.

  1. 최신값과 기준일 평가 자료를 분리하고 동일 역할 구조가 있으면 재사용한다. 소스 조사상 계좌 평가 이력은 없고 asset_snapshots는 마감 계층이므로 마감 구조를 폐기하거나 중복 마감 엔진을 만들지 않는다. account_valuations는 제안명이며 물리 테이블명은 요구사항/구현 설계에서 위 계약에 맞춰 정한다.
  2. exact를 월마감 기본으로 삼고 미래 기준일 평가값을 exact/as_of 모두에서 제외한다. 누락과 이월을 구분한다.
  3. NULL과 0, 취득원가와 순납입액과 기관 표시 원금, 외부 확인값과 장부 계산값을 구분한다. 대표 투자 총평가액만 합산하며 그 안의 현금성 잔액과 원금을 다시 더하지 않는다.
  4. 평가 정정·마감 정정은 append-only다. 기존 마감은 불변이며 반영은 사유를 가진 명시적 재마감으로 수행한다. 동일 증빙 중복 및 정정 충돌·순환을 방지한다.
  5. 투자 총평가액을 거래 순증감으로 대체하거나 평가 등록을 위해 허위 거래를 만들지 않는다.
  6. 기준일 미상 자료를 동기화 시각만으로 소급하지 않고 기존 최신값 호환과 마감 이력을 보존한다.
  7. 후속 요구사항은 인증/메뉴와 독립된 금융 기능이므로 새 REQ-003을 사용한다. 동일 저장소 Issue 추적성은 #12, 구현 PR은 미정으로 기록한다. 승인 상태를 임의로 부여하지 않는다.
  8. OQ-001의 선택을 채택한다. 대출 평가 기록마다 대표 부채 정의를 필수로 명시하고 기본값으로 추정하지 않는다. 원금만 또는 원금+이자+수수료를 명시적으로 선택하며 구성 금액 미확인도 그대로 표시한다.
  9. OQ-002의 선택을 채택한다. 기본 as_of도 확인된 유효 자료만 선택하고 미확인 자료는 별도 경고/후보로 반환하되 합산하지 않는다.
  10. OQ-003의 선택을 채택한다. 조건부 마감은 누락 제외와 확인된 과거값의 명시적 as_of 이월만 별도 승인으로 허용한다. 미확인·미래·기준일 미상 자료는 합산하지 않고 승인 없이는 미완료 초안에 머문다. 승인자/시각/사유/근거와 적용/제외 항목·이월을 마감 버전에 고정한다.

저장소 근거

모든 경로는 대상 저장소의 위 exact revision에서 이번 review로 다시 조사했다. 세 사용자 선택은 기존 기능이 이미 지원한다는 증거가 아니라 신규 데이터/선택/승인 검증 계약이다. 현재 SQLite 스키마·additive migration·공통 application 및 adapter 경로에서 해당 계약을 추가할 위치를 확인했다. 별도 API·dependency·runtime·배포 기능을 전제로 하는 결정은 없으며 기술적 전제의 실행 실험을 요구할 근거는 확인되지 않았다. 실제 신규 구현과 회귀 검증은 후속 단계에서 수행해야 한다.

  • jarca_ledger_mcp/infrastructure/sqlite/schema.py: schema version 11, accounts.last_balance/last_synced_at, manual_assets, asset_snapshots와 run 정정 필드는 존재한다. 계좌별 평가 이력 테이블·평가 근거 FK·원금 정의 필드는 없다.
  • jarca_ledger_mcp/infrastructure/sqlite/migrations.py: migrate_db는 additive/idempotent migration 및 snapshot correction 필드 보강을 수행한다.
  • jarca_ledger_mcp/application/assets_service.py: _valuation_policy, _account_valuation_items, _manual_asset_valuation_items, _snapshot_preview_from_conn, get_asset_snapshot_report, close_asset_snapshot, _snapshot_rows_for_latest_run, _summarize_valuation_items를 조사했다. 현재값 권위, stale 경고, 미마감 fallback, append-only run과 asset_buckets - loan 계산을 확인했다.
  • jarca_ledger_mcp/application/reconciliation_service.py: _account_balance_row의 net_transaction_delta_without_opening_balance와 get_balance_reconciliation_report의 OK/REVIEW_NEEDED/BASELINE_REQUIRED 판정이 존재한다. 투자 총평가액의 별도 대사 가능성 판정은 없다.
  • jarca_ledger_mcp/application/monthly_settlement_service.py: get_monthly_settlement_summary는 월말의 자산 보고와 별도 대사 보고를 읽어 요약하며 read_only=True를 반환한다. 월정산 전용 저장 엔진은 확인되지 않았다.
  • jarca_ledger_mcp/application/accounts_write_services.py, jarca_ledger_mcp/application/imports_service.py: 계좌 생성·수정 및 import가 last_balance/last_synced_at을 직접 쓴다. 이 경로를 무시한 새 이력만 추가하면 권위 자료가 이중 관리된다.
  • jarca_ledger_mcp/service.py, jarca_ledger_mcp/application/asset_account_services.py, jarca_ledger_mcp/adapters/mcp/server.py, jarca_ledger_mcp/adapters/mcp/tool_contracts.py, jarca_ledger_mcp/adapters/streamlit/assets_gateway.py, jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py, jarca_ledger_mcp/adapters/streamlit/overview_gateway.py: 기존 공개 facade·MCP 도구·Streamlit gateway 연결 경로다.
  • dashboard/app.py, dashboard/page_views/accounts.py, dashboard/page_views/assets.py, dashboard/page_views/monthly_settlement.py: 인증 후 기존 화면을 dispatch한다. 계좌 화면은 최신 잔고·동기화 시각을 수정하고 자산 화면은 preview/close를 제공하며 월정산 화면은 읽기 전용이다.
  • tests/test_asset_snapshots.py: additive migration, 기존 현재값 fallback, 합산 및 append-only 마감 정정 테스트가 있다. tests/test_contract_regression.py, tests/contract_snapshots/response_contract_v1_0.json: preview/close 필수 응답 키와 타입 및 additive/breaking 변경 정책이 존재한다. 테스트는 읽었으며 이번 Discovery에서 실행하지 않았다.
  • docs/requirements/req-001_dashboard-administrator-authentication.md, docs/requirements/req-002_dashboard-menu-transition.md: 기존 ID는 REQ-001·REQ-002이며 연속·중복 없음 및 파일명/본문 ID 일치를 확인했다. 이번 계좌 평가 기능의 기존 요구사항 문서는 없다. 소스 주석의 REQ-005는 실제 요구사항 파일의 존재나 ID 할당 근거로 사용하지 않는다.
  • docs/interface-contract.md, docs/project-structure.md, docs/runtime-flow.md는 현재 인증 및 메뉴 계약을 담는다. docs/data-model.md는 존재하지 않는다. 후속 금융 계약은 기존 공통 문서에 추가하고 기존 내용을 유지해야 한다.

문서 영향 및 산출물

요구사항명세서

  • 조치: 신규 작성
  • 경로: docs/requirements/req-003_account-valuation-history.md
  • 문서 ID: REQ-003
  • 제목: 계좌 기준일 평가 이력과 자산 마감 연동
  • 변경 내용: 독립된 금융 기능을 신규 요구사항으로 정의한다. revision과 문서 상태는 작성/승인 단계에 맞춰 기록하고 #12·구현 PR 미정의 추적성과 각 요구사항/acceptance criterion의 소스·테스트 연결을 둔다. 세 사용자 결정을 하위 요구사항과 인수 기준에 반영하고 구현 준비 여부는 별도로 판정한다.
  • 포함할 내용: 평가 근거 필드와 정확한 금액/NULL/0, 원금 지표 정의 및 중복 합산 금지, exact/as_of/최신 선택과 미래값 배제, 동일 통화·목적 대표값과 정정 체인, idempotency와 다른 payload 충돌·동시 정정·순환 오류, 대사 계산 완전성/시작잔고/투자 대사 불가 상태, 현재값 쓰기 및 import 연동, 마감 근거 고정과 상태/조건부 승인/재마감 불변성, MCP·Dashboard 입력/출력/검증/인증 보존, additive migration·legacy 처리·기존 API 호환성을 요구사항으로 내린다. 회귀 사례는 2026-10-05 평가값의 2026-09-30 조회/마감 배제, exact 누락/as_of 이월, 과거 등록 후 최신 유지, 미확인 원금과 0, 투자 총평가액 중복 방지, 거래 없는 IRP 무허위거래, 증빙 재입력, 정정 및 동시 충돌, 기존 마감 불변과 명시적 재마감, 대출 합산 정의, 기준일 미상 이관 금지, MCP·Dashboard 기존 응답·화면·인증 회귀를 모두 포함한다. 선택된 정책의 인수 기준으로 대출 대표 정의 누락 시 추정 금지와 구성 금액 미확인/중복 합산 방지, 더 최근 미확인 자료 대신 최신 확인된 as_of 후보 선택과 확인 후보 없음 시 미확인 반환, 미확인 경고 후보의 합계 제외, 별도 승인 없는 누락/이월 마감의 미완료 초안 유지, 승인 후 누락 제외/확인된 과거값 이월 및 승인 근거 고정, 승인으로도 미확인/미래/기준일 미상 합산 불가를 추가한다. 이는 사용자 결정을 검증하는 핵심 요청의 acceptance 사례이며 선택적 확장이 아니다. 구현 후 실행할 검증을 새 사용자 결정 공백으로 간주하지 않는다.
  • 제외할 내용: 자동 증권사 연동·종목별 원장·정확한 성과/환율 엔진·새 인증·수기 비계좌 자산 전체 이력 재설계·기존 마감 자동 수정.
  • 근거: 기존 REQ-001/002는 인증과 메뉴 전환이며 이번 금융 이력의 기존 문서가 아니다. 조사한 연속 ID의 다음 값 REQ-003과 exact 신규 경로가 위 revision에서 충돌하지 않는다.

데이터 모델

  • 조치: 신규 작성
  • 경로: docs/data-model.md
  • 변경 내용: 기존 accounts, transactions, manual_assets, asset_snapshots, reconciliation_sessions와 신규 계좌 평가 근거의 관계를 설명한다. 평가 ID/계좌 FK/기준일/대표 금액/통화/종류/출처/확인 상태/등록 시각/증빙 중복키/정정 연결·사유 및 투자·대출 선택 필드, NULL/0와 정확한 저장 단위, 날짜/시간 구분, 계좌·통화·목적·기준일 인덱스와 단일 유효 정정본 불변조건을 명시한다. snapshot run에 valuation 참조와 적용값·분류·출처·확인 상태·누락/이월·마감 상태/승인 근거·버전을 고정하는 관계, 평가 정정과 마감 정정의 분리를 정의한다. 기존 schema 11에서의 additive/idempotent 이관, 기준일 증거 필요성, 미상 날짜/legacy snapshot 처리와 최신 캐시 동기화 책임을 기록한다. 대출 평가에 대표 부채 정의를 필수 저장하고 원금만/원금+이자+수수료를 명시적으로 구분하며 구성 금액 미확인은 NULL/unknown으로 보존한다. 확인된 유효 자료만 기본 as_of 후보가 되는 불변조건과 미확인 후보의 합계 제외를 기록한다. 조건부 마감은 누락 제외·확인 자료 이월·승인자/시각/사유/근거 및 적용/제외 항목을 버전에 고정하고 별도 승인 없이는 미완료 초안임을 정의한다. 미확인/미래/기준일 미상 금액은 조건부 합계에도 포함하지 않는다.
  • 근거: 정본 문서는 부재하며 schema 및 Issue #12의 이력·정정·마감 고정 요구가 영속 데이터 계약을 변경한다.

인터페이스 계약

  • 조치: 갱신
  • 경로: docs/interface-contract.md
  • 변경 내용: 기존 인증·cookie·메뉴 계약을 보존한 채 평가 등록/조회/정정의 계좌 ID·기준일·금액·통화·종류·확인 상태·증빙/idempotency·정정 대상/사유 입력 및 평가 ID/유효본/원금 정의 출력을 추가한다. 기존 자산 보고·preview/close·월정산·대사·현재값 API의 공통 선택 정책, 기본 exact, 실제 기준일·이월 일수·누락/미확인·선택 출처·마감 상태·버전/승인 근거 출력을 정의한다. 잘못된 날짜/종류/통화·미존재 계좌·다른 payload 중복·정정 분기/순환·근거 부족 마감 실패에서 오류와 무변경 상태를 명시한다. 기존 success/error_code/error와 필수 키/타입을 유지하고 필요한 의미 변경/버전 정책을 기록한다. Dashboard는 기존 auth gate를 따르고 MCP는 기존 접근 경계를 유지하며 새 인증을 도입하지 않는다. 대출 등록/정정 입력에는 대표 부채 정의를 필수로 두고 원금만/원금+이자+수수료의 의미와 구성 금액 미확인 출력 및 누락 정의의 무추정 검증을 명시한다. 기본 as_of는 확인된 유효 자료만 합산하고 미확인 경고/후보를 별도 출력한다. 조건부 마감 입력/출력은 누락 제외·확인된 과거값 이월의 명시적 승인과 승인자/시각/사유/근거를 담으며 승인 없이는 미완료 초안, 승인 시 조건부, 모든 필요한 exact 자료 충족 시 완전 마감을 구분한다. 미확인/미래/기준일 미상 금액은 승인으로도 합산하지 않는다. API 코드명과 필드 배치는 후속 계약 작성에서 기존 호환성을 유지해 구체화하고 정책 선택을 다시 열지 않는다.
  • 근거: 기존 MCP server/tool facade·gateway와 보고 응답이 이력 근거를 전달하도록 확장돼야 하며 현재 정본의 인증/메뉴 내용은 변경 대상이 아니다.

프로젝트 구조

  • 조치: 갱신
  • 경로: docs/project-structure.md
  • 변경 내용: 기존 인증/메뉴 source·test·evidence 배치를 유지하고 jarca_ledger_mcp/infrastructure/sqlite/schema.py·migrations.py의 이력/마감 영속 책임, application/assets_service.py·accounts_write_services.py·imports_service.py·reconciliation_service.py·monthly_settlement_service.py의 공통 선택/권위 동기화/대사/마감 책임을 추가한다. service.py·application/asset_account_services.py 호환 facade, adapters/mcp/server.py·tool_contracts.py와 adapters/streamlit/ gateway, 기존 dashboard/page_views/accounts.py·assets.py·monthly_settlement.py 및 관련 tests의 대응을 기록한다. adapter/page → shared application → SQLite 의존과 선택 로직을 각 adapter에 복제하지 않는 규칙, source/test/docs 배치와 개인정보 금지 원칙을 명시한다. 새 내부 모듈이 필요하면 요구사항 계약에 따라 책임·exact 경로를 정하되 별도 제품/마감 엔진을 생성하지 않는다. 대출 대표 정의 필수 검증과 기본 as_of 확인 자료 한정 및 조건부 누락 제외/확인 자료 이월·승인 경계는 공통 application 책임으로 배치하고 MCP/Streamlit adapter는 같은 계약을 전달한다. 각 adapter가 다른 기본값이나 미확인 합산 정책을 만들지 않으며 대응 tests에 세 정책의 경계 사례를 배치한다.
  • 근거: 실제 pinned tree의 application·adapter·SQLite 분리 및 기존 화면을 확장하는 범위다.

런타임 흐름

  • 조치: 갱신
  • 경로: docs/runtime-flow.md
  • 변경 내용: 인증 gate와 메뉴 흐름을 유지하면서 명시적 등록/정정 제출 → 입력 및 증빙 중복 검증 → 단일 트랜잭션 내 append/유효본 확인/최신 캐시 동기화, 읽기 요청 → 날짜·정책별 공통 선택 → 통화/대표값 합산 → 근거/경고 반환, 마감 preview → exact 검증 → 명시적 승인 및 조건부 경계 검증 → 선택 근거와 상태의 원자적 고정, 재마감 → 사유/이전 run 연결 → 새 버전 추가를 기록한다. 월정산 읽기와 대사에서는 같은 기준일과 근거를 사용하고 계산 완전성/수동 투자 대사 불가를 구분한다. 기존 import 최신값 쓰기·기준일 증거 이관의 시작 조건과 실패 복구, idempotency 재시도·동시 정정/마감 충돌·preview 후 근거 변경 시 재검증, 오류 시 부분 쓰기 금지, 민감 값 없는 평가/run 상관 ID 및 실패 유형을 명시한다. 신규 외부 금융기관 호출은 없다. 대출 등록/정정은 대표 부채 정의를 명시적으로 받은 뒤 저장하며 누락된 정의를 추정하지 않는다. 기본 as_of는 확인된 유효 후보만 선택하고 미확인 자료는 경고/후보로 분리해 합산하지 않는다. preview에서 누락/이월이 있으면 별도 승인 전 미완료 초안 상태이며 조건부 저장은 누락 제외·확인된 과거값의 명시적 이월·승인자/시각/사유/근거를 고정한 경우에만 수행한다. 미확인/미래/기준일 미상 금액의 합산은 승인으로도 우회하지 못한다. 선택 자료나 승인 대상이 preview 이후 달라졌다면 기존 재검증 경계로 돌아가며 승인 없이 조건부 저장하지 않는다.
  • 근거: 평가/조회/마감/대사/월정산의 기존 서비스 흐름에 근거 선택과 불변성·충돌 제어가 추가된다.

미해결 질문

없음

<!-- gitea-agent:discovery-draft/v2 --> ## 요약 계좌의 최신 표시값과 특정 기준일의 평가 근거를 분리하고, 기준일 평가 이력의 등록·조회·정정 및 기존 자산 마감·월정산·잔고 대사·Dashboard 연결을 구현한다. Issue #12가 제안한 `account_valuations`와 원금성 선택 필드를 검토한 결과, 현재 계좌 평가 이력에 해당하는 구조는 없으며 기존 `asset_snapshots`는 마감 결과 보존 계층으로 재사용할 수 있다. 새로운 평가 근거 계층과 기존 마감 계층의 책임을 분리하되 공통 선택 로직으로 조회 정책을 일원화한다. 이 문서는 Discovery 초안이며 구현 승인이 아니다. 사용자가 선택한 세 정책을 반영했다. 대출 대표 부채 정의는 평가 기록마다 필수로 명시하고 추정하지 않는다. 기본 `as_of`는 확인된 유효 자료만 선택하며 미확인 자료는 경고/후보로만 반환한다. 조건부 마감은 누락 제외와 확인된 과거값의 명시적 이월만 별도 승인으로 허용한다. 미해결 질문은 없다. ## 문제 - 원본 Issue는 `preview_asset_snapshot_close(basis_date="2026-09-30")`에 2026-10-05 IRP 평가값과 오래된 계좌 잔고가 포함됐다고 보고했다. 실제 운영 DB는 조사하지 않았으며 금액·계좌번호를 수집하지 않았다. - 고정 소스에서 `_account_valuation_items`는 `accounts.last_balance`를 읽고 `last_synced_at`을 `valuation_date`로 표시한다. `_snapshot_preview_from_conn`은 요청 기준일과 무관하게 이 현재값을 합산하고 과거 자료에만 `stale_valuation` 경고를 붙인다. 미래값 제외와 exact 선택 검증이 없다. - `get_asset_snapshot_report`는 해당 날짜의 마감 행이 없으면 현재 계좌·수기 자산값으로 fallback한다. `is_closed_snapshot=False`는 반환하지만 기준일 이하의 근거만 선택하지는 않는다. - `_account_balance_row`는 `balance_after`가 없으면 시작잔고 없는 거래 순증감을 계산값으로 사용한다. `get_balance_reconciliation_report`는 이를 외부 잔고와 비교하므로 거래 없는 투자 계좌도 `REVIEW_NEEDED`가 될 수 있다. - 현재 스키마에는 기준일별 계좌 평가 근거, 원금 정의, 확인 상태, 평가 정정 체인이 없다. 기존 마감의 append-only correction run은 있으나 평가 근거 ID·누락 및 이월·조건부 승인 근거를 충분히 고정하지 않는다. ## 포함 범위 - **평가 근거 이력:** 계좌 FK, `basis_date`, 대표 `amount`, `currency`, `valuation_kind`, `source_type`, `source_ref`, `verification_status`, `recorded_at`, `memo`, `supersedes_id`, `correction_reason` 및 증빙/idempotency 식별자를 저장한다. 기준일과 등록일을 분리하고 날짜 자료에 임의 확인 시각을 만들지 않는다. 시간 자료를 지원하는 경우에만 실제 `as_of_at`과 시간대를 보존한다. - **정확한 금액과 지표:** 기존 원화 정수 원 단위를 보존하고 통화 최소단위 정수 또는 정확한 decimal로 저장한다. NULL과 실제 0을 구분한다. 취득원가 `cost_basis_amount`, 누적 순납입액 `net_contributed_amount`, 기관 표시 `reported_principal_amount`·`reported_principal_kind`·원문 명칭, 표시 손익·수익률 및 `return_basis`를 각각 선택 정보로 관리한다. 정의 미확인은 unknown으로 보존한다. 대출 잔여 원금·미납 이자·수수료를 분리한다. 평가 기록마다 대표 부채가 원금만인지 원금+이자+수수료인지 필수로 명시하며 기본값으로 추정하지 않는다. 구성 금액 미확인도 그대로 표시하고 대표 금액과 구성 금액을 중복 합산하지 않는다. - **공통 선택:** exact는 요청일과 일치하는 확인된 유효 대표값만 사용하고 누락은 미확인으로 반환한다. 월마감 기본은 exact다. `as_of`는 요청일 이하의 최신 유효값을 선택하고 실제 평가일·경과 일수·확인 상태·이월 여부를 반환한다. 기본 `as_of`도 확인된 유효 자료만 선택한다. 미확인 자료는 별도 경고/후보로 반환하되 합산하지 않으며 더 최근 미확인 기록이 확인된 후보를 대체하지 않는다. 미래 자료는 두 정책 모두 제외하고 계좌·통화·평가 목적별 유효 정정본 하나만 합산한다. - **현재값과 과거값:** 뒤늦은 과거 자료 등록이 최신 표시값을 과거로 되돌리지 않아야 한다. 기존 계좌 수정·import 경로의 최신값 쓰기와 새 이력의 권위 관계를 연결하고, 기준일 미상 값을 과거 보고·마감의 확정 자료로 사용하지 않는다. 현재값 호환 표시가 남더라도 출처와 기준일 확인 여부를 명시한다. - **중복 및 정정:** 동일 증빙/idempotency 재입력은 동일 기록을 재사용하고 내용이 다른 충돌은 거부한다. 실제 정정은 append-only로 대상·사유를 연결한다. 다른 계좌·통화·목적을 참조하는 정정, 순환 참조 및 동일 유효본에 대한 동시 분기 정정을 차단한다. `UNIQUE(account_id, basis_date)` 하나로 정정 행 추가를 막지 않는다. - **마감과 월정산:** 기존 `asset_snapshots`·correction run을 보존·확장하여 기준일, 선택한 `valuation_id`, 적용 금액·통화·자산/부채 분류·출처·확인 상태, 누락/이월, 마감 버전과 정정 사유를 고정한다. 평가 최신값 변경·평가 정정·거래 추가로 기존 마감이 자동 변경되지 않으며 명시적인 재마감만 새 버전을 추가한다. 완전한 마감·미완료 초안·승인된 조건부 마감을 구분하고 승인 근거를 보존한다. 조건부 마감에서는 누락 항목을 제외하고 확인된 과거값의 명시적 `as_of` 이월을 별도 승인으로 허용한다. 미확인·미래·기준일 미상 자료는 합산하지 않으며 승인으로 우회할 수 없다. 별도 승인 없이는 미완료 초안에 머문다. 적용/제외 항목·이월 및 승인자/시각/사유/근거를 마감 버전에 보존하고 완전한 exact 마감과 구분한다. - **대사:** 외부 확인값과 장부 계산값을 구분한다. 장부 계산은 검증된 시작잔고·기준시점·거래 포함 범위·완전성과 계산 근거를 표시한다. 투자 총평가액을 거래 순증감으로 대체하지 않고 거래 없는 수동 투자 계좌의 대사 불가·거래 미수입·평가 수동 관리 상태를 구분한다. 가짜 수입·지출·조정 거래를 만들지 않는다. - **MCP·Dashboard:** 평가 등록·조회·정정 기능과 기존 자산 보고·preview/close·대사·현재 자산 조회·월정산을 공통 선택 로직에 연결한다. Dashboard의 계좌·자산/마감·월정산 기존 화면 안에서 최신 평가액/실제 기준일, 이력 등록·조회·정정, 확인 잔고/확인 평가액/잔여 원금 명칭, 원금 정의 미확인 및 누락·이월·조건부 경고를 표시한다. 조회·렌더링은 쓰기를 실행하지 않고 명시적인 사용자 제출만 변경을 수행한다. - **이관 및 검증:** 기준일이 증명된 기존 자료만 이력으로 이관하고 `last_synced_at`을 무조건 실제 기준일로 간주하지 않는다. 기준일 미상 자료는 임의 월말로 소급하지 않는다. 기존 마감과 개인정보 비노출을 보존하고 idempotent additive migration, 기존 API 및 Dashboard 회귀 테스트를 제공한다. ## 제외 범위 - 증권사 자동 연동, 종목별 매매 원장, 정확한 투자 성과 계산 엔진은 원본 요청의 필수 범위가 아니다. - 자동 환율 수집·환산 엔진, 새로운 인증/RBAC, 별도 월정산 제품 또는 기존 금융 데이터의 자동 재작성은 추가하지 않는다. 서로 다른 통화를 근거 없이 같은 금액으로 합산하지 않는다. - 기존 수기 비계좌 자산 전체의 평가 이력 재설계는 확정 범위가 아니다. 기존 경로를 유지하되 preview/close에서 그 자료의 기준일·누락·이월 경고와 정책 적용을 누락하지 않는다. - Discovery 수행 중 코드·스키마·후속 문서 작성, PR 생성, label·assignee·state 변경은 하지 않는다. ## 제약 조건 - 저장소 근거 revision은 `main`의 `5813dd484196239ab1fac4ba066c5b4922fb33e6`이다. 실제 운영 DB 관찰이나 기능 실행 결과를 소스 조사와 혼동하지 않는다. - SQLite schema version 11의 기존 데이터 및 additive/idempotent migration 원칙을 보존한다. 대표값과 모든 부가 원금 지표를 동시에 합산하지 않는다. `loan` 부채를 차감하는 기존 순자산 방향과 금액 정밀도를 유지한다. - 공통 서비스 계층을 MCP와 Streamlit gateway가 공유하는 구조를 유지한다. Dashboard의 기존 fail-closed 인증을 DB 접근보다 앞에 두고 REQ-001 cookie·logout 계약과 REQ-002 메뉴 label/order·공통 shell·명시적 금융 쓰기 계약을 유지한다. MCP에 Dashboard 인증이 적용된다고 주장하지 않는다. - 기존 `success` 및 실패의 `error_code`/`error`, 호출명·기존 인수·응답 필수 키/타입은 가능한 한 유지한다. 현재값을 과거값으로 합산하던 의미 오류는 보존할 계약이 아니다. 필수 변경이 생기면 명시적 호환성·버전 정책과 회귀 검증을 요구사항 및 인터페이스 계약에 기록한다. - 기존 legacy snapshot의 평가 근거를 추측하여 `valuation_id`를 생성하지 않는다. 기존 기록은 legacy 근거로 구분하고 신규 마감만 새 근거 계약을 충족하게 한다. - 실제 계좌번호, 평가액, 증빙 원문 및 credential을 로그·테스트·문서에 기록하지 않는다. 테스트는 synthetic 자료만 사용한다. - 사용자 선택으로 확정된 대출 정의 필수·기본 `as_of` 확인 자료 한정·조건부 누락 제외/확인 자료 이월 정책은 MCP, Dashboard, 공통 선택, 마감 저장/재조회에서 동일하게 적용한다. 미확인·미래·기준일 미상 자료의 합산은 조건부 승인으로도 허용하지 않는다. 이 결정은 새 코드의 구현·실행 성공을 의미하지 않는다. ## 확정된 결정 원본 Issue의 명시 요구와 현재 Discovery에서 사용자가 선택한 결정을 확정 범위로 기록한다. 선택되지 않은 대안은 채택하지 않으며 이 기록은 Discovery 승인이나 구현 handoff가 아니다. 1. 최신값과 기준일 평가 자료를 분리하고 동일 역할 구조가 있으면 재사용한다. 소스 조사상 계좌 평가 이력은 없고 `asset_snapshots`는 마감 계층이므로 마감 구조를 폐기하거나 중복 마감 엔진을 만들지 않는다. `account_valuations`는 제안명이며 물리 테이블명은 요구사항/구현 설계에서 위 계약에 맞춰 정한다. 2. exact를 월마감 기본으로 삼고 미래 기준일 평가값을 exact/as_of 모두에서 제외한다. 누락과 이월을 구분한다. 3. NULL과 0, 취득원가와 순납입액과 기관 표시 원금, 외부 확인값과 장부 계산값을 구분한다. 대표 투자 총평가액만 합산하며 그 안의 현금성 잔액과 원금을 다시 더하지 않는다. 4. 평가 정정·마감 정정은 append-only다. 기존 마감은 불변이며 반영은 사유를 가진 명시적 재마감으로 수행한다. 동일 증빙 중복 및 정정 충돌·순환을 방지한다. 5. 투자 총평가액을 거래 순증감으로 대체하거나 평가 등록을 위해 허위 거래를 만들지 않는다. 6. 기준일 미상 자료를 동기화 시각만으로 소급하지 않고 기존 최신값 호환과 마감 이력을 보존한다. 7. 후속 요구사항은 인증/메뉴와 독립된 금융 기능이므로 새 `REQ-003`을 사용한다. 동일 저장소 Issue 추적성은 #12, 구현 PR은 `미정`으로 기록한다. 승인 상태를 임의로 부여하지 않는다. 8. OQ-001의 선택을 채택한다. 대출 평가 기록마다 대표 부채 정의를 필수로 명시하고 기본값으로 추정하지 않는다. 원금만 또는 원금+이자+수수료를 명시적으로 선택하며 구성 금액 미확인도 그대로 표시한다. 9. OQ-002의 선택을 채택한다. 기본 `as_of`도 확인된 유효 자료만 선택하고 미확인 자료는 별도 경고/후보로 반환하되 합산하지 않는다. 10. OQ-003의 선택을 채택한다. 조건부 마감은 누락 제외와 확인된 과거값의 명시적 `as_of` 이월만 별도 승인으로 허용한다. 미확인·미래·기준일 미상 자료는 합산하지 않고 승인 없이는 미완료 초안에 머문다. 승인자/시각/사유/근거와 적용/제외 항목·이월을 마감 버전에 고정한다. ## 저장소 근거 모든 경로는 대상 저장소의 위 exact revision에서 이번 review로 다시 조사했다. 세 사용자 선택은 기존 기능이 이미 지원한다는 증거가 아니라 신규 데이터/선택/승인 검증 계약이다. 현재 SQLite 스키마·additive migration·공통 application 및 adapter 경로에서 해당 계약을 추가할 위치를 확인했다. 별도 API·dependency·runtime·배포 기능을 전제로 하는 결정은 없으며 기술적 전제의 실행 실험을 요구할 근거는 확인되지 않았다. 실제 신규 구현과 회귀 검증은 후속 단계에서 수행해야 한다. - `jarca_ledger_mcp/infrastructure/sqlite/schema.py`: schema version 11, `accounts.last_balance/last_synced_at`, `manual_assets`, `asset_snapshots`와 run 정정 필드는 존재한다. 계좌별 평가 이력 테이블·평가 근거 FK·원금 정의 필드는 없다. - `jarca_ledger_mcp/infrastructure/sqlite/migrations.py`: `migrate_db`는 additive/idempotent migration 및 snapshot correction 필드 보강을 수행한다. - `jarca_ledger_mcp/application/assets_service.py`: `_valuation_policy`, `_account_valuation_items`, `_manual_asset_valuation_items`, `_snapshot_preview_from_conn`, `get_asset_snapshot_report`, `close_asset_snapshot`, `_snapshot_rows_for_latest_run`, `_summarize_valuation_items`를 조사했다. 현재값 권위, stale 경고, 미마감 fallback, append-only run과 `asset_buckets - loan` 계산을 확인했다. - `jarca_ledger_mcp/application/reconciliation_service.py`: `_account_balance_row`의 `net_transaction_delta_without_opening_balance`와 `get_balance_reconciliation_report`의 `OK/REVIEW_NEEDED/BASELINE_REQUIRED` 판정이 존재한다. 투자 총평가액의 별도 대사 가능성 판정은 없다. - `jarca_ledger_mcp/application/monthly_settlement_service.py`: `get_monthly_settlement_summary`는 월말의 자산 보고와 별도 대사 보고를 읽어 요약하며 `read_only=True`를 반환한다. 월정산 전용 저장 엔진은 확인되지 않았다. - `jarca_ledger_mcp/application/accounts_write_services.py`, `jarca_ledger_mcp/application/imports_service.py`: 계좌 생성·수정 및 import가 `last_balance/last_synced_at`을 직접 쓴다. 이 경로를 무시한 새 이력만 추가하면 권위 자료가 이중 관리된다. - `jarca_ledger_mcp/service.py`, `jarca_ledger_mcp/application/asset_account_services.py`, `jarca_ledger_mcp/adapters/mcp/server.py`, `jarca_ledger_mcp/adapters/mcp/tool_contracts.py`, `jarca_ledger_mcp/adapters/streamlit/assets_gateway.py`, `jarca_ledger_mcp/adapters/streamlit/accounts_gateway.py`, `jarca_ledger_mcp/adapters/streamlit/overview_gateway.py`: 기존 공개 facade·MCP 도구·Streamlit gateway 연결 경로다. - `dashboard/app.py`, `dashboard/page_views/accounts.py`, `dashboard/page_views/assets.py`, `dashboard/page_views/monthly_settlement.py`: 인증 후 기존 화면을 dispatch한다. 계좌 화면은 최신 잔고·동기화 시각을 수정하고 자산 화면은 preview/close를 제공하며 월정산 화면은 읽기 전용이다. - `tests/test_asset_snapshots.py`: additive migration, 기존 현재값 fallback, 합산 및 append-only 마감 정정 테스트가 있다. `tests/test_contract_regression.py`, `tests/contract_snapshots/response_contract_v1_0.json`: preview/close 필수 응답 키와 타입 및 additive/breaking 변경 정책이 존재한다. 테스트는 읽었으며 이번 Discovery에서 실행하지 않았다. - `docs/requirements/req-001_dashboard-administrator-authentication.md`, `docs/requirements/req-002_dashboard-menu-transition.md`: 기존 ID는 REQ-001·REQ-002이며 연속·중복 없음 및 파일명/본문 ID 일치를 확인했다. 이번 계좌 평가 기능의 기존 요구사항 문서는 없다. 소스 주석의 REQ-005는 실제 요구사항 파일의 존재나 ID 할당 근거로 사용하지 않는다. - `docs/interface-contract.md`, `docs/project-structure.md`, `docs/runtime-flow.md`는 현재 인증 및 메뉴 계약을 담는다. `docs/data-model.md`는 존재하지 않는다. 후속 금융 계약은 기존 공통 문서에 추가하고 기존 내용을 유지해야 한다. ## 문서 영향 및 산출물 ### 요구사항명세서 - 조치: 신규 작성 - 경로: `docs/requirements/req-003_account-valuation-history.md` - 문서 ID: `REQ-003` - 제목: 계좌 기준일 평가 이력과 자산 마감 연동 - 변경 내용: 독립된 금융 기능을 신규 요구사항으로 정의한다. revision과 문서 상태는 작성/승인 단계에 맞춰 기록하고 #12·구현 PR `미정`의 추적성과 각 요구사항/acceptance criterion의 소스·테스트 연결을 둔다. 세 사용자 결정을 하위 요구사항과 인수 기준에 반영하고 구현 준비 여부는 별도로 판정한다. - 포함할 내용: 평가 근거 필드와 정확한 금액/NULL/0, 원금 지표 정의 및 중복 합산 금지, exact/as_of/최신 선택과 미래값 배제, 동일 통화·목적 대표값과 정정 체인, idempotency와 다른 payload 충돌·동시 정정·순환 오류, 대사 계산 완전성/시작잔고/투자 대사 불가 상태, 현재값 쓰기 및 import 연동, 마감 근거 고정과 상태/조건부 승인/재마감 불변성, MCP·Dashboard 입력/출력/검증/인증 보존, additive migration·legacy 처리·기존 API 호환성을 요구사항으로 내린다. 회귀 사례는 2026-10-05 평가값의 2026-09-30 조회/마감 배제, exact 누락/as_of 이월, 과거 등록 후 최신 유지, 미확인 원금과 0, 투자 총평가액 중복 방지, 거래 없는 IRP 무허위거래, 증빙 재입력, 정정 및 동시 충돌, 기존 마감 불변과 명시적 재마감, 대출 합산 정의, 기준일 미상 이관 금지, MCP·Dashboard 기존 응답·화면·인증 회귀를 모두 포함한다. 선택된 정책의 인수 기준으로 대출 대표 정의 누락 시 추정 금지와 구성 금액 미확인/중복 합산 방지, 더 최근 미확인 자료 대신 최신 확인된 `as_of` 후보 선택과 확인 후보 없음 시 미확인 반환, 미확인 경고 후보의 합계 제외, 별도 승인 없는 누락/이월 마감의 미완료 초안 유지, 승인 후 누락 제외/확인된 과거값 이월 및 승인 근거 고정, 승인으로도 미확인/미래/기준일 미상 합산 불가를 추가한다. 이는 사용자 결정을 검증하는 핵심 요청의 acceptance 사례이며 선택적 확장이 아니다. 구현 후 실행할 검증을 새 사용자 결정 공백으로 간주하지 않는다. - 제외할 내용: 자동 증권사 연동·종목별 원장·정확한 성과/환율 엔진·새 인증·수기 비계좌 자산 전체 이력 재설계·기존 마감 자동 수정. - 근거: 기존 REQ-001/002는 인증과 메뉴 전환이며 이번 금융 이력의 기존 문서가 아니다. 조사한 연속 ID의 다음 값 REQ-003과 exact 신규 경로가 위 revision에서 충돌하지 않는다. ### 데이터 모델 - 조치: 신규 작성 - 경로: `docs/data-model.md` - 변경 내용: 기존 `accounts`, `transactions`, `manual_assets`, `asset_snapshots`, `reconciliation_sessions`와 신규 계좌 평가 근거의 관계를 설명한다. 평가 ID/계좌 FK/기준일/대표 금액/통화/종류/출처/확인 상태/등록 시각/증빙 중복키/정정 연결·사유 및 투자·대출 선택 필드, NULL/0와 정확한 저장 단위, 날짜/시간 구분, 계좌·통화·목적·기준일 인덱스와 단일 유효 정정본 불변조건을 명시한다. snapshot run에 valuation 참조와 적용값·분류·출처·확인 상태·누락/이월·마감 상태/승인 근거·버전을 고정하는 관계, 평가 정정과 마감 정정의 분리를 정의한다. 기존 schema 11에서의 additive/idempotent 이관, 기준일 증거 필요성, 미상 날짜/legacy snapshot 처리와 최신 캐시 동기화 책임을 기록한다. 대출 평가에 대표 부채 정의를 필수 저장하고 원금만/원금+이자+수수료를 명시적으로 구분하며 구성 금액 미확인은 NULL/unknown으로 보존한다. 확인된 유효 자료만 기본 `as_of` 후보가 되는 불변조건과 미확인 후보의 합계 제외를 기록한다. 조건부 마감은 누락 제외·확인 자료 이월·승인자/시각/사유/근거 및 적용/제외 항목을 버전에 고정하고 별도 승인 없이는 미완료 초안임을 정의한다. 미확인/미래/기준일 미상 금액은 조건부 합계에도 포함하지 않는다. - 근거: 정본 문서는 부재하며 schema 및 Issue #12의 이력·정정·마감 고정 요구가 영속 데이터 계약을 변경한다. ### 인터페이스 계약 - 조치: 갱신 - 경로: `docs/interface-contract.md` - 변경 내용: 기존 인증·cookie·메뉴 계약을 보존한 채 평가 등록/조회/정정의 계좌 ID·기준일·금액·통화·종류·확인 상태·증빙/idempotency·정정 대상/사유 입력 및 평가 ID/유효본/원금 정의 출력을 추가한다. 기존 자산 보고·preview/close·월정산·대사·현재값 API의 공통 선택 정책, 기본 exact, 실제 기준일·이월 일수·누락/미확인·선택 출처·마감 상태·버전/승인 근거 출력을 정의한다. 잘못된 날짜/종류/통화·미존재 계좌·다른 payload 중복·정정 분기/순환·근거 부족 마감 실패에서 오류와 무변경 상태를 명시한다. 기존 `success/error_code/error`와 필수 키/타입을 유지하고 필요한 의미 변경/버전 정책을 기록한다. Dashboard는 기존 auth gate를 따르고 MCP는 기존 접근 경계를 유지하며 새 인증을 도입하지 않는다. 대출 등록/정정 입력에는 대표 부채 정의를 필수로 두고 원금만/원금+이자+수수료의 의미와 구성 금액 미확인 출력 및 누락 정의의 무추정 검증을 명시한다. 기본 `as_of`는 확인된 유효 자료만 합산하고 미확인 경고/후보를 별도 출력한다. 조건부 마감 입력/출력은 누락 제외·확인된 과거값 이월의 명시적 승인과 승인자/시각/사유/근거를 담으며 승인 없이는 미완료 초안, 승인 시 조건부, 모든 필요한 exact 자료 충족 시 완전 마감을 구분한다. 미확인/미래/기준일 미상 금액은 승인으로도 합산하지 않는다. API 코드명과 필드 배치는 후속 계약 작성에서 기존 호환성을 유지해 구체화하고 정책 선택을 다시 열지 않는다. - 근거: 기존 MCP server/tool facade·gateway와 보고 응답이 이력 근거를 전달하도록 확장돼야 하며 현재 정본의 인증/메뉴 내용은 변경 대상이 아니다. ### 프로젝트 구조 - 조치: 갱신 - 경로: `docs/project-structure.md` - 변경 내용: 기존 인증/메뉴 source·test·evidence 배치를 유지하고 `jarca_ledger_mcp/infrastructure/sqlite/schema.py`·`migrations.py`의 이력/마감 영속 책임, `application/assets_service.py`·`accounts_write_services.py`·`imports_service.py`·`reconciliation_service.py`·`monthly_settlement_service.py`의 공통 선택/권위 동기화/대사/마감 책임을 추가한다. `service.py`·`application/asset_account_services.py` 호환 facade, `adapters/mcp/server.py`·`tool_contracts.py`와 `adapters/streamlit/` gateway, 기존 `dashboard/page_views/accounts.py`·`assets.py`·`monthly_settlement.py` 및 관련 tests의 대응을 기록한다. adapter/page → shared application → SQLite 의존과 선택 로직을 각 adapter에 복제하지 않는 규칙, source/test/docs 배치와 개인정보 금지 원칙을 명시한다. 새 내부 모듈이 필요하면 요구사항 계약에 따라 책임·exact 경로를 정하되 별도 제품/마감 엔진을 생성하지 않는다. 대출 대표 정의 필수 검증과 기본 `as_of` 확인 자료 한정 및 조건부 누락 제외/확인 자료 이월·승인 경계는 공통 application 책임으로 배치하고 MCP/Streamlit adapter는 같은 계약을 전달한다. 각 adapter가 다른 기본값이나 미확인 합산 정책을 만들지 않으며 대응 tests에 세 정책의 경계 사례를 배치한다. - 근거: 실제 pinned tree의 application·adapter·SQLite 분리 및 기존 화면을 확장하는 범위다. ### 런타임 흐름 - 조치: 갱신 - 경로: `docs/runtime-flow.md` - 변경 내용: 인증 gate와 메뉴 흐름을 유지하면서 명시적 등록/정정 제출 → 입력 및 증빙 중복 검증 → 단일 트랜잭션 내 append/유효본 확인/최신 캐시 동기화, 읽기 요청 → 날짜·정책별 공통 선택 → 통화/대표값 합산 → 근거/경고 반환, 마감 preview → exact 검증 → 명시적 승인 및 조건부 경계 검증 → 선택 근거와 상태의 원자적 고정, 재마감 → 사유/이전 run 연결 → 새 버전 추가를 기록한다. 월정산 읽기와 대사에서는 같은 기준일과 근거를 사용하고 계산 완전성/수동 투자 대사 불가를 구분한다. 기존 import 최신값 쓰기·기준일 증거 이관의 시작 조건과 실패 복구, idempotency 재시도·동시 정정/마감 충돌·preview 후 근거 변경 시 재검증, 오류 시 부분 쓰기 금지, 민감 값 없는 평가/run 상관 ID 및 실패 유형을 명시한다. 신규 외부 금융기관 호출은 없다. 대출 등록/정정은 대표 부채 정의를 명시적으로 받은 뒤 저장하며 누락된 정의를 추정하지 않는다. 기본 `as_of`는 확인된 유효 후보만 선택하고 미확인 자료는 경고/후보로 분리해 합산하지 않는다. preview에서 누락/이월이 있으면 별도 승인 전 미완료 초안 상태이며 조건부 저장은 누락 제외·확인된 과거값의 명시적 이월·승인자/시각/사유/근거를 고정한 경우에만 수행한다. 미확인/미래/기준일 미상 금액의 합산은 승인으로도 우회하지 못한다. 선택 자료나 승인 대상이 preview 이후 달라졌다면 기존 재검증 경계로 돌아가며 승인 없이 조건부 저장하지 않는다. - 근거: 평가/조회/마감/대사/월정산의 기존 서비스 흐름에 근거 선택과 불변성·충돌 제어가 추가된다. ## 미해결 질문 없음
Owner

Discovery 작성 전 이슈 원본

목적

계좌의 최신 잔고와 특정 기준일의 잔고·평가액을 분리하여, 과거 자산 조회 및 월말 마감을 정확하게 지원한다.

account_valuations는 구현 제안이다. 기존 스키마와 평가·마감 로직을 먼저 확인하고, 동일 역할의 구조가 있다면 확장하거나 통합한다.

확인된 문제

  1. preview_asset_snapshot_close(basis_date="2026-09-30") 호출 결과에 2026-10-05 기준 IRP 평가액이 포함되었다.
  2. 여러 계좌의 오래된 잔고도 마감 미리보기에 포함되었다.
  3. 현재 accounts.last_balance를 과거 기준일의 평가 자료로 그대로 사용해서는 안 된다.
  4. get_balance_reconciliation_report는 거래 없는 수동 관리 IRP 계좌의 거래 순증감 0을 평가액과 비교하여 REVIEW_NEEDED로 표시했다.
    • 반환된 계산 방식: net_transaction_delta_without_opening_balance
    • 이를 실제 장부 오류나 누락 수입으로 오인하지 않도록 구분이 필요하다.

개인정보 최소화를 위해 실제 계좌번호 및 평가액은 이슈에서 생략한다.

1. 계좌별 기준일 평가 이력

가칭 account_valuations에 다음 정보를 저장한다.

공통 필드

  • id
  • account_id: 계좌 FK
  • basis_date: 금액이 유효한 기준일
  • amount: 자산·부채 합산에 사용하는 대표 금액
  • currency
  • valuation_kind: 현금 잔고 / 계좌 총평가액 / 대출 잔여 원금 등
  • source_type: 앱 화면 / 잔고증명 / 거래내역 / 장부 계산 등
  • source_ref: 증빙 자료 식별자
  • verification_status: 미확인 / 확인 완료 등
  • recorded_at: 실제 등록 시각
  • memo
  • supersedes_id: 정정 대상 기록
  • correction_reason: 정정 사유
  • 중복 등록 방지용 자료 식별자 또는 idempotency key

저장 원칙

  • 기준일과 등록일을 분리한다.
  • 시간 단위 자료가 필요하면 as_of_at 및 시간대를 추가한다.
  • 날짜만 있는 자료에 임의의 확인 시각을 부여하지 않는다.
  • 금액은 통화 최소단위 정수 또는 정확한 decimal로 저장한다.
  • 정보 없음은 NULL, 실제 0은 0으로 구분한다.
  • 대표 합산값을 명확히 하여 평가액·원금·현금성 잔액의 중복 합산을 방지한다.
  • 계좌별 기준일 조회를 위한 인덱스를 추가한다.

2. 원금 및 투자 관련 정보

단일 principal_amount로 모든 계좌의 원금을 표현하지 않는다.

투자 계좌 선택 필드

  • cost_basis_amount: 현재 보유자산의 취득원가
  • net_contributed_amount: 누적 순납입액
  • reported_principal_amount: 금융기관이 표시한 원금성 금액
  • reported_principal_kind: 금융기관 표시 금액의 정의; unknown 허용
  • 금융기관 표시 금액의 원문 명칭
  • reported_profit_amount: 금융기관이 표시한 손익
  • reported_return_rate: 금융기관이 표시한 수익률
    -return_basis: 수익률의 계산 기준 및 기간

취득원가와 누적 순납입액은 서로 다른 지표다. 금융기관 화면의 ‘잔액’을 확인 없이 취득원가나 순납입액으로 확정하지 않는다.

원금성 금액의 정의가 확인되지 않았다면 원문과 금액을 보존하고 미확인 상태로 둔다.

대출 계좌 선택 필드

  • outstanding_principal_amount: 기준일 잔여 원금
  • accrued_interest_amount: 기준일 발생·미납 이자
  • outstanding_fee_amount: 기준일 미납 수수료

대표 amount가 원금만 의미하는지, 이자·수수료를 포함한 부채인지 명시한다.

최초 대출 실행 원금은 별도 대출 상세정보에 저장하는 것을 권장한다. 추가 대출·대환 등은 변경 이력으로 관리한다.

합산 원칙

  • 투자자산에는 대표 총평가액만 합산한다.
  • 취득원가·순납입액·표시 원금은 추가 자산으로 합산하지 않는다.
  • 총평가액에 포함된 현금성 잔액을 다시 더하지 않는다.
  • 투자 성과의 계산 기준·기간이 미확인이라면 추정값을 확정 수익률로 표시하지 않는다.

3. 기준일 조회 정책

exact

  • 요청 기준일과 일치하는 확인된 유효 평가값만 사용한다.
  • 자료가 없으면 ‘해당 기준일 평가액 미확인’을 반환한다.
  • 월마감의 기본 조회 정책으로 사용한다.

as_of

  • 요청 기준일 이하의 유효 자료 중 가장 최근 값을 선택한다.
  • 실제 평가일, 경과 일수, 확인 상태, 이월 여부를 반환한다.
  • 이월값을 해당 날짜에 확인한 값처럼 표시하지 않는다.

공통 규칙

  • 요청 기준일 이후의 평가값은 선택하지 않는다.
  • 과거 날짜 자료를 뒤늦게 등록해도 계좌의 최신 평가값이 과거값으로 돌아가지 않는다.
  • 정정 버전이 있으면 기준일별 유효 정정본을 선택한다.
  • 동일 통화·평가 목적의 대표값 선택 규칙을 명시한다.

4. 거래 장부 및 잔고 대사와의 관계

외부 확인값과 장부 계산값을 구분한다.

외부 확인값

은행·증권사 증빙에서 확인한 잔고 또는 평가액이다.

장부 계산값

검증된 시작잔고와 이후 거래를 이용하여 계산한 금액이다.

  • 시작잔고 기준시점과 거래 포함 범위를 명시한다.
  • 자료 완전성 및 계산 근거를 표시한다.
  • 거래가 추가되면 계산 결과가 달라질 수 있다.
  • 외부 확인 증빙과 이미 확정된 마감 기록을 자동 수정하지 않는다.

투자 계좌

  • IRP·증권 계좌의 총평가액을 거래 순증감으로 대체하지 않는다.
  • 거래가 0건인 수동 관리 투자 계좌를 곧바로 장부 오류로 판정하지 않는다.
  • 대사 불가 / 거래 미수입 / 평가액 수동 관리 상태를 구분한다.
  • 평가액 또는 원금을 등록하기 위해 가짜 수입·지출 거래를 생성하지 않는다.

5. 중복 방지 및 정정 이력

  • 같은 증빙 재등록은 idempotency로 중복을 차단한다.
  • 실제 금액 정정은 기존 기록을 덮어쓰지 않고 새 기록을 추가한다.
  • 정정 대상과 사유를 연결한다.
  • 동일 기준일의 유효 버전 선택 규칙을 정의한다.
  • 동시 정정 충돌 및 순환 정정 참조를 방지한다.
  • 단순 UNIQUE(account_id, basis_date)로 정정 이력 추가를 막지 않는다.

6. 월정산 연동

월마감은 합계뿐 아니라 사용한 평가 자료를 고정한다.

보존할 정보

  • 마감 기준일
  • 계좌별 valuation_id
  • 적용 금액 및 통화
  • 적용한 자산·부채 분류
  • 출처와 확인 상태
  • 누락 및 이월 자료 여부
  • 마감 버전
  • 정정 사유

동작 원칙

  • 최신 계좌 평가액이 바뀌어도 기존 월마감은 자동 변경되지 않는다.
  • 평가 이력이 정정되어도 기존 마감은 유지한다.
  • 반영하려면 명시적인 재마감으로 정정 버전을 추가한다.
  • 누락·오래된 평가액·미확인·미래 기준일 자료를 미리보기에서 검증한다.
  • 완전한 마감, 미완료 초안, 사용자가 승인한 조건부 마감을 구분한다.
  • 조건부 마감 시 누락·이월 항목과 승인 근거를 보존한다.

7. MCP 및 대시보드

MCP

평가 이력의 등록·조회·정정 기능을 제공한다.

다음 기능을 공통 평가 선택 로직에 연결한다.

  • 기준일 자산 보고
  • 월마감 미리보기
  • 월마감 저장
  • 잔고 대사
  • 현재 자산 조회

과거 보고서에서 현재값을 fallback으로 사용할 경우, 이를 확정된 과거 스냅샷처럼 표시하지 않는다. 응답에 자료 출처와 마감 여부를 명시한다.

대시보드

  • 계좌별 최신 평가액과 실제 기준일 표시
  • 평가 이력 등록·조회·정정
  • 금액 종류에 따른 명칭:
    • 확인 잔고
    • 확인 평가액
    • 잔여 원금
  • 투자 원금 정보의 정의 및 미확인 상태 표시
  • 월정산의 누락·이월·조건부 마감 경고 표시

8. 마이그레이션 및 호환성

  • 기존 accounts.last_balance, last_synced_at의 의미를 확인한 뒤 이관한다.
  • 기준일이 확인되는 자료만 해당 날짜의 평가 이력으로 이관한다.
  • 동기화 시각을 실제 평가 기준일로 무조건 간주하지 않는다.
  • 기준일 미상 자료를 임의 월말로 소급하지 않는다.
  • 기존 최신값 필드는 호환 캐시 또는 최신 이력 기반 조회로 유지할 수 있다.
  • 평가 이력을 권위 자료로 일원화하고 이중 관리 불일치를 방지한다.
  • 기존 월마감 이력은 보존한다.
  • 스키마 마이그레이션 및 기존 API 호환성 테스트를 제공한다.

범위 제외

다음은 이번 요청의 필수 범위가 아니다.

  • 증권사 자동 연동
  • 종목별 매매 원장
  • 정확한 투자 성과 계산 엔진

수락 기준 및 회귀 테스트

  • 10월 5일 투자 평가액이 9월 30일 exact/as_of 조회 및 마감에 포함되지 않는다.
  • exact 누락과 as_of 이월을 구분하고 실제 평가 기준일을 반환한다.
  • 과거 자료 등록 후에도 현재 최신 평가값은 유지된다.
  • 취득원가·순납입액·금융기관 표시 잔액을 구분한다.
  • 미확인 금액과 실제 0원을 구분한다.
  • 평가액·원금·현금성 잔액을 중복 합산하지 않는다.
  • 거래 없는 수동 투자 계좌에 허위 수입이나 장부 오류를 생성하지 않는다.
  • 동일 증빙 재입력의 중복을 차단한다.
  • 정정 이력과 유효 정정본 선택을 검증한다.
  • 최신 평가 갱신·정정 후에도 기존 월마감은 불변이다.
  • 재마감은 정정 버전과 사유를 추가한다.
  • 대출 원금·이자·수수료의 부채 합산 정책을 검증한다.
  • 기준일 미상 기존 자료를 임의 날짜로 소급하지 않는다.
  • MCP·대시보드·기존 자산 보고의 호환성 테스트를 제공한다.
<!-- gitea-agent:discovery-origin/v1 owner=jsfamily repository=jarca-ledger-mcp issue=12 body-sha256=008f57afb4428fb0c8d077ec5b840f6dc34a6e99f04ef5bd385bcf38592bd5e4 --> ## Discovery 작성 전 이슈 원본 ## 목적 계좌의 최신 잔고와 특정 기준일의 잔고·평가액을 분리하여, 과거 자산 조회 및 월말 마감을 정확하게 지원한다. `account_valuations`는 구현 제안이다. 기존 스키마와 평가·마감 로직을 먼저 확인하고, 동일 역할의 구조가 있다면 확장하거나 통합한다. ## 확인된 문제 1. `preview_asset_snapshot_close(basis_date="2026-09-30")` 호출 결과에 2026-10-05 기준 IRP 평가액이 포함되었다. 2. 여러 계좌의 오래된 잔고도 마감 미리보기에 포함되었다. 3. 현재 `accounts.last_balance`를 과거 기준일의 평가 자료로 그대로 사용해서는 안 된다. 4. `get_balance_reconciliation_report`는 거래 없는 수동 관리 IRP 계좌의 거래 순증감 0을 평가액과 비교하여 `REVIEW_NEEDED`로 표시했다. - 반환된 계산 방식: `net_transaction_delta_without_opening_balance` - 이를 실제 장부 오류나 누락 수입으로 오인하지 않도록 구분이 필요하다. 개인정보 최소화를 위해 실제 계좌번호 및 평가액은 이슈에서 생략한다. ## 1. 계좌별 기준일 평가 이력 가칭 `account_valuations`에 다음 정보를 저장한다. ### 공통 필드 - `id` - `account_id`: 계좌 FK - `basis_date`: 금액이 유효한 기준일 - `amount`: 자산·부채 합산에 사용하는 대표 금액 - `currency` - `valuation_kind`: 현금 잔고 / 계좌 총평가액 / 대출 잔여 원금 등 - `source_type`: 앱 화면 / 잔고증명 / 거래내역 / 장부 계산 등 - `source_ref`: 증빙 자료 식별자 - `verification_status`: 미확인 / 확인 완료 등 - `recorded_at`: 실제 등록 시각 - `memo` - `supersedes_id`: 정정 대상 기록 - `correction_reason`: 정정 사유 - 중복 등록 방지용 자료 식별자 또는 idempotency key ### 저장 원칙 - 기준일과 등록일을 분리한다. - 시간 단위 자료가 필요하면 `as_of_at` 및 시간대를 추가한다. - 날짜만 있는 자료에 임의의 확인 시각을 부여하지 않는다. - 금액은 통화 최소단위 정수 또는 정확한 decimal로 저장한다. - 정보 없음은 NULL, 실제 0은 0으로 구분한다. - 대표 합산값을 명확히 하여 평가액·원금·현금성 잔액의 중복 합산을 방지한다. - 계좌별 기준일 조회를 위한 인덱스를 추가한다. ## 2. 원금 및 투자 관련 정보 단일 `principal_amount`로 모든 계좌의 원금을 표현하지 않는다. ### 투자 계좌 선택 필드 - `cost_basis_amount`: 현재 보유자산의 취득원가 - `net_contributed_amount`: 누적 순납입액 - `reported_principal_amount`: 금융기관이 표시한 원금성 금액 - `reported_principal_kind`: 금융기관 표시 금액의 정의; unknown 허용 - 금융기관 표시 금액의 원문 명칭 - `reported_profit_amount`: 금융기관이 표시한 손익 - `reported_return_rate`: 금융기관이 표시한 수익률 -`return_basis`: 수익률의 계산 기준 및 기간 취득원가와 누적 순납입액은 서로 다른 지표다. 금융기관 화면의 ‘잔액’을 확인 없이 취득원가나 순납입액으로 확정하지 않는다. 원금성 금액의 정의가 확인되지 않았다면 원문과 금액을 보존하고 미확인 상태로 둔다. ### 대출 계좌 선택 필드 - `outstanding_principal_amount`: 기준일 잔여 원금 - `accrued_interest_amount`: 기준일 발생·미납 이자 - `outstanding_fee_amount`: 기준일 미납 수수료 대표 `amount`가 원금만 의미하는지, 이자·수수료를 포함한 부채인지 명시한다. 최초 대출 실행 원금은 별도 대출 상세정보에 저장하는 것을 권장한다. 추가 대출·대환 등은 변경 이력으로 관리한다. ### 합산 원칙 - 투자자산에는 대표 총평가액만 합산한다. - 취득원가·순납입액·표시 원금은 추가 자산으로 합산하지 않는다. - 총평가액에 포함된 현금성 잔액을 다시 더하지 않는다. - 투자 성과의 계산 기준·기간이 미확인이라면 추정값을 확정 수익률로 표시하지 않는다. ## 3. 기준일 조회 정책 ### exact - 요청 기준일과 일치하는 확인된 유효 평가값만 사용한다. - 자료가 없으면 ‘해당 기준일 평가액 미확인’을 반환한다. - 월마감의 기본 조회 정책으로 사용한다. ### as_of - 요청 기준일 이하의 유효 자료 중 가장 최근 값을 선택한다. - 실제 평가일, 경과 일수, 확인 상태, 이월 여부를 반환한다. - 이월값을 해당 날짜에 확인한 값처럼 표시하지 않는다. ### 공통 규칙 - 요청 기준일 이후의 평가값은 선택하지 않는다. - 과거 날짜 자료를 뒤늦게 등록해도 계좌의 최신 평가값이 과거값으로 돌아가지 않는다. - 정정 버전이 있으면 기준일별 유효 정정본을 선택한다. - 동일 통화·평가 목적의 대표값 선택 규칙을 명시한다. ## 4. 거래 장부 및 잔고 대사와의 관계 외부 확인값과 장부 계산값을 구분한다. ### 외부 확인값 은행·증권사 증빙에서 확인한 잔고 또는 평가액이다. ### 장부 계산값 검증된 시작잔고와 이후 거래를 이용하여 계산한 금액이다. - 시작잔고 기준시점과 거래 포함 범위를 명시한다. - 자료 완전성 및 계산 근거를 표시한다. - 거래가 추가되면 계산 결과가 달라질 수 있다. - 외부 확인 증빙과 이미 확정된 마감 기록을 자동 수정하지 않는다. ### 투자 계좌 - IRP·증권 계좌의 총평가액을 거래 순증감으로 대체하지 않는다. - 거래가 0건인 수동 관리 투자 계좌를 곧바로 장부 오류로 판정하지 않는다. - 대사 불가 / 거래 미수입 / 평가액 수동 관리 상태를 구분한다. - 평가액 또는 원금을 등록하기 위해 가짜 수입·지출 거래를 생성하지 않는다. ## 5. 중복 방지 및 정정 이력 - 같은 증빙 재등록은 idempotency로 중복을 차단한다. - 실제 금액 정정은 기존 기록을 덮어쓰지 않고 새 기록을 추가한다. - 정정 대상과 사유를 연결한다. - 동일 기준일의 유효 버전 선택 규칙을 정의한다. - 동시 정정 충돌 및 순환 정정 참조를 방지한다. - 단순 `UNIQUE(account_id, basis_date)`로 정정 이력 추가를 막지 않는다. ## 6. 월정산 연동 월마감은 합계뿐 아니라 사용한 평가 자료를 고정한다. ### 보존할 정보 - 마감 기준일 - 계좌별 `valuation_id` - 적용 금액 및 통화 - 적용한 자산·부채 분류 - 출처와 확인 상태 - 누락 및 이월 자료 여부 - 마감 버전 - 정정 사유 ### 동작 원칙 - 최신 계좌 평가액이 바뀌어도 기존 월마감은 자동 변경되지 않는다. - 평가 이력이 정정되어도 기존 마감은 유지한다. - 반영하려면 명시적인 재마감으로 정정 버전을 추가한다. - 누락·오래된 평가액·미확인·미래 기준일 자료를 미리보기에서 검증한다. - 완전한 마감, 미완료 초안, 사용자가 승인한 조건부 마감을 구분한다. - 조건부 마감 시 누락·이월 항목과 승인 근거를 보존한다. ## 7. MCP 및 대시보드 ### MCP 평가 이력의 등록·조회·정정 기능을 제공한다. 다음 기능을 공통 평가 선택 로직에 연결한다. - 기준일 자산 보고 - 월마감 미리보기 - 월마감 저장 - 잔고 대사 - 현재 자산 조회 과거 보고서에서 현재값을 fallback으로 사용할 경우, 이를 확정된 과거 스냅샷처럼 표시하지 않는다. 응답에 자료 출처와 마감 여부를 명시한다. ### 대시보드 - 계좌별 최신 평가액과 실제 기준일 표시 - 평가 이력 등록·조회·정정 - 금액 종류에 따른 명칭: - 확인 잔고 - 확인 평가액 - 잔여 원금 - 투자 원금 정보의 정의 및 미확인 상태 표시 - 월정산의 누락·이월·조건부 마감 경고 표시 ## 8. 마이그레이션 및 호환성 - 기존 `accounts.last_balance`, `last_synced_at`의 의미를 확인한 뒤 이관한다. - 기준일이 확인되는 자료만 해당 날짜의 평가 이력으로 이관한다. - 동기화 시각을 실제 평가 기준일로 무조건 간주하지 않는다. - 기준일 미상 자료를 임의 월말로 소급하지 않는다. - 기존 최신값 필드는 호환 캐시 또는 최신 이력 기반 조회로 유지할 수 있다. - 평가 이력을 권위 자료로 일원화하고 이중 관리 불일치를 방지한다. - 기존 월마감 이력은 보존한다. - 스키마 마이그레이션 및 기존 API 호환성 테스트를 제공한다. ## 범위 제외 다음은 이번 요청의 필수 범위가 아니다. - 증권사 자동 연동 - 종목별 매매 원장 - 정확한 투자 성과 계산 엔진 ## 수락 기준 및 회귀 테스트 - [ ] 10월 5일 투자 평가액이 9월 30일 exact/as_of 조회 및 마감에 포함되지 않는다. - [ ] exact 누락과 as_of 이월을 구분하고 실제 평가 기준일을 반환한다. - [ ] 과거 자료 등록 후에도 현재 최신 평가값은 유지된다. - [ ] 취득원가·순납입액·금융기관 표시 잔액을 구분한다. - [ ] 미확인 금액과 실제 0원을 구분한다. - [ ] 평가액·원금·현금성 잔액을 중복 합산하지 않는다. - [ ] 거래 없는 수동 투자 계좌에 허위 수입이나 장부 오류를 생성하지 않는다. - [ ] 동일 증빙 재입력의 중복을 차단한다. - [ ] 정정 이력과 유효 정정본 선택을 검증한다. - [ ] 최신 평가 갱신·정정 후에도 기존 월마감은 불변이다. - [ ] 재마감은 정정 버전과 사유를 추가한다. - [ ] 대출 원금·이자·수수료의 부채 합산 정책을 검증한다. - [ ] 기준일 미상 기존 자료를 임의 날짜로 소급하지 않는다. - [ ] MCP·대시보드·기존 자산 보고의 호환성 테스트를 제공한다.
Sign in to join this conversation.