## 구현 진행 상황 - **대상:** Fix investment totals: remove source='manual' filter from ledger aggregates - **브랜치:** `main` - **기준:** `main` (`02bfa602995b8e1c2f410c9bd5762f062666f2d6`) - **상태:** 로컬 `main` 구현·검증·독립 재QC·커밋 완료 — 미푸시, 미배포 - **최종 업데이트:** 2026-08-19 17:34:13 KST ### 구현 계획 및 작업 목록 - [x] 투자 원금 집계를 모든 source로 확장 - `total_invested`는 유효한 모든 `INVEST`의 gross 합계로 유지하고, `net_contributed_capital`은 `INVEST - WITHDRAW`로 계산한다. - [x] 수익 인출을 투자 원금과 분리 - `PROFIT`는 원금 계산에서 제외하고 `cumulative_profit_withdrawn`으로만 집계한다. - [x] Source와 무관한 reversal 제외 보장 - 동일 portfolio의 matching `REVERSAL.target_ledger_entry_id`가 있으면 original row와 reversal의 source와 관계없이 원본을 제외한다. - [x] 기존 ledger data와 accounting side 경계 보존 - Existing ledger row를 mutation/backfill하지 않고 query semantic만 교정하며 `buffer_out` 등 다른 side를 `INVEST`로 재해석하지 않는다. - [x] List와 단건 returns summary의 동일한 의미 유지 - `GET /v1/portfolios`와 `GET /v1/portfolios/{portfolio_id}/returns/summary`가 같은 repository aggregate를 사용함을 검증한다. - [x] Non-manual 및 mixed-source 회귀 테스트 추가 - Non-zero broker `INVEST`, manual/broker 혼합 `INVEST`·`WITHDRAW`·`PROFIT`, source-independent reversal을 검증한다. - [x] API 및 interface 문서 갱신 - `total_invested`, `total_withdrawn`, `net_contributed_capital`, `cumulative_profit_withdrawn`의 all-source 의미와 `PROFIT` 분리 경계를 명시한다. - [x] 전체 회귀와 변경 범위 정적 검증 - Focused tests, full repository tests, 변경 범위 lint와 diff 검사를 실행한다. - [x] 독립 QC 및 완료 경계 기록 - Blocker/Major/Minor를 독립 검토하고 local 구현·검증과 push·release·deployment를 구분해 기록한다. ### 진행 기록 - 2026-08-19 17:23:19 KST — Issue #28의 승인된 OQ-1-A~OQ-5-A와 구현 경계를 확인했다. - 2026-08-19 17:23:19 KST — 별도 worktree 없이 clean local `main`의 기준 SHA를 고정하고 구현·검증을 시작했다. - 2026-08-19 17:25:55 KST — Original과 reversal의 `source='manual'` predicate를 제거하고 side별 gross INVEST, WITHDRAW, PROFIT 분리 계산을 구현했다. - 2026-08-19 17:25:55 KST — API schema와 data-model/runtime-flow 문서를 all-source semantics, PROFIT 분리, source-independent reversal 경계로 갱신했다. - 2026-08-19 17:25:55 KST — Focused API/repository tests `38 passed`; disposable PostgreSQL 16에서 broker-only, mixed source, 양방향 cross-source reversal, `buffer_out` 제외 semantic test `1 passed`. - 2026-08-19 17:25:55 KST — 전체 파일 Ruff에는 candidate 이전부터 존재한 오류가 있어 변경 범위와 구분해 기록했고, 신규 파일 lint 및 diff 검사는 PASS했다. - 2026-08-19 17:28:28 KST — 원본 checkout full suite는 기존 `temp/deleted_20260813/.worktrees/` 복제본을 grep하는 auth surface tests 3건만 실패하고 `657 passed, 16 skipped`였다. 해당 pre-existing artifact를 제외한 clean candidate copy에서 full suite `660 passed, 16 skipped`로 PASS했다. - 2026-08-19 17:28:28 KST — 구현 범위의 독립 read-only QC를 시작했다. QC 결과 반영 전에는 최종 완료로 표시하지 않는다. - 2026-08-19 17:32:35 KST — 최초 독립 QC는 Blocker 0 / Major 1 / Minor 0으로, `docs/interface-contract.md`의 manual-only 외부 계약이 구현과 충돌한다고 판정했다. - 2026-08-19 17:32:35 KST — 외부 interface contract의 list/summary 의미, source-independent reversal, non-capital side 제외와 change log를 갱신하고 문서 계약 회귀 테스트를 추가했다. - 2026-08-19 17:32:35 KST — 보완 후 focused `39 passed`, test-file Ruff·diff check PASS, clean candidate full suite `661 passed, 16 skipped`로 재검증하고 독립 재QC를 시작했다. - 2026-08-19 17:34:13 KST — 독립 재QC가 PASS(Blocker 0 / Major 0 / Minor 0)했다. - 2026-08-19 17:34:13 KST — 로컬 `main`에 `5eb8c042668b1c383ac59ca9be00aa1a5dfcb37a` (`fix: aggregate investment totals across ledger sources`)로 커밋했다. Push, PR, release, deployment와 production read-only pre/post check는 수행하지 않았다. > 각 작업이 실제로 완료되고 검증될 때마다 이 댓글의 체크박스와 진행 기록을 갱신한다. 체크 표시는 구현 완료 또는 해당 검증의 실제 통과를 의미하며, 배포·릴리스 완료를 의미하지 않는다.