월정산 초안 및 계좌별 평가 스냅샷 지정 기능 구현 — 기준일 이후 자료의 승인된 대체 사용 지원 #15

Closed
opened 2026-10-08 13:17:02 +00:00 by genichin · 1 comment
Owner

요약

월정산을 영속 초안 생성 → 계좌별 평가자료 등록·직접 지정 → 누락·날짜 차이 검토 → 명시적 승인 → 최종 자산 마감 흐름으로 확장한다. 자료가 없어도 초안을 저장하며, 기준일 이후 평가자료는 사용자가 특정 valuation_id를 지정하고 대체 사유와 승인을 남긴 경우에만 사용한다. 원본 평가 기준일은 변경하지 않고 결과를 “대체 평가자료를 포함한 월정산”으로 표시한다.

기존 계좌 평가 이력과 자산 마감 계약의 확장이므로 REQ-003을 기존 경로에서 갱신한다. 거래 정산과 자산 마감을 분리하고 기존 exact/as_of 자동 선택, 수동 자산·부채, 불변 마감 이력, Dashboard 인증 및 MCP 응답 호환성을 유지한다. 정산 월마다 일반/정정 구분 없이 활성 초안은 하나만 허용하고 기준일은 해당 월말로 고정한다. 미확인 자료는 초안에서 검토할 수 있지만 최종 합산 전 확인/정정 자료로 명시적으로 교체·재검토·승인해야 하며, 미확인으로 남은 항목은 승인된 누락/제외로 처리한다.

문제

  • 기존 preview_asset_snapshot_close()는 읽기 전용 미리보기이며 준비 중 선택 내역을 영속 저장하지 않는다. close_asset_snapshot()의 조건부 마감은 이미 저장된 마감 실행이므로 편집 중 초안의 대체가 아니다.
  • 계좌 평가 자동 선택은 exact/as_of이며 미래 자료를 선택하지 않는다. 특정 계좌에 정산 기준일 이후의 자료를 직접 연결해 검토·승인하는 경로가 없다.
  • 기존 직접 마감은 실행 시점의 자료를 다시 조회한다. 검토한 초안의 계좌별 선택과 금액을 그대로 최종화하려면 버전·증거 fingerprint에 결합한 별도 초안 경계가 필요하다.
  • get_monthly_settlement_summary()는 거래·검토·자산 보고를 결합하는 읽기 모델이다. 거래 미정리 상태, 자산자료 누락, 대체 자료 사용을 같은 완료 판단으로 취급하지 않아야 한다.

포함 범위

  • 초안 ID, 정산 월·기준일, 상태, 생성자·생성/변경 시각, 메모, 동시 편집 버전, 생성 중복 방지 키, 최종 마감 ID 및 정정 관계를 영속 저장한다. 자료가 없어도 생성·저장할 수 있고 생성 자체로 마감 run이나 확정 금액을 만들지 않는다. 정산 월별 활성 초안은 일반/정정 구분 없이 하나로 제한하고, 완료·취소 후 새 초안을 열 수 있다. 생성 키 재시도는 같은 초안을 반환하고 다른 요청의 활성 중복은 충돌한다. 이미 마감한 기준일의 새 초안은 이전 run과 정정 사유를 연결한다. 정산 기준일은 해당 월말로 고정하며 입력한 날짜도 월말과 일치하는지 검증한다.
  • 초안의 정산 대상 계좌·자산·부채와 포함/제외 여부·사유를 관리한다. 계좌별 valuation_id, 선택 방식·사유, 선택자·시각, 항목 버전, 대체 승인 근거와 준비 상태를 저장한다. 새로운 계좌·대상 변경을 자동 반영하지 않고 명시적 대상 갱신으로만 반영하며 기존 선택과 승인에 미치는 차이를 검토한다.
  • 기존 평가 등록·조회·정정 기능을 재사용한다. 선택한 자료의 계좌 소속, 통화, 평가 목적과 대표 부채 정의를 검증하고 계좌별 대표 합산 금액은 하나만 사용한다. 투자 원금·현금성 잔액·평가액을 중복 합산하지 않는다. 증빙/등록 중복 방지와 append-only 정정을 보존한다.
  • exact는 같은 기준일의 확인 자료, carried_before는 이전 확인 자료의 승인된 이월, manual_substitute는 특정 자료의 명시적 직접 지정이다. 자동 선택은 이후 날짜 자료를 선택하지 않는다. 수동 대체는 실제 날짜·방향을 포함한 날짜 차이·사유·승인을 보존한다. 등록일과 평가 기준일을 구분한다. 미확인 자료는 초안 선택·검토용으로 보존하되 잠정 합계의 authority 금액에 포함하지 않고 확인 필요 상태로 표시한다. 최종 합산하려면 append-only 확인/정정 자료를 사용자가 명시적으로 다시 선택하고 재검토·승인한다. 끝내 미확인인 항목은 누락/제외로 표시하고 조건부 마감 시 그 누락을 승인한다. 확인 승인을 이유로 원본 verification_status를 덮어쓰지 않는다.
  • 초안 조회·검토·미리보기에서 대상/제외 목록, 자료 ID, 대표 금액·통화·자산/부채 분류, 실제 평가일, 선택 방식·날짜 차이, 증빙 출처·확인 상태, 선택/대체/제외 사유, 누락·승인 필요 항목, 잠정 총자산·총부채·순자산을 제공한다. 미선택 금액은 0으로 표시하지 않고 자료 완전성, 미등록 부채 및 대체 포함 여부를 명시한다.
  • 최종 마감은 사용자가 검토한 초안 버전과 선택 증거를 고정한다. 승인 뒤 대상·선택·사유·금액/분류·경고 또는 관련 증거가 달라지면 기존 승인을 사용할 수 없다. 계좌의 현재값이나 최신 정정본으로 조용히 다시 선택하지 않는다.
  • 초안 최종 상태 전이, 연결된 asset_snapshot_runs 및 asset_snapshots 저장을 하나의 트랜잭션으로 처리한다. 중복 클릭/동일 요청 재시도는 같은 마감을 반환하고 다른 payload의 키 재사용은 충돌한다. 실패 시 부분 마감과 완료 초안이 남지 않는다.
  • 원본 초안 ID·버전, 월·기준일, 적용 자료/금액/통화/분류, 실제 날짜·선택 방식·날짜 차이, 증빙/확인 상태, 포함·제외·대체 사유, 승인자·시각·근거와 누락/경고를 마감 이력에 보존한다. 완전한 exact 마감, 이월·대체 포함, 승인된 누락을 별도로 식별한다. 대체 사용과 누락은 하나의 모호한 상태로 합치지 않는다.
  • 초안에서 선택 자료에 정정본이 생기면 검토 필요를 표시하고 사용자가 교체 여부를 결정한다. 확정 마감은 이후 평가 등록·정정으로 변경하지 않는다. 명시적 정정 초안과 사유로 새 마감을 이전 run에 연결하며 이전 기록을 보존한다.
  • 기존 수동 자산·부채도 대상과 합계에 포함한다. 검토 당시의 값·날짜·분류·출처를 증거로 고정하고 원본 변경을 drift로 검출한다. 갱신하려면 명시적 재검토를 거치며 마감 때 live 값을 몰래 재사용하지 않는다. 수동 자료의 자동 날짜 선택은 기존 exact/as_of 제한을 유지한다.
  • Dashboard에서 생성·목록·상세·저장·취소, 계좌 자료 조회·등록·지정·해제, 포함/제외 및 사유 수정, 검토·승인·최종 마감, 확정 조회·정정 초안 생성을 제공한다. MCP도 같은 작업을 공통 application service로 제공한다.
  • 합성 자료로 원본 수락 기준을 검증한다. 특히 2026-09 초안에 2026-10-05/07 자료 직접 지정, 늦게 등록한 2026-09-30 자료의 exact 구분, 자동 미래 선택 금지, 승인 후 변경 차단, 정정·동시 편집·재시도·트랜잭션 실패와 기존 API/마이그레이션 회귀를 포함한다.

제외 범위

  • 거래 분류 완료 보장, 실제 월말 평가액 역산, 투자 성과 추정, 자산 증감을 수입·지출/투자 수익 거래로 자동 생성하는 기능.
  • 외부 가격 API, 새 환율 변환 정책, 자동 승인, 실제 계좌번호·금융자료·credential을 문서나 fixture에 저장하는 작업.
  • Dashboard 인증·쿠키/logout 또는 메뉴 순서 재설계, MCP 인증의 신규 도입.
  • 초안 취소에 따른 원본 평가·마감 이력 삭제, 기존 마감 덮어쓰기, 원본 평가일 소급 변경.
  • 정산 월의 월말과 다른 기준일, 같은 월의 복수 활성 초안, 미확인 자료의 단순 사용 승인만으로 금액을 최종 합산하는 경로.
  • Discovery 단계의 제품 코드·요구사항명세서·설계문서 작성 또는 수정, PR/브랜치 생성. 아래 산출물은 후속 구현 시의 문서 계약이다.

제약 조건

  • 조사 기준은 main의 고정 revision 68212e773b94dd89b6c036e6616759542c178de3이다. Gitea authoritative SHA와 갱신한 bare cache의 local ref를 비교했다.
  • SQLite schema 12에서 additive migration하며 기존 테이블·행·이력·인덱스의 의미를 보존한다. 실제 새 스키마 버전 및 물리 필드는 구현 결과와 함께 문서화하고 기존 자료를 추정 이주하지 않는다.
  • 기존 자동 exact/as_of와 기존 직접 마감의 호출/응답 계약을 유지한다. 미래 사용 예외는 직접 지정·검토·승인된 초안 마감에 한정하며 자동 선택 계약을 전역 완화하지 않는다. 기존 직접 마감이 초안의 승인·변경 검증을 우회해 선택 자료를 대신 확정하는 경로를 만들지 않는다.
  • rejected/unknown 날짜, 잘못된 계좌·통화·목적·대표 부채 정의와 모호한 대표 선택은 승인만으로 정상 자료가 되지 않는다. 미확인 자료는 초안에서 선택·검토할 수 있지만 미확인 금액 자체를 승인으로 합산하지 않는다. 최종 합산 전 append-only 확인/정정 자료를 명시적으로 다시 선택하고 재검토·승인해야 한다. 미확인으로 남으면 누락/제외와 그 누락에 대한 조건부 승인만 허용한다.
  • 정수 금액의 정확도와 NULL/0 구분, 순자산의 자산−부채 계산, KRW 중심 기존 정책을 유지한다. FX 정책 없는 비KRW 금액은 단순 합산하지 않고 제외/경고를 표시한다.
  • carried_before는 초안의 이전 자료 선택 의미이고 기존 public as_of를 제거하거나 이름을 바꾸지 않는다. 기존 age_days의 의미를 변경하지 않고 수동 미래 자료의 방향 있는 날짜 차이 계약을 별도로 명확히 한다.
  • get_monthly_settlement_summary()와 기존 preview/report/render는 읽기 전용을 유지한다. 새 초안 mutation은 명시적 버튼·도구 호출로만 수행한다. missing DB 조회는 기존 db_not_initialized/no-create 계약을 유지한다.
  • Dashboard auth-before-DB, 기존 성공/오류 envelope, 기존 MCP transport와 application → SQLite 의존 방향을 유지한다. 업무 검증·선택·마감은 UI/MCP에서 중복 구현하지 않는다.
  • 거래 import/분류/대사가 미완료라는 이유만으로 평가 등록과 자산 마감을 막지 않는다. 거래 준비 상태와 자산 마감 상태를 별도로 표시한다.
  • 월별 단일 활성 초안·월말 기준일·미확인 금액 제외 정책을 생성/편집/검토/최종화 및 모든 후속 문서에 동일하게 적용한다. 활성 초안 중복은 일반/정정 구분으로 우회하지 않으며 취소는 증빙이나 기존 마감을 삭제하지 않는다. 사용자 선택은 제품 구현/시험 완료의 증거가 아니다.

확정된 결정

  • 자료 확보 전 영속 초안을 만들고 계좌별 자료를 순차적으로 채우는 흐름이 필요하다. 조건부 마감을 초안처럼 반복 생성하는 것으로 대체하지 않는다.

  • 기준일 이후 자료는 사용자가 특정 평가를 직접 지정하고 이유 및 최종 승인을 남긴 경우에만 허용한다. 원본 기준일은 그대로 두고 “정확한 월말 평가액”으로 표시하지 않는다.

  • 승인은 검토한 초안 버전/증거에 결합하며 변경 후 재검토·재승인이 필요하다. 마감은 선택한 자료와 적용 금액을 불변 증거로 저장한다.

  • 취소·정정은 원본 증빙과 이전 마감을 보존한다. 정정본은 자동 교체하지 않고 정정 마감은 새 run으로 연결한다.

  • 기존 계좌 이력, 자동 exact/as_of, 수동 자산·부채와 Dashboard/MCP 공통 서비스 경계를 유지한다. 거래 정산과 자산 마감은 분리한다.

  • 문서 분류는 기존 계좌 평가·자산 마감 기능과 월정산 propagation의 동작/정책 확장이므로 기존 REQ-003을 갱신한다. 새 테이블/초안 lifecycle의 추가나 기존 문서의 제외 범위만으로 별도 ID를 만들지 않는다. 이는 문서 배치 판정이며 OQ의 제품 정책을 결정하지 않는다.

  • 사용자 선택 — 활성 초안: 정산 월마다 활성 초안을 하나만 허용한다. 일반/정정 초안을 같은 제한으로 관리하고 완료·취소 후 새 초안을 열 수 있다. 이미 마감한 기준일의 새 초안은 이전 run과 정정 사유를 연결하며, 동일 키 재시도는 기존 초안을 반환하고 다른 요청의 중복 생성은 충돌한다.

  • 사용자 선택 — 정산 기준일: 정산 기준일은 정산 월의 마지막 날짜로 고정한다. 사용자가 입력했다면 월말과 일치하는지 검증하고 월정산 summary의 현재 월말 읽기 의미를 유지한다.

  • 사용자 선택 — 미확인 자료: 미확인 자료는 초안에서 선택·검토할 수 있으나 최종 금액에 반영하려면 append-only 확인/정정 자료를 명시적으로 다시 선택하고 재검토·승인해야 한다. 끝내 확인되지 않은 항목은 누락/제외로 표시하고 조건부 마감 시 그 누락을 승인한다. 기존 verified authority를 유지한다.

저장소 근거

모든 아래 경로는 대상 저장소 기준이며 고정 revision 68212e773b94dd89b6c036e6616759542c178de3에서 조사했다. 아래 테스트는 존재와 계약을 조사한 근거이며 이번 Discovery 작업에서 제품 테스트를 실행했다는 뜻이 아니다.

  • jarca_ledger_mcp/application/account_valuation_service.py: register_account_valuation(), list_account_valuations(), select_account_valuation(), correct_account_valuation()이 날짜·통화·목적·확인 상태, 계좌 소속, 대표 부채와 append-only 정정/중복 검증을 담당한다. 현재 selector는 exact/as_of이며 valuation_id 초안 연결 mutation이 아니다. correct_account_valuation()은 verification_status를 변경한 append-only child를 만들 수 있고 원본 계좌/날짜/통화/목적과 단일 child 제약을 보존하므로 확인 자료의 명시적 재선택 경로를 재사용할 수 있다.
  • jarca_ledger_mcp/application/assets_service.py: _account_valuation_items()는 verified leaf의 exact/as_of 및 계좌 목적 우선순위를 적용하고 미래를 자동 선택하지 않는다. _manual_asset_valuation_items()는 수동 자료와 날짜/통화 제한을 적용한다. preview_asset_snapshot_close()는 미리보기, close_asset_snapshot()은 BEGIN IMMEDIATE, fingerprint, 승인·키·정정 검증과 run/rows 저장을 수행한다. 현 마감은 live 자료를 다시 조회하므로 초안 선택을 그대로 최종화하는 계약이 추가로 필요하다.
  • jarca_ledger_mcp/application/monthly_settlement_service.py: _month_end_date()와 get_monthly_settlement_summary()는 월말 기준의 read-only 집계와 monthly_source_snapshot_id alias 전파를 담당한다. 현재 초안 persistence는 없다. application/shared.py의 normalize_snapshot_at()은 정산 월의 마지막 날짜를 계산하므로 월말 고정 결정의 기존 읽기 기준과 정합성이 확인된다.
  • jarca_ledger_mcp/infrastructure/sqlite/schema.py, migrations.py: SCHEMA_VERSION = "12", account_valuations, manual_assets, asset_snapshot_runs, asset_snapshots 및 idempotency/단일 correction 인덱스가 존재하고 월정산 초안 테이블은 없다. 기존 partial unique index와 transaction 경계는 후속 초안의 월별 활성 유일성·원자적 최종화 설계에 재사용할 저장 방식의 근거이며, 초안 기능이 이미 구현됐다는 뜻은 아니다. connection.py의 read_db()는 SQLite read-only 경계다.
  • jarca_ledger_mcp/adapters/mcp/server.py, tool_contracts.py, jarca_ledger_mcp/adapters/streamlit/assets_gateway.py: 기존 valuation/snapshot 도구와 service delegation이 존재한다. dashboard/page_views/monthly_settlement.py는 월정산 보고, dashboard/page_views/assets.py는 기존 마감 UI이며 영속 초안 편집 흐름이 없다.
  • docs/requirements/req-001_dashboard-administrator-authentication.md, req-002_dashboard-menu-transition.md, req-003_account-valuation-history.md: 정본 ID는 REQ-001~003으로 연속이며 REQ-003은 계좌 이력·선택·조건부 마감·정정·월정산 읽기 전파·공통 adapter 계약을 소유한다. REQ-003의 미래/미확인 제외와 월정산 read-only 계약을 새 명시적 초안 mutation 및 확인된 미래자료의 승인 예외와 구분해 갱신해야 한다. 미확인 금액 authority는 기존 verified-only를 유지하고 미확인 선택/검토와 누락 승인을 별도로 명세한다.
  • docs/data-model.md, docs/interface-contract.md, docs/project-structure.md, docs/runtime-flow.md: 네 정본 문서가 모두 존재한다. verified leaf authority, immutable run, monthly_source_snapshot_id read alias, auth-before-DB, preview drift 및 service/adapter 책임을 규정한다.
  • tests/test_account_valuations.py, tests/test_asset_snapshots.py, tests/test_asset_snapshot_idempotency.py, tests/test_legacy_snapshot_migration.py, tests/test_contract_regression.py, tests/test_requirement_docs.py: 기존 선택·중복/정정·수동 자산·불변/legacy 마감·응답/문서 계약의 회귀 대상이다. 기존 schema 12·future exclusion 단언은 유지할 자동 경로와 새 초안 예외를 구분해서 갱신한다.

문서 영향 및 산출물

요구사항명세서

  • 조치: 갱신
  • 경로: docs/requirements/req-003_account-valuation-history.md
  • 문서 ID: REQ-003
  • 제목: 계좌 기준일 평가 이력과 자산 마감 연동
  • 변경 내용: 기존 ID·파일명·제목을 유지하고 초안 생성/편집/취소, 계좌별 직접 지정, 날짜 차이와 대체 승인, 대상 갱신, 검토 버전/fingerprint, 최종화·정정 초안 및 공통 adapter 요구사항/인수 기준을 추가한다. 미래 제외 규칙을 자동/직접 마감과 승인된 초안 예외로 분리한다. 월별 단일 활성 초안과 월말 기준일 검증을 추가하고 미확인 선택·검토는 허용하되 확인/정정 자료의 명시적 재선택·재검토·승인 전 금액 합산을 금지한다. 미확인으로 남은 항목은 누락/제외 및 조건부 누락 승인으로 처리한다. 기존 append-only, 정수/NULL, 대표 부채, no-fake-transaction, auth/menu·읽기 전용 계약을 유지한다. revision과 변경 이력을 갱신하고 기존 #12/#13 추적성을 보존하면서 이번 근거 #15, 이번 구현 PR 미정을 구분한다.
  • 포함할 내용: 무자료 생성과 no-close, 같은 키 재사용/다른 payload 충돌, 일반/정정 통합 월별 단일 활성 초안, 완료/취소 후 재생성과 기존 마감의 정정 연결, 월말 고정 기준일과 입력 일치 검증, 대상의 명시적 갱신, 준비 상태와 금액의 NULL/0, 계좌/통화/목적/대표 부채 검증, exact/carried_before/manual_substitute와 자동 미래 금지, 이후 자료의 원본 날짜·사유·승인, 미확인 초안 선택/검토, 확인/정정 자료의 명시적 재선택·재검토·승인, 미확인 금액 합산 금지 및 미해소 항목의 승인된 누락/제외, 잠정 합계·완전성·누락/제외/대체 구분, 수동 자산/부채 보존 및 drift, 검토 이후 모든 의미 있는 변경의 재승인, 단일 트랜잭션과 동시 편집 충돌/no-partial-write, persisted evidence 기반 재시도, immutable close와 명시적 정정, 거래/자산 상태 분리, Dashboard/MCP 동등 동작, schema migration 및 기존 API/보안/legacy 회귀를 정상·경계·실패 사례로 명세한다.
  • 제외할 내용: 거래 완료/성과 추정 보장, FX/가격 API, 자동 승인·자동 미래 선택, 인증/메뉴 재설계, 실제 금융자료, 원본 날짜 변경 및 이력 삭제.
  • 근거: REQ-003.02/.06/.07/.08/.09의 기존 기능과 정책을 직접 확장하는 작업이다. 영속 초안이 새 aggregate라는 이유만으로 별도 REQ-004를 만들지 않고 현 작성 규칙에 따라 갱신한다. 동일 ID를 유지하므로 신규 ID 할당은 없다.

데이터 모델

  • 조치: 갱신
  • 경로: docs/data-model.md
  • 변경 내용: 초안과 항목의 영속 엔터티를 추가해 초안→대상 항목, 항목→계좌/valuation, 초안→최종 run, 정정 초안→이전 run 관계와 필수/선택성·유일성·삭제 금지를 기록한다. 초안의 월·기준일·상태·작성자·시각·메모·버전·중복 키·완료 연결, 항목의 source identity·선택 자료·방식/사유·포함/제외·선택자·시각·버전·승인 결합 정보를 명세한다. 수동 자료는 검토 증거 값을 고정하고 원본 drift를 검출한다. 최종 run/rows에는 실제 날짜·방향 있는 차이·확인 상태·적용 금액·분류·사유·승인·누락/경고·초안 버전/fingerprint를 보존한다. 일반/정정 통합 정산 월별 활성 초안 유일성을 저장 제약과 동시성 검증으로 강제하고 완료·취소 이력은 보존한다. 월·기준일의 월말 일치 검증을 명세한다. 미확인 항목은 검토용 선택과 금액 authority를 분리하며 확인/정정 child의 명시적 재선택 후에만 합산한다. 미확인으로 남은 항목의 제외 사유와 누락 승인도 보존한다. 기존 correction/idempotency 제약, read alias와 nullable 금액 의미를 보존하고 schema 12→새 버전의 additive·반복 가능한 migration/legacy 조회/실패 및 백업 복구 경계를 문서화한다.
  • 근거: schema 12에는 초안/항목 persistence가 없으며 기존 account_valuations와 run/rows를 재사용·연결해야 한다. 원본 이력의 변경/삭제나 guessed migration은 필요하지 않다.

인터페이스 계약

  • 조치: 갱신
  • 경로: docs/interface-contract.md
  • 변경 내용: 공통 초안 생성·목록·상세·수정/대상 갱신·취소·계좌 자료 지정/해제·포함/제외·검토/검증·승인 최종화·정정 초안 operation을 정의하고 실제 구현의 snake_case 함수/MCP 도구/gateway 이름과 exact signature를 고정한다. 입력에는 초안/항목 ID·기대 버전, 월·기준일, 자료 ID·선택 방식·사유, 명시적 포함/제외와 사유, 생성/마감 키, 검토 fingerprint 및 승인자·시각/근거를 기록한다. 출력에는 준비 상태·버전, 대상/선택 증거, 날짜 차이·확인 상태, 잠정 합계·완전성·누락/승인 필요 목록, 완료 run/정정 연결과 persisted replay를 정의한다. 검증/대상 부재/상태·버전·증거 drift/승인 부족/키 충돌/동시 마감 오류의 조건·재시도·no-write를 명확히 한다. 기존 success/error_code/error, 자동 selector, 기존 close/report 키와 provenance 의미, Dashboard 인증 및 MCP 인증 범위를 보존한다. 초안 사용 시 직접 마감으로 안전 검증을 우회하지 못하는 경계를 규정한다. 생성·정정 생성은 같은 월의 활성 초안 중복을 검사하고 월말 아닌 입력 기준일은 거절한다. 미확인 선택은 검토용 상태를 반환하고 합계/최종화는 금액을 제외한다. 확인/정정 child를 명시적으로 다시 선택하면 버전·검토/승인을 갱신하고, 끝내 미확인인 항목은 누락/제외 승인 대상으로만 반환한다.
  • 근거: 기존 MCP/gateway에는 초안 mutation이 없고 현재 close는 basis-date 자료 자동 재조회 경로다. 새 공통 계약과 legacy 경로 구분이 필요하다.

프로젝트 구조

  • 조치: 갱신
  • 경로: docs/project-structure.md
  • 변경 내용: 기존 application/monthly_settlement_service.py의 read model을 보존하면서 초안 lifecycle의 application-layer 책임과 account_valuation_service.py(등록·검증·정정), assets_service.py(금액/증거·run 최종화), infrastructure/sqlite/schema.py/migrations.py(영속 제약/이주)의 소유권을 명확히 한다. service.py 공개 re-export, adapters/mcp/server.py/tool_contracts.py, adapters/streamlit gateway와 dashboard/page_views/monthly_settlement.py/assets.py의 연결을 실제 경로로 기록한다. 새 파일을 추가하면 그 exact 경로·책임·진입점을 문서에 반영하되 UI/MCP direct SQL, application의 Dashboard 역의존과 중복 업무 검증을 금지한다. 월별 활성 초안 유일성·월말 검증·미확인 금액 제외/확인 후 재선택의 책임을 공통 application과 SQLite 제약에 두고 adapter별 예외를 만들지 않는다. 각 변경에 대응하는 합성 테스트, 문서 검증과 기존 auth/menu/legacy 회귀 위치를 연결한다.
  • 근거: 기존 구조 문서는 service→SQLite와 page/tool→gateway/service 방향을 정본으로 규정한다. 새 초안 작업은 해당 책임 경계를 확장하며 별도 UI 전용 마감 로직을 만들지 않는다.

런타임 흐름

  • 조치: 갱신
  • 경로: docs/runtime-flow.md
  • 변경 내용: 인증→명시적 무자료 초안 생성→대상 동결→자료 등록/지정·해제/제외→읽기 전용 검토→버전·증거에 결합한 승인→동일 transaction에서 증거 재검증·run/rows 저장·초안 완료→불변 조회 흐름을 정의한다. 생성/정정 생성 guard는 일반/정정 통합 월별 단일 활성 초안과 월말 일치를 검증한다. 완료·취소 후 재생성은 가능하지만 기존 마감이 있으면 이전 run과 정정 사유를 연결한다. 미확인 자료 선택은 검토 필요로 전이하며 합계에는 포함하지 않는다. 확인/정정 자료를 명시적으로 재선택하면 재검토·재승인 후 최종화하고, 끝내 확인되지 않으면 누락/제외 및 조건부 누락 승인을 거친다. 변경/정정/대상 갱신은 승인을 무효화하고 검토 단계로 돌아간다. 취소는 기존 증거/run을 삭제하지 않으며 재마감은 이전 run 연결·사유·단일 correction 제약을 유지한다. 거래 준비와 자산 상태를 별도로 표시하고 외부 가격/환율 호출·추정 거래 생성은 없다. SQLite 동시 편집·키/버전 충돌, stale approval, 정정본 등장, 중복 최종화, DB 실패에 대해 no-partial-write·rollback·안전 재시도/사용자 재검토와 반환 오류를 기록한다. 관찰 정보는 초안/버전/run 상관 ID와 상태/경고 코드로 제한하고 credential/실제 계좌 자료를 로그에 남기지 않는다.
  • 근거: 현 runtime은 read-only preview→live authority 기반 close이며 영속 준비 단계가 없다. 기존 fingerprint drift·원자 저장·persisted replay guard를 초안 선택에 결합해 확장해야 한다.

미해결 질문

없음

<!-- gitea-agent:discovery-draft/v2 --> ## 요약 월정산을 **영속 초안 생성 → 계좌별 평가자료 등록·직접 지정 → 누락·날짜 차이 검토 → 명시적 승인 → 최종 자산 마감** 흐름으로 확장한다. 자료가 없어도 초안을 저장하며, 기준일 이후 평가자료는 사용자가 특정 `valuation_id`를 지정하고 대체 사유와 승인을 남긴 경우에만 사용한다. 원본 평가 기준일은 변경하지 않고 결과를 “대체 평가자료를 포함한 월정산”으로 표시한다. 기존 계좌 평가 이력과 자산 마감 계약의 확장이므로 `REQ-003`을 기존 경로에서 갱신한다. 거래 정산과 자산 마감을 분리하고 기존 exact/as_of 자동 선택, 수동 자산·부채, 불변 마감 이력, Dashboard 인증 및 MCP 응답 호환성을 유지한다. 정산 월마다 일반/정정 구분 없이 활성 초안은 하나만 허용하고 기준일은 해당 월말로 고정한다. 미확인 자료는 초안에서 검토할 수 있지만 최종 합산 전 확인/정정 자료로 명시적으로 교체·재검토·승인해야 하며, 미확인으로 남은 항목은 승인된 누락/제외로 처리한다. ## 문제 - 기존 `preview_asset_snapshot_close()`는 읽기 전용 미리보기이며 준비 중 선택 내역을 영속 저장하지 않는다. `close_asset_snapshot()`의 조건부 마감은 이미 저장된 마감 실행이므로 편집 중 초안의 대체가 아니다. - 계좌 평가 자동 선택은 exact/as_of이며 미래 자료를 선택하지 않는다. 특정 계좌에 정산 기준일 이후의 자료를 직접 연결해 검토·승인하는 경로가 없다. - 기존 직접 마감은 실행 시점의 자료를 다시 조회한다. 검토한 초안의 계좌별 선택과 금액을 그대로 최종화하려면 버전·증거 fingerprint에 결합한 별도 초안 경계가 필요하다. - `get_monthly_settlement_summary()`는 거래·검토·자산 보고를 결합하는 읽기 모델이다. 거래 미정리 상태, 자산자료 누락, 대체 자료 사용을 같은 완료 판단으로 취급하지 않아야 한다. ## 포함 범위 - 초안 ID, 정산 월·기준일, 상태, 생성자·생성/변경 시각, 메모, 동시 편집 버전, 생성 중복 방지 키, 최종 마감 ID 및 정정 관계를 영속 저장한다. 자료가 없어도 생성·저장할 수 있고 생성 자체로 마감 run이나 확정 금액을 만들지 않는다. 정산 월별 활성 초안은 일반/정정 구분 없이 하나로 제한하고, 완료·취소 후 새 초안을 열 수 있다. 생성 키 재시도는 같은 초안을 반환하고 다른 요청의 활성 중복은 충돌한다. 이미 마감한 기준일의 새 초안은 이전 run과 정정 사유를 연결한다. 정산 기준일은 해당 월말로 고정하며 입력한 날짜도 월말과 일치하는지 검증한다. - 초안의 정산 대상 계좌·자산·부채와 포함/제외 여부·사유를 관리한다. 계좌별 `valuation_id`, 선택 방식·사유, 선택자·시각, 항목 버전, 대체 승인 근거와 준비 상태를 저장한다. 새로운 계좌·대상 변경을 자동 반영하지 않고 명시적 대상 갱신으로만 반영하며 기존 선택과 승인에 미치는 차이를 검토한다. - 기존 평가 등록·조회·정정 기능을 재사용한다. 선택한 자료의 계좌 소속, 통화, 평가 목적과 대표 부채 정의를 검증하고 계좌별 대표 합산 금액은 하나만 사용한다. 투자 원금·현금성 잔액·평가액을 중복 합산하지 않는다. 증빙/등록 중복 방지와 append-only 정정을 보존한다. - `exact`는 같은 기준일의 확인 자료, `carried_before`는 이전 확인 자료의 승인된 이월, `manual_substitute`는 특정 자료의 명시적 직접 지정이다. 자동 선택은 이후 날짜 자료를 선택하지 않는다. 수동 대체는 실제 날짜·방향을 포함한 날짜 차이·사유·승인을 보존한다. 등록일과 평가 기준일을 구분한다. 미확인 자료는 초안 선택·검토용으로 보존하되 잠정 합계의 authority 금액에 포함하지 않고 확인 필요 상태로 표시한다. 최종 합산하려면 append-only 확인/정정 자료를 사용자가 명시적으로 다시 선택하고 재검토·승인한다. 끝내 미확인인 항목은 누락/제외로 표시하고 조건부 마감 시 그 누락을 승인한다. 확인 승인을 이유로 원본 verification_status를 덮어쓰지 않는다. - 초안 조회·검토·미리보기에서 대상/제외 목록, 자료 ID, 대표 금액·통화·자산/부채 분류, 실제 평가일, 선택 방식·날짜 차이, 증빙 출처·확인 상태, 선택/대체/제외 사유, 누락·승인 필요 항목, 잠정 총자산·총부채·순자산을 제공한다. 미선택 금액은 0으로 표시하지 않고 자료 완전성, 미등록 부채 및 대체 포함 여부를 명시한다. - 최종 마감은 사용자가 검토한 초안 버전과 선택 증거를 고정한다. 승인 뒤 대상·선택·사유·금액/분류·경고 또는 관련 증거가 달라지면 기존 승인을 사용할 수 없다. 계좌의 현재값이나 최신 정정본으로 조용히 다시 선택하지 않는다. - 초안 최종 상태 전이, 연결된 `asset_snapshot_runs` 및 `asset_snapshots` 저장을 하나의 트랜잭션으로 처리한다. 중복 클릭/동일 요청 재시도는 같은 마감을 반환하고 다른 payload의 키 재사용은 충돌한다. 실패 시 부분 마감과 완료 초안이 남지 않는다. - 원본 초안 ID·버전, 월·기준일, 적용 자료/금액/통화/분류, 실제 날짜·선택 방식·날짜 차이, 증빙/확인 상태, 포함·제외·대체 사유, 승인자·시각·근거와 누락/경고를 마감 이력에 보존한다. 완전한 exact 마감, 이월·대체 포함, 승인된 누락을 별도로 식별한다. 대체 사용과 누락은 하나의 모호한 상태로 합치지 않는다. - 초안에서 선택 자료에 정정본이 생기면 검토 필요를 표시하고 사용자가 교체 여부를 결정한다. 확정 마감은 이후 평가 등록·정정으로 변경하지 않는다. 명시적 정정 초안과 사유로 새 마감을 이전 run에 연결하며 이전 기록을 보존한다. - 기존 수동 자산·부채도 대상과 합계에 포함한다. 검토 당시의 값·날짜·분류·출처를 증거로 고정하고 원본 변경을 drift로 검출한다. 갱신하려면 명시적 재검토를 거치며 마감 때 live 값을 몰래 재사용하지 않는다. 수동 자료의 자동 날짜 선택은 기존 exact/as_of 제한을 유지한다. - Dashboard에서 생성·목록·상세·저장·취소, 계좌 자료 조회·등록·지정·해제, 포함/제외 및 사유 수정, 검토·승인·최종 마감, 확정 조회·정정 초안 생성을 제공한다. MCP도 같은 작업을 공통 application service로 제공한다. - 합성 자료로 원본 수락 기준을 검증한다. 특히 2026-09 초안에 2026-10-05/07 자료 직접 지정, 늦게 등록한 2026-09-30 자료의 exact 구분, 자동 미래 선택 금지, 승인 후 변경 차단, 정정·동시 편집·재시도·트랜잭션 실패와 기존 API/마이그레이션 회귀를 포함한다. ## 제외 범위 - 거래 분류 완료 보장, 실제 월말 평가액 역산, 투자 성과 추정, 자산 증감을 수입·지출/투자 수익 거래로 자동 생성하는 기능. - 외부 가격 API, 새 환율 변환 정책, 자동 승인, 실제 계좌번호·금융자료·credential을 문서나 fixture에 저장하는 작업. - Dashboard 인증·쿠키/logout 또는 메뉴 순서 재설계, MCP 인증의 신규 도입. - 초안 취소에 따른 원본 평가·마감 이력 삭제, 기존 마감 덮어쓰기, 원본 평가일 소급 변경. - 정산 월의 월말과 다른 기준일, 같은 월의 복수 활성 초안, 미확인 자료의 단순 사용 승인만으로 금액을 최종 합산하는 경로. - Discovery 단계의 제품 코드·요구사항명세서·설계문서 작성 또는 수정, PR/브랜치 생성. 아래 산출물은 후속 구현 시의 문서 계약이다. ## 제약 조건 - 조사 기준은 `main`의 고정 revision `68212e773b94dd89b6c036e6616759542c178de3`이다. Gitea authoritative SHA와 갱신한 bare cache의 local ref를 비교했다. - SQLite schema 12에서 additive migration하며 기존 테이블·행·이력·인덱스의 의미를 보존한다. 실제 새 스키마 버전 및 물리 필드는 구현 결과와 함께 문서화하고 기존 자료를 추정 이주하지 않는다. - 기존 자동 exact/as_of와 기존 직접 마감의 호출/응답 계약을 유지한다. 미래 사용 예외는 직접 지정·검토·승인된 초안 마감에 한정하며 자동 선택 계약을 전역 완화하지 않는다. 기존 직접 마감이 초안의 승인·변경 검증을 우회해 선택 자료를 대신 확정하는 경로를 만들지 않는다. - rejected/unknown 날짜, 잘못된 계좌·통화·목적·대표 부채 정의와 모호한 대표 선택은 승인만으로 정상 자료가 되지 않는다. 미확인 자료는 초안에서 선택·검토할 수 있지만 미확인 금액 자체를 승인으로 합산하지 않는다. 최종 합산 전 append-only 확인/정정 자료를 명시적으로 다시 선택하고 재검토·승인해야 한다. 미확인으로 남으면 누락/제외와 그 누락에 대한 조건부 승인만 허용한다. - 정수 금액의 정확도와 NULL/0 구분, 순자산의 자산−부채 계산, KRW 중심 기존 정책을 유지한다. FX 정책 없는 비KRW 금액은 단순 합산하지 않고 제외/경고를 표시한다. - `carried_before`는 초안의 이전 자료 선택 의미이고 기존 public `as_of`를 제거하거나 이름을 바꾸지 않는다. 기존 `age_days`의 의미를 변경하지 않고 수동 미래 자료의 방향 있는 날짜 차이 계약을 별도로 명확히 한다. - `get_monthly_settlement_summary()`와 기존 preview/report/render는 읽기 전용을 유지한다. 새 초안 mutation은 명시적 버튼·도구 호출로만 수행한다. missing DB 조회는 기존 `db_not_initialized`/no-create 계약을 유지한다. - Dashboard auth-before-DB, 기존 성공/오류 envelope, 기존 MCP transport와 application → SQLite 의존 방향을 유지한다. 업무 검증·선택·마감은 UI/MCP에서 중복 구현하지 않는다. - 거래 import/분류/대사가 미완료라는 이유만으로 평가 등록과 자산 마감을 막지 않는다. 거래 준비 상태와 자산 마감 상태를 별도로 표시한다. - 월별 단일 활성 초안·월말 기준일·미확인 금액 제외 정책을 생성/편집/검토/최종화 및 모든 후속 문서에 동일하게 적용한다. 활성 초안 중복은 일반/정정 구분으로 우회하지 않으며 취소는 증빙이나 기존 마감을 삭제하지 않는다. 사용자 선택은 제품 구현/시험 완료의 증거가 아니다. ## 확정된 결정 - 자료 확보 전 영속 초안을 만들고 계좌별 자료를 순차적으로 채우는 흐름이 필요하다. 조건부 마감을 초안처럼 반복 생성하는 것으로 대체하지 않는다. - 기준일 이후 자료는 사용자가 특정 평가를 직접 지정하고 이유 및 최종 승인을 남긴 경우에만 허용한다. 원본 기준일은 그대로 두고 “정확한 월말 평가액”으로 표시하지 않는다. - 승인은 검토한 초안 버전/증거에 결합하며 변경 후 재검토·재승인이 필요하다. 마감은 선택한 자료와 적용 금액을 불변 증거로 저장한다. - 취소·정정은 원본 증빙과 이전 마감을 보존한다. 정정본은 자동 교체하지 않고 정정 마감은 새 run으로 연결한다. - 기존 계좌 이력, 자동 exact/as_of, 수동 자산·부채와 Dashboard/MCP 공통 서비스 경계를 유지한다. 거래 정산과 자산 마감은 분리한다. - 문서 분류는 기존 계좌 평가·자산 마감 기능과 월정산 propagation의 동작/정책 확장이므로 기존 `REQ-003`을 갱신한다. 새 테이블/초안 lifecycle의 추가나 기존 문서의 제외 범위만으로 별도 ID를 만들지 않는다. 이는 문서 배치 판정이며 OQ의 제품 정책을 결정하지 않는다. - 사용자 선택 — 활성 초안: 정산 월마다 활성 초안을 하나만 허용한다. 일반/정정 초안을 같은 제한으로 관리하고 완료·취소 후 새 초안을 열 수 있다. 이미 마감한 기준일의 새 초안은 이전 run과 정정 사유를 연결하며, 동일 키 재시도는 기존 초안을 반환하고 다른 요청의 중복 생성은 충돌한다. - 사용자 선택 — 정산 기준일: 정산 기준일은 정산 월의 마지막 날짜로 고정한다. 사용자가 입력했다면 월말과 일치하는지 검증하고 월정산 summary의 현재 월말 읽기 의미를 유지한다. - 사용자 선택 — 미확인 자료: 미확인 자료는 초안에서 선택·검토할 수 있으나 최종 금액에 반영하려면 append-only 확인/정정 자료를 명시적으로 다시 선택하고 재검토·승인해야 한다. 끝내 확인되지 않은 항목은 누락/제외로 표시하고 조건부 마감 시 그 누락을 승인한다. 기존 verified authority를 유지한다. ## 저장소 근거 모든 아래 경로는 대상 저장소 기준이며 고정 revision `68212e773b94dd89b6c036e6616759542c178de3`에서 조사했다. 아래 테스트는 존재와 계약을 조사한 근거이며 이번 Discovery 작업에서 제품 테스트를 실행했다는 뜻이 아니다. - `jarca_ledger_mcp/application/account_valuation_service.py`: `register_account_valuation()`, `list_account_valuations()`, `select_account_valuation()`, `correct_account_valuation()`이 날짜·통화·목적·확인 상태, 계좌 소속, 대표 부채와 append-only 정정/중복 검증을 담당한다. 현재 selector는 exact/as_of이며 `valuation_id` 초안 연결 mutation이 아니다. `correct_account_valuation()`은 verification_status를 변경한 append-only child를 만들 수 있고 원본 계좌/날짜/통화/목적과 단일 child 제약을 보존하므로 확인 자료의 명시적 재선택 경로를 재사용할 수 있다. - `jarca_ledger_mcp/application/assets_service.py`: `_account_valuation_items()`는 verified leaf의 exact/as_of 및 계좌 목적 우선순위를 적용하고 미래를 자동 선택하지 않는다. `_manual_asset_valuation_items()`는 수동 자료와 날짜/통화 제한을 적용한다. `preview_asset_snapshot_close()`는 미리보기, `close_asset_snapshot()`은 `BEGIN IMMEDIATE`, fingerprint, 승인·키·정정 검증과 run/rows 저장을 수행한다. 현 마감은 live 자료를 다시 조회하므로 초안 선택을 그대로 최종화하는 계약이 추가로 필요하다. - `jarca_ledger_mcp/application/monthly_settlement_service.py`: `_month_end_date()`와 `get_monthly_settlement_summary()`는 월말 기준의 read-only 집계와 `monthly_source_snapshot_id` alias 전파를 담당한다. 현재 초안 persistence는 없다. `application/shared.py`의 `normalize_snapshot_at()`은 정산 월의 마지막 날짜를 계산하므로 월말 고정 결정의 기존 읽기 기준과 정합성이 확인된다. - `jarca_ledger_mcp/infrastructure/sqlite/schema.py`, `migrations.py`: `SCHEMA_VERSION = "12"`, `account_valuations`, `manual_assets`, `asset_snapshot_runs`, `asset_snapshots` 및 idempotency/단일 correction 인덱스가 존재하고 월정산 초안 테이블은 없다. 기존 partial unique index와 transaction 경계는 후속 초안의 월별 활성 유일성·원자적 최종화 설계에 재사용할 저장 방식의 근거이며, 초안 기능이 이미 구현됐다는 뜻은 아니다. `connection.py`의 `read_db()`는 SQLite read-only 경계다. - `jarca_ledger_mcp/adapters/mcp/server.py`, `tool_contracts.py`, `jarca_ledger_mcp/adapters/streamlit/assets_gateway.py`: 기존 valuation/snapshot 도구와 service delegation이 존재한다. `dashboard/page_views/monthly_settlement.py`는 월정산 보고, `dashboard/page_views/assets.py`는 기존 마감 UI이며 영속 초안 편집 흐름이 없다. - `docs/requirements/req-001_dashboard-administrator-authentication.md`, `req-002_dashboard-menu-transition.md`, `req-003_account-valuation-history.md`: 정본 ID는 REQ-001~003으로 연속이며 REQ-003은 계좌 이력·선택·조건부 마감·정정·월정산 읽기 전파·공통 adapter 계약을 소유한다. REQ-003의 미래/미확인 제외와 월정산 read-only 계약을 새 명시적 초안 mutation 및 확인된 미래자료의 승인 예외와 구분해 갱신해야 한다. 미확인 금액 authority는 기존 verified-only를 유지하고 미확인 선택/검토와 누락 승인을 별도로 명세한다. - `docs/data-model.md`, `docs/interface-contract.md`, `docs/project-structure.md`, `docs/runtime-flow.md`: 네 정본 문서가 모두 존재한다. verified leaf authority, immutable run, `monthly_source_snapshot_id` read alias, auth-before-DB, preview drift 및 service/adapter 책임을 규정한다. - `tests/test_account_valuations.py`, `tests/test_asset_snapshots.py`, `tests/test_asset_snapshot_idempotency.py`, `tests/test_legacy_snapshot_migration.py`, `tests/test_contract_regression.py`, `tests/test_requirement_docs.py`: 기존 선택·중복/정정·수동 자산·불변/legacy 마감·응답/문서 계약의 회귀 대상이다. 기존 schema 12·future exclusion 단언은 유지할 자동 경로와 새 초안 예외를 구분해서 갱신한다. ## 문서 영향 및 산출물 ### 요구사항명세서 - 조치: 갱신 - 경로: `docs/requirements/req-003_account-valuation-history.md` - 문서 ID: `REQ-003` - 제목: 계좌 기준일 평가 이력과 자산 마감 연동 - 변경 내용: 기존 ID·파일명·제목을 유지하고 초안 생성/편집/취소, 계좌별 직접 지정, 날짜 차이와 대체 승인, 대상 갱신, 검토 버전/fingerprint, 최종화·정정 초안 및 공통 adapter 요구사항/인수 기준을 추가한다. 미래 제외 규칙을 자동/직접 마감과 승인된 초안 예외로 분리한다. 월별 단일 활성 초안과 월말 기준일 검증을 추가하고 미확인 선택·검토는 허용하되 확인/정정 자료의 명시적 재선택·재검토·승인 전 금액 합산을 금지한다. 미확인으로 남은 항목은 누락/제외 및 조건부 누락 승인으로 처리한다. 기존 append-only, 정수/NULL, 대표 부채, no-fake-transaction, auth/menu·읽기 전용 계약을 유지한다. revision과 변경 이력을 갱신하고 기존 #12/#13 추적성을 보존하면서 이번 근거 `#15`, 이번 구현 PR `미정`을 구분한다. - 포함할 내용: 무자료 생성과 no-close, 같은 키 재사용/다른 payload 충돌, 일반/정정 통합 월별 단일 활성 초안, 완료/취소 후 재생성과 기존 마감의 정정 연결, 월말 고정 기준일과 입력 일치 검증, 대상의 명시적 갱신, 준비 상태와 금액의 NULL/0, 계좌/통화/목적/대표 부채 검증, exact/carried_before/manual_substitute와 자동 미래 금지, 이후 자료의 원본 날짜·사유·승인, 미확인 초안 선택/검토, 확인/정정 자료의 명시적 재선택·재검토·승인, 미확인 금액 합산 금지 및 미해소 항목의 승인된 누락/제외, 잠정 합계·완전성·누락/제외/대체 구분, 수동 자산/부채 보존 및 drift, 검토 이후 모든 의미 있는 변경의 재승인, 단일 트랜잭션과 동시 편집 충돌/no-partial-write, persisted evidence 기반 재시도, immutable close와 명시적 정정, 거래/자산 상태 분리, Dashboard/MCP 동등 동작, schema migration 및 기존 API/보안/legacy 회귀를 정상·경계·실패 사례로 명세한다. - 제외할 내용: 거래 완료/성과 추정 보장, FX/가격 API, 자동 승인·자동 미래 선택, 인증/메뉴 재설계, 실제 금융자료, 원본 날짜 변경 및 이력 삭제. - 근거: REQ-003.02/.06/.07/.08/.09의 기존 기능과 정책을 직접 확장하는 작업이다. 영속 초안이 새 aggregate라는 이유만으로 별도 REQ-004를 만들지 않고 현 작성 규칙에 따라 갱신한다. 동일 ID를 유지하므로 신규 ID 할당은 없다. ### 데이터 모델 - 조치: 갱신 - 경로: `docs/data-model.md` - 변경 내용: 초안과 항목의 영속 엔터티를 추가해 초안→대상 항목, 항목→계좌/valuation, 초안→최종 run, 정정 초안→이전 run 관계와 필수/선택성·유일성·삭제 금지를 기록한다. 초안의 월·기준일·상태·작성자·시각·메모·버전·중복 키·완료 연결, 항목의 source identity·선택 자료·방식/사유·포함/제외·선택자·시각·버전·승인 결합 정보를 명세한다. 수동 자료는 검토 증거 값을 고정하고 원본 drift를 검출한다. 최종 run/rows에는 실제 날짜·방향 있는 차이·확인 상태·적용 금액·분류·사유·승인·누락/경고·초안 버전/fingerprint를 보존한다. 일반/정정 통합 정산 월별 활성 초안 유일성을 저장 제약과 동시성 검증으로 강제하고 완료·취소 이력은 보존한다. 월·기준일의 월말 일치 검증을 명세한다. 미확인 항목은 검토용 선택과 금액 authority를 분리하며 확인/정정 child의 명시적 재선택 후에만 합산한다. 미확인으로 남은 항목의 제외 사유와 누락 승인도 보존한다. 기존 correction/idempotency 제약, read alias와 nullable 금액 의미를 보존하고 schema 12→새 버전의 additive·반복 가능한 migration/legacy 조회/실패 및 백업 복구 경계를 문서화한다. - 근거: schema 12에는 초안/항목 persistence가 없으며 기존 `account_valuations`와 run/rows를 재사용·연결해야 한다. 원본 이력의 변경/삭제나 guessed migration은 필요하지 않다. ### 인터페이스 계약 - 조치: 갱신 - 경로: `docs/interface-contract.md` - 변경 내용: 공통 초안 생성·목록·상세·수정/대상 갱신·취소·계좌 자료 지정/해제·포함/제외·검토/검증·승인 최종화·정정 초안 operation을 정의하고 실제 구현의 snake_case 함수/MCP 도구/gateway 이름과 exact signature를 고정한다. 입력에는 초안/항목 ID·기대 버전, 월·기준일, 자료 ID·선택 방식·사유, 명시적 포함/제외와 사유, 생성/마감 키, 검토 fingerprint 및 승인자·시각/근거를 기록한다. 출력에는 준비 상태·버전, 대상/선택 증거, 날짜 차이·확인 상태, 잠정 합계·완전성·누락/승인 필요 목록, 완료 run/정정 연결과 persisted replay를 정의한다. 검증/대상 부재/상태·버전·증거 drift/승인 부족/키 충돌/동시 마감 오류의 조건·재시도·no-write를 명확히 한다. 기존 `success/error_code/error`, 자동 selector, 기존 close/report 키와 provenance 의미, Dashboard 인증 및 MCP 인증 범위를 보존한다. 초안 사용 시 직접 마감으로 안전 검증을 우회하지 못하는 경계를 규정한다. 생성·정정 생성은 같은 월의 활성 초안 중복을 검사하고 월말 아닌 입력 기준일은 거절한다. 미확인 선택은 검토용 상태를 반환하고 합계/최종화는 금액을 제외한다. 확인/정정 child를 명시적으로 다시 선택하면 버전·검토/승인을 갱신하고, 끝내 미확인인 항목은 누락/제외 승인 대상으로만 반환한다. - 근거: 기존 MCP/gateway에는 초안 mutation이 없고 현재 close는 basis-date 자료 자동 재조회 경로다. 새 공통 계약과 legacy 경로 구분이 필요하다. ### 프로젝트 구조 - 조치: 갱신 - 경로: `docs/project-structure.md` - 변경 내용: 기존 `application/monthly_settlement_service.py`의 read model을 보존하면서 초안 lifecycle의 application-layer 책임과 `account_valuation_service.py`(등록·검증·정정), `assets_service.py`(금액/증거·run 최종화), `infrastructure/sqlite/schema.py`/`migrations.py`(영속 제약/이주)의 소유권을 명확히 한다. `service.py` 공개 re-export, `adapters/mcp/server.py`/`tool_contracts.py`, `adapters/streamlit` gateway와 `dashboard/page_views/monthly_settlement.py`/`assets.py`의 연결을 실제 경로로 기록한다. 새 파일을 추가하면 그 exact 경로·책임·진입점을 문서에 반영하되 UI/MCP direct SQL, application의 Dashboard 역의존과 중복 업무 검증을 금지한다. 월별 활성 초안 유일성·월말 검증·미확인 금액 제외/확인 후 재선택의 책임을 공통 application과 SQLite 제약에 두고 adapter별 예외를 만들지 않는다. 각 변경에 대응하는 합성 테스트, 문서 검증과 기존 auth/menu/legacy 회귀 위치를 연결한다. - 근거: 기존 구조 문서는 service→SQLite와 page/tool→gateway/service 방향을 정본으로 규정한다. 새 초안 작업은 해당 책임 경계를 확장하며 별도 UI 전용 마감 로직을 만들지 않는다. ### 런타임 흐름 - 조치: 갱신 - 경로: `docs/runtime-flow.md` - 변경 내용: 인증→명시적 무자료 초안 생성→대상 동결→자료 등록/지정·해제/제외→읽기 전용 검토→버전·증거에 결합한 승인→동일 transaction에서 증거 재검증·run/rows 저장·초안 완료→불변 조회 흐름을 정의한다. 생성/정정 생성 guard는 일반/정정 통합 월별 단일 활성 초안과 월말 일치를 검증한다. 완료·취소 후 재생성은 가능하지만 기존 마감이 있으면 이전 run과 정정 사유를 연결한다. 미확인 자료 선택은 검토 필요로 전이하며 합계에는 포함하지 않는다. 확인/정정 자료를 명시적으로 재선택하면 재검토·재승인 후 최종화하고, 끝내 확인되지 않으면 누락/제외 및 조건부 누락 승인을 거친다. 변경/정정/대상 갱신은 승인을 무효화하고 검토 단계로 돌아간다. 취소는 기존 증거/run을 삭제하지 않으며 재마감은 이전 run 연결·사유·단일 correction 제약을 유지한다. 거래 준비와 자산 상태를 별도로 표시하고 외부 가격/환율 호출·추정 거래 생성은 없다. SQLite 동시 편집·키/버전 충돌, stale approval, 정정본 등장, 중복 최종화, DB 실패에 대해 no-partial-write·rollback·안전 재시도/사용자 재검토와 반환 오류를 기록한다. 관찰 정보는 초안/버전/run 상관 ID와 상태/경고 코드로 제한하고 credential/실제 계좌 자료를 로그에 남기지 않는다. - 근거: 현 runtime은 read-only preview→live authority 기반 close이며 영속 준비 단계가 없다. 기존 fingerprint drift·원자 저장·persisted replay guard를 초안 선택에 결합해 확장해야 한다. ## 미해결 질문 없음
Owner

Discovery 작성 전 이슈 원본

목적

월정산을 다음 흐름으로 진행할 수 있도록 구현한다.

월정산 초안 생성 → 계좌별 평가 스냅샷 등록·지정 → 누락 및 날짜 불일치 검토 → 최종 마감

거래 장부 정리나 월말 평가 자료 확보가 늦어지더라도 정산 초안을 먼저 만들고 자료를 하나씩 채울 수 있어야 한다.

평가 기준일이 정산 기준일과 다르더라도 사용자가 명시적으로 지정·승인하면 대체 자료로 사용할 수 있도록 한다. 원본 스냅샷의 기준일은 변경하지 않는다.

배경 및 현재 제약

현재 확인된 기능:

  • account_valuations: 계좌별 기준일 평가 이력 및 정정 기록
  • preview_asset_snapshot_close: 마감 미리보기; 초안은 영속 저장하지 않음
  • close_asset_snapshot: 마감 저장
  • asset_snapshot_runs: 확정·조건부 마감 실행 기록
  • asset_snapshots: 해당 마감에 반영된 자산별 상세

현재 날짜 선택 방식은 exact/as_of 중심이다.

  • exact: 정산 기준일과 일치하는 확인된 평가값
  • as_of: 정산 기준일 이하의 최신 확인값
  • 기준일 이후 자료를 계좌별로 직접 지정하는 기능은 확인되지 않음

자료 누락을 허용한 조건부 마감은 편집 중인 초안과 다르다. 조건부 마감을 먼저 만들고 자료 추가마다 재마감하는 방식 대신, 편집 가능한 준비 단계가 필요하다.

사용 사례

2026년 9월 정산을 시작하지만 9월 30일 평가 자료를 확보하지 못한 상황:

  1. 2026-09 정산 초안을 생성한다.
  2. 신한 개인형 IRP에는 10월 5일 평가 스냅샷을 선택한다.
  3. DC 퇴직연금에는 10월 7일 평가 스냅샷을 선택한다.
  4. 다른 계좌의 스냅샷도 차례로 등록·연결한다.
  5. 이후 날짜 자료 사용에 따른 경고와 선택 금액을 검토한다.
  6. 대체 자료 사용을 승인하고 최종 마감한다.

이 결과는 “9월 말 정확한 평가액”이 아니라 “대체 평가자료를 포함한 9월 정산”으로 표시한다.

실제 계좌번호 및 금액은 본 이슈에서 생략한다.

1. 월정산 초안 생성·저장

평가 자료가 없어도 정산 초안을 생성할 수 있어야 한다.

초안 정보

  • 초안 ID
  • 정산 월
  • 정산 기준일
  • 상태
  • 생성자·생성 시각
  • 변경 시각
  • 메모
  • 동시 편집 제어용 버전
  • 생성 중복 방지 키
  • 최종 마감 ID 연결

원칙

  • 초안 생성은 자산 금액 확정이나 월마감 실행이 아니다.
  • 자료가 부족해도 초안을 저장할 수 있다.
  • 같은 정산 월의 활성 초안 중복 생성 정책을 정의한다.
  • 완료·취소된 초안 및 정정 작업의 관계를 명확히 한다.
  • 초안 취소는 기존 평가 증빙이나 마감 기록을 삭제하지 않는다.
  • 정산 월과 기준일의 관계를 검증한다.

별도 초안 테이블과 항목 테이블을 권장하되, 기존 모델을 검토하여 최종 구조를 결정한다.

2. 정산 대상 및 계좌별 항목

초안에서 정산 대상 계좌·자산 목록과 준비 상태를 관리한다.

계좌별 항목 정보

  • 초안 ID
  • 계좌 ID
  • 선택한 valuation_id
  • 선택 방식
  • 선택 사유
  • 포함·제외 여부
  • 제외 사유
  • 선택자·선택 시각
  • 대체 자료 승인 정보
  • 항목 버전

준비 상태 예시

  • 미선택
  • 확인된 기준일 자료 선택
  • 이전 자료 이월
  • 이후 자료 대체 선택
  • 미확인 자료 선택
  • 제외
  • 검토 필요

기존 수동 자산·부채도 정산에 누락되지 않도록 포함 범위를 정의한다. 계좌 평가 이력만 구현하더라도 기존 수동 자산 처리와 호환되어야 한다.

정산 대상 변경이나 새 계좌 추가 시 자동으로 확정 범위가 바뀌지 않도록, 대상 갱신 정책을 명시한다.

3. 스냅샷 등록 및 직접 지정

  • 기존 account_valuations 기록을 조회·선택할 수 있다.
  • 새 평가 스냅샷을 등록한 뒤 초안 항목에 연결할 수 있다.
  • 선택한 기록이 해당 계좌에 속하는지 검증한다.
  • 통화와 평가 종류가 정산 목적에 적합한지 검증한다.
  • 평가액·원금·현금성 잔액의 중복 합산을 방지한다.
  • 계좌별 대표 합산값은 하나로 명확히 선택한다.
  • 동일 증빙 재등록의 중복 방지 기능을 유지한다.

4. 평가 자료 선택 방식

exact

정산 기준일과 일치하는 확인된 평가값을 선택한다.

carried_before

정산 기준일 이전의 평가값을 이월하여 사용한다.

실제 평가일과 경과 일수를 표시하고, 이월 사용 승인 근거를 남긴다.

manual_substitute

사용자가 특정 평가 기록을 직접 지정한다.

정산 기준일 이후 자료도 허용하되:

  • 실제 평가 기준일을 유지한다.
  • 정산 기준일과의 날짜 차이를 표시한다.
  • 대체 사유를 요구한다.
  • 최종 마감 시 명시적인 승인을 요구한다.
  • 정확한 월말 평가액으로 표시하지 않는다.

공통 원칙

  • 자동 선택은 기준일 이후 자료를 임의로 선택하지 않는다.
  • 사용자 직접 지정만 승인된 예외로 허용한다.
  • 이후 자료를 사용하기 위해 원본 기준일을 소급 변경하지 않는다.
  • 등록일이 늦은 것과 평가 기준일이 다른 것을 구분한다.
    • 10월에 등록한 9월 30일 자료: exact 가능
    • 10월 5일 평가 자료: manual_substitute
  • 날짜 차이는 방향을 포함하여 표시한다.
  • 허용 범위 제한이 필요하면 설정값으로 정의하고, 임의 기준을 하드코딩하지 않는다.

5. 초안 검토 및 합계

초안 화면과 API에서 다음 정보를 제공한다.

  • 정산 대상 및 포함·제외 계좌
  • 선택한 스냅샷 ID
  • 대표 금액·통화·자산 또는 부채 분류
  • 실제 평가일과 정산 기준일
  • 선택 방식 및 날짜 차이
  • 증빙 출처·확인 상태
  • 선택·대체·제외 사유
  • 누락 및 승인 필요 항목
  • 잠정 총자산·총부채·순자산

표시 원칙

  • 초안 합계는 잠정값으로 표시한다.
  • 미선택 금액을 실제 0원으로 오인하지 않도록 한다.
  • 자료가 없거나 일부만 선택된 결과를 완전한 가계 자산으로 표시하지 않는다.
  • 대체 자료가 포함되면 이를 합계와 보고서에 표시한다.
  • 미등록 부채가 없다는 이유만으로 실제 부채가 없다고 단정하지 않는다.
  • 서로 다른 통화를 환율 정책 없이 단순 합산하지 않는다.

6. 최종 마감

최종 마감은 사용자가 검토한 초안의 선택 내역을 기준으로 한다.

현재값을 다시 자동 선택하여 초안의 선택을 조용히 바꾸면 안 된다.

저장할 정보

  • 원본 초안 ID 및 버전
  • 정산 월·기준일
  • 계좌별 선택한 valuation_id
  • 적용 금액·통화·분류
  • 실제 평가 기준일
  • 선택 방식 및 날짜 차이
  • 증빙과 확인 상태
  • 포함·제외·대체 사유
  • 승인자·승인 시각·승인 근거
  • 경고 및 누락 내역

기존 asset_snapshot_runs와 asset_snapshots에 연결하거나 필요한 필드를 확장한다.

마감 구분

  • 기준일 일치 자료로 완전하게 마감
  • 이월·대체 자료를 포함한 마감
  • 누락 항목을 명시적으로 승인한 조건부 마감
    구체적인 상태명은 기존 구현과 정합성을 유지하여 결정한다. 대체 자료 사용과 자료 누락은 별도 정보로 식별 가능해야 한다.

안전성

  • 승인하지 않은 대체·누락·미확인 자료는 확정 마감을 차단한다.
  • 승인 당시 초안 버전 또는 fingerprint와 실제 마감 대상을 비교한다.
  • 승인 후 선택 내역이 변경되면 재검토·재승인이 필요하다.
  • 마감 저장과 초안 상태 변경은 하나의 트랜잭션으로 처리한다.
  • 재시도와 중복 클릭은 동일 마감을 중복 생성하지 않는다.
  • 마감 실패 시 초안이 완료 상태로 남지 않는다.

7. 스냅샷 정정 및 재마감

초안 단계

선택한 스냅샷에 새 정정본이 생기면 검토 필요 상태를 표시한다.

  • 기존 선택을 조용히 교체하지 않는다.
  • 정정본으로 갱신할지 사용자가 결정한다.
  • 대체 승인에 영향을 주는 변경은 재승인한다.

마감 이후

  • 계좌 최신 평가값이나 평가 이력 정정이 기존 마감을 변경하지 않는다.
  • 정정하려면 명시적으로 새 초안 또는 정정 초안을 연다.
  • 재마감은 이전 마감과 연결된 새 버전으로 저장한다.
  • 정정 사유와 이전 기록을 보존한다.
  • 나중에 정확한 월말 자료를 확보하면 대체 자료를 교체하여 정정 마감할 수 있다.

8. 거래 정산과 자산 마감 분리

거래 장부 정리가 미완료여도 자산 마감을 진행할 수 있어야 한다.

  • 자산 마감 상태와 거래 정산 상태를 구분한다.
  • 거래 미수입 때문에 계좌 평가 증빙 등록을 막지 않는다.
  • 자산 증감을 자동으로 수입·지출 또는 투자 수익으로 처리하지 않는다.
  • 투자 평가액의 변화에는 납입·인출·시장가격 변동이 섞일 수 있음을 표시한다.
  • 본 기능은 거래 분류 완료나 정확한 투자 성과 계산을 보장하지 않는다.

9. 대시보드 및 MCP

대시보드

  • 월정산 초안 생성·목록·상세·저장·취소
  • 계좌별 스냅샷 조회·등록·지정·선택 해제
  • 실제 평가일·날짜 차이·선택 방식 표시
  • 누락·제외·대체 자료 검토
  • 승인 및 최종 마감
  • 확정 마감 조회와 정정 초안 생성

MCP

동일 작업을 수행할 도구를 제공한다.

필요 기능:

  • 초안 생성·조회·목록
  • 계좌별 스냅샷 지정·해제
  • 포함·제외 및 사유 변경
  • 초안 미리보기·검증
  • 승인된 초안 마감
  • 초안 취소
  • 정정 초안 생성

도구명은 기존 명명 규칙에 맞춰 결정한다.

대시보드와 MCP는 동일한 검증·선택·마감 서비스 로직을 사용한다.

10. 호환성 및 범위

  • 기존 account_valuations 및 정정 이력을 재사용한다.
  • 기존 마감 기록은 보존한다.
  • 기존 exact/as_of 자동 선택 방식도 유지한다.
  • 초안 기반 마감과 기존 직접 마감의 관계를 문서화한다.
  • 안전 검증을 우회하는 경로가 생기지 않도록 한다.
  • 스키마 마이그레이션과 기존 API 호환성 테스트를 제공한다.
  • 대체 자료로 실제 월말 평가액을 역산하거나 투자 성과를 추정하는 기능은 필수 범위가 아니다.

수락 기준 및 회귀 테스트

  • 평가 자료가 없어도 월정산 초안을 생성·저장할 수 있다.
  • 초안 생성만으로 확정 마감 기록이 생성되지 않는다.
  • 계좌별 스냅샷을 하나씩 등록·지정하고 준비 상태를 저장할 수 있다.
  • 타 계좌의 스냅샷 지정과 부적합한 평가 종류·통화를 검증한다.
  • 늦게 등록한 정확한 월말 자료와 이후 날짜 대체 자료를 구분한다.
  • 9월 정산에 10월 5일·7일 자료를 직접 지정할 수 있다.
  • 이후 자료의 실제 기준일은 변경되지 않는다.
  • 자동 선택은 미래 자료를 사용하지 않는다.
  • 대체 자료 사용에 사유와 명시적인 승인이 필요하다.
  • 자료 누락·이월·대체 여부를 잠정 합계 및 마감 보고서에 표시한다.
  • 미확인 금액과 실제 0원을 구분한다.
  • 원금·평가액·현금성 잔액을 중복 합산하지 않는다.
  • 승인 후 초안 변경 시 마감을 차단하고 재승인을 요구한다.
  • 마감은 선택한 평가 기록과 금액을 고정하여 저장한다.
  • 마감 재시도·중복 클릭으로 기록이 중복 생성되지 않는다.
  • 초안 상태 변경과 마감 저장의 원자성을 검증한다.
  • 평가 이력 정정이 초안 선택이나 확정 마감을 조용히 변경하지 않는다.
  • 정확한 자료 확보 후 정정 초안·재마감으로 대체 자료를 교체할 수 있다.
  • 거래 정산 미완료 상태에서도 자산 마감이 가능하다.
  • 기존 마감·평가 이력과 MCP·대시보드 호환성을 유지한다.
<!-- gitea-agent:discovery-origin/v1 owner=jsfamily repository=jarca-ledger-mcp issue=15 body-sha256=37b2caf969e63d68e983065f030e3e294fabc2364cd58c2763773a6242e1086a --> ## Discovery 작성 전 이슈 원본 ## 목적 월정산을 다음 흐름으로 진행할 수 있도록 구현한다. 월정산 초안 생성 → 계좌별 평가 스냅샷 등록·지정 → 누락 및 날짜 불일치 검토 → 최종 마감 거래 장부 정리나 월말 평가 자료 확보가 늦어지더라도 정산 초안을 먼저 만들고 자료를 하나씩 채울 수 있어야 한다. 평가 기준일이 정산 기준일과 다르더라도 사용자가 명시적으로 지정·승인하면 대체 자료로 사용할 수 있도록 한다. 원본 스냅샷의 기준일은 변경하지 않는다. ## 배경 및 현재 제약 현재 확인된 기능: - `account_valuations`: 계좌별 기준일 평가 이력 및 정정 기록 - `preview_asset_snapshot_close`: 마감 미리보기; 초안은 영속 저장하지 않음 - `close_asset_snapshot`: 마감 저장 - `asset_snapshot_runs`: 확정·조건부 마감 실행 기록 - `asset_snapshots`: 해당 마감에 반영된 자산별 상세 현재 날짜 선택 방식은 exact/as_of 중심이다. - exact: 정산 기준일과 일치하는 확인된 평가값 - as_of: 정산 기준일 이하의 최신 확인값 - 기준일 이후 자료를 계좌별로 직접 지정하는 기능은 확인되지 않음 자료 누락을 허용한 조건부 마감은 편집 중인 초안과 다르다. 조건부 마감을 먼저 만들고 자료 추가마다 재마감하는 방식 대신, 편집 가능한 준비 단계가 필요하다. ## 사용 사례 2026년 9월 정산을 시작하지만 9월 30일 평가 자료를 확보하지 못한 상황: 1. `2026-09` 정산 초안을 생성한다. 2. 신한 개인형 IRP에는 10월 5일 평가 스냅샷을 선택한다. 3. DC 퇴직연금에는 10월 7일 평가 스냅샷을 선택한다. 4. 다른 계좌의 스냅샷도 차례로 등록·연결한다. 5. 이후 날짜 자료 사용에 따른 경고와 선택 금액을 검토한다. 6. 대체 자료 사용을 승인하고 최종 마감한다. 이 결과는 “9월 말 정확한 평가액”이 아니라 “대체 평가자료를 포함한 9월 정산”으로 표시한다. 실제 계좌번호 및 금액은 본 이슈에서 생략한다. ## 1. 월정산 초안 생성·저장 평가 자료가 없어도 정산 초안을 생성할 수 있어야 한다. ### 초안 정보 - 초안 ID - 정산 월 - 정산 기준일 - 상태 - 생성자·생성 시각 - 변경 시각 - 메모 - 동시 편집 제어용 버전 - 생성 중복 방지 키 - 최종 마감 ID 연결 ### 원칙 - 초안 생성은 자산 금액 확정이나 월마감 실행이 아니다. - 자료가 부족해도 초안을 저장할 수 있다. - 같은 정산 월의 활성 초안 중복 생성 정책을 정의한다. - 완료·취소된 초안 및 정정 작업의 관계를 명확히 한다. - 초안 취소는 기존 평가 증빙이나 마감 기록을 삭제하지 않는다. - 정산 월과 기준일의 관계를 검증한다. 별도 초안 테이블과 항목 테이블을 권장하되, 기존 모델을 검토하여 최종 구조를 결정한다. ## 2. 정산 대상 및 계좌별 항목 초안에서 정산 대상 계좌·자산 목록과 준비 상태를 관리한다. ### 계좌별 항목 정보 - 초안 ID - 계좌 ID - 선택한 `valuation_id` - 선택 방식 - 선택 사유 - 포함·제외 여부 - 제외 사유 - 선택자·선택 시각 - 대체 자료 승인 정보 - 항목 버전 ### 준비 상태 예시 - 미선택 - 확인된 기준일 자료 선택 - 이전 자료 이월 - 이후 자료 대체 선택 - 미확인 자료 선택 - 제외 - 검토 필요 기존 수동 자산·부채도 정산에 누락되지 않도록 포함 범위를 정의한다. 계좌 평가 이력만 구현하더라도 기존 수동 자산 처리와 호환되어야 한다. 정산 대상 변경이나 새 계좌 추가 시 자동으로 확정 범위가 바뀌지 않도록, 대상 갱신 정책을 명시한다. ## 3. 스냅샷 등록 및 직접 지정 - 기존 `account_valuations` 기록을 조회·선택할 수 있다. - 새 평가 스냅샷을 등록한 뒤 초안 항목에 연결할 수 있다. - 선택한 기록이 해당 계좌에 속하는지 검증한다. - 통화와 평가 종류가 정산 목적에 적합한지 검증한다. - 평가액·원금·현금성 잔액의 중복 합산을 방지한다. - 계좌별 대표 합산값은 하나로 명확히 선택한다. - 동일 증빙 재등록의 중복 방지 기능을 유지한다. ## 4. 평가 자료 선택 방식 ### exact 정산 기준일과 일치하는 확인된 평가값을 선택한다. ### carried_before 정산 기준일 이전의 평가값을 이월하여 사용한다. 실제 평가일과 경과 일수를 표시하고, 이월 사용 승인 근거를 남긴다. ### manual_substitute 사용자가 특정 평가 기록을 직접 지정한다. 정산 기준일 이후 자료도 허용하되: - 실제 평가 기준일을 유지한다. - 정산 기준일과의 날짜 차이를 표시한다. - 대체 사유를 요구한다. - 최종 마감 시 명시적인 승인을 요구한다. - 정확한 월말 평가액으로 표시하지 않는다. ### 공통 원칙 - 자동 선택은 기준일 이후 자료를 임의로 선택하지 않는다. - 사용자 직접 지정만 승인된 예외로 허용한다. - 이후 자료를 사용하기 위해 원본 기준일을 소급 변경하지 않는다. - 등록일이 늦은 것과 평가 기준일이 다른 것을 구분한다. - 10월에 등록한 9월 30일 자료: exact 가능 - 10월 5일 평가 자료: manual_substitute - 날짜 차이는 방향을 포함하여 표시한다. - 허용 범위 제한이 필요하면 설정값으로 정의하고, 임의 기준을 하드코딩하지 않는다. ## 5. 초안 검토 및 합계 초안 화면과 API에서 다음 정보를 제공한다. - 정산 대상 및 포함·제외 계좌 - 선택한 스냅샷 ID - 대표 금액·통화·자산 또는 부채 분류 - 실제 평가일과 정산 기준일 - 선택 방식 및 날짜 차이 - 증빙 출처·확인 상태 - 선택·대체·제외 사유 - 누락 및 승인 필요 항목 - 잠정 총자산·총부채·순자산 ### 표시 원칙 - 초안 합계는 잠정값으로 표시한다. - 미선택 금액을 실제 0원으로 오인하지 않도록 한다. - 자료가 없거나 일부만 선택된 결과를 완전한 가계 자산으로 표시하지 않는다. - 대체 자료가 포함되면 이를 합계와 보고서에 표시한다. - 미등록 부채가 없다는 이유만으로 실제 부채가 없다고 단정하지 않는다. - 서로 다른 통화를 환율 정책 없이 단순 합산하지 않는다. ## 6. 최종 마감 최종 마감은 사용자가 검토한 초안의 선택 내역을 기준으로 한다. 현재값을 다시 자동 선택하여 초안의 선택을 조용히 바꾸면 안 된다. ### 저장할 정보 - 원본 초안 ID 및 버전 - 정산 월·기준일 - 계좌별 선택한 `valuation_id` - 적용 금액·통화·분류 - 실제 평가 기준일 - 선택 방식 및 날짜 차이 - 증빙과 확인 상태 - 포함·제외·대체 사유 - 승인자·승인 시각·승인 근거 - 경고 및 누락 내역 기존 `asset_snapshot_runs`와 `asset_snapshots`에 연결하거나 필요한 필드를 확장한다. ### 마감 구분 - 기준일 일치 자료로 완전하게 마감 - 이월·대체 자료를 포함한 마감 - 누락 항목을 명시적으로 승인한 조건부 마감 구체적인 상태명은 기존 구현과 정합성을 유지하여 결정한다. 대체 자료 사용과 자료 누락은 별도 정보로 식별 가능해야 한다. ### 안전성 - 승인하지 않은 대체·누락·미확인 자료는 확정 마감을 차단한다. - 승인 당시 초안 버전 또는 fingerprint와 실제 마감 대상을 비교한다. - 승인 후 선택 내역이 변경되면 재검토·재승인이 필요하다. - 마감 저장과 초안 상태 변경은 하나의 트랜잭션으로 처리한다. - 재시도와 중복 클릭은 동일 마감을 중복 생성하지 않는다. - 마감 실패 시 초안이 완료 상태로 남지 않는다. ## 7. 스냅샷 정정 및 재마감 ### 초안 단계 선택한 스냅샷에 새 정정본이 생기면 검토 필요 상태를 표시한다. - 기존 선택을 조용히 교체하지 않는다. - 정정본으로 갱신할지 사용자가 결정한다. - 대체 승인에 영향을 주는 변경은 재승인한다. ### 마감 이후 - 계좌 최신 평가값이나 평가 이력 정정이 기존 마감을 변경하지 않는다. - 정정하려면 명시적으로 새 초안 또는 정정 초안을 연다. - 재마감은 이전 마감과 연결된 새 버전으로 저장한다. - 정정 사유와 이전 기록을 보존한다. - 나중에 정확한 월말 자료를 확보하면 대체 자료를 교체하여 정정 마감할 수 있다. ## 8. 거래 정산과 자산 마감 분리 거래 장부 정리가 미완료여도 자산 마감을 진행할 수 있어야 한다. - 자산 마감 상태와 거래 정산 상태를 구분한다. - 거래 미수입 때문에 계좌 평가 증빙 등록을 막지 않는다. - 자산 증감을 자동으로 수입·지출 또는 투자 수익으로 처리하지 않는다. - 투자 평가액의 변화에는 납입·인출·시장가격 변동이 섞일 수 있음을 표시한다. - 본 기능은 거래 분류 완료나 정확한 투자 성과 계산을 보장하지 않는다. ## 9. 대시보드 및 MCP ### 대시보드 - 월정산 초안 생성·목록·상세·저장·취소 - 계좌별 스냅샷 조회·등록·지정·선택 해제 - 실제 평가일·날짜 차이·선택 방식 표시 - 누락·제외·대체 자료 검토 - 승인 및 최종 마감 - 확정 마감 조회와 정정 초안 생성 ### MCP 동일 작업을 수행할 도구를 제공한다. 필요 기능: - 초안 생성·조회·목록 - 계좌별 스냅샷 지정·해제 - 포함·제외 및 사유 변경 - 초안 미리보기·검증 - 승인된 초안 마감 - 초안 취소 - 정정 초안 생성 도구명은 기존 명명 규칙에 맞춰 결정한다. 대시보드와 MCP는 동일한 검증·선택·마감 서비스 로직을 사용한다. ## 10. 호환성 및 범위 - 기존 `account_valuations` 및 정정 이력을 재사용한다. - 기존 마감 기록은 보존한다. - 기존 exact/as_of 자동 선택 방식도 유지한다. - 초안 기반 마감과 기존 직접 마감의 관계를 문서화한다. - 안전 검증을 우회하는 경로가 생기지 않도록 한다. - 스키마 마이그레이션과 기존 API 호환성 테스트를 제공한다. - 대체 자료로 실제 월말 평가액을 역산하거나 투자 성과를 추정하는 기능은 필수 범위가 아니다. ## 수락 기준 및 회귀 테스트 - [ ] 평가 자료가 없어도 월정산 초안을 생성·저장할 수 있다. - [ ] 초안 생성만으로 확정 마감 기록이 생성되지 않는다. - [ ] 계좌별 스냅샷을 하나씩 등록·지정하고 준비 상태를 저장할 수 있다. - [ ] 타 계좌의 스냅샷 지정과 부적합한 평가 종류·통화를 검증한다. - [ ] 늦게 등록한 정확한 월말 자료와 이후 날짜 대체 자료를 구분한다. - [ ] 9월 정산에 10월 5일·7일 자료를 직접 지정할 수 있다. - [ ] 이후 자료의 실제 기준일은 변경되지 않는다. - [ ] 자동 선택은 미래 자료를 사용하지 않는다. - [ ] 대체 자료 사용에 사유와 명시적인 승인이 필요하다. - [ ] 자료 누락·이월·대체 여부를 잠정 합계 및 마감 보고서에 표시한다. - [ ] 미확인 금액과 실제 0원을 구분한다. - [ ] 원금·평가액·현금성 잔액을 중복 합산하지 않는다. - [ ] 승인 후 초안 변경 시 마감을 차단하고 재승인을 요구한다. - [ ] 마감은 선택한 평가 기록과 금액을 고정하여 저장한다. - [ ] 마감 재시도·중복 클릭으로 기록이 중복 생성되지 않는다. - [ ] 초안 상태 변경과 마감 저장의 원자성을 검증한다. - [ ] 평가 이력 정정이 초안 선택이나 확정 마감을 조용히 변경하지 않는다. - [ ] 정확한 자료 확보 후 정정 초안·재마감으로 대체 자료를 교체할 수 있다. - [ ] 거래 정산 미완료 상태에서도 자산 마감이 가능하다. - [ ] 기존 마감·평가 이력과 MCP·대시보드 호환성을 유지한다.
Sign in to join this conversation.