diff --git a/docs/discovery/dcy-012_20260714_manual-ledger-write-api-owner-scoped.md b/docs/discovery/dcy-012_20260714_manual-ledger-write-api-owner-scoped.md index 42c4520..2ebb3ce 100644 --- a/docs/discovery/dcy-012_20260714_manual-ledger-write-api-owner-scoped.md +++ b/docs/discovery/dcy-012_20260714_manual-ledger-write-api-owner-scoped.md @@ -110,6 +110,7 @@ - FR-11: manual ledger history 조회 API는 portfolio별 최근 ledger entries를 반환해야 한다. action, amount/quantity/price/fee/tax, note, recorded_at, after-snapshot을 trex-web이 표시할 수 있어야 한다. - FR-12: disabled portfolio write는 현행 state rule과 일관되게 거부한다. - FR-13: daemon-managed portfolio에 manual ledger write 시 완전 차단하지 않는다. 대신 response/request contract에 trex-web이 강한 경고와 명시 확인을 표현할 수 있는 정책을 포함한다. +- FR-14: manual endpoint는 1차 범위에서 새 음수 상태를 만드는 write를 거부한다. `BUY`는 `quantity * price + fee + tax > cash_balance`이면 HTTP 409, `SELL`은 `quantity > asset_quantity`이면 HTTP 409, `BUFFER_OUT`/`WITHDRAW`는 `amount > profit_buffer`이면 HTTP 409, `BUFFER_IN`은 `amount > cash_balance`이면 HTTP 409로 거부한다. `INVEST`는 `amount > 0`이면 허용한다. ## 비기능 요구사항 - NFR-1: ledger append와 portfolio snapshot update는 단일 DB 트랜잭션으로 처리되어야 한다. @@ -147,7 +148,7 @@ - R-3 (Medium): manual write와 daemon write가 같은 portfolio에서 혼재되어 운영자가 상태를 오해. - 완화: source 분리, daemon-managed warning/explicit confirmation policy, history 표시. - R-4 (Medium): 기존 CLI/domain 흐름과 신규 API 회계 공식이 divergence. - - 완화: shared domain helper 추출 또는 동일 test vectors로 검증. + - 완화: shared domain helper 추출 또는 동일 test vectors로 검증. manual API는 1차에서 부족 cash/quantity/buffer를 거부하므로 기존 CLI/domain validation 정책과 의도적 차이가 있다면 REQ에서 명시한다. - R-5 (Mitigated): `REVERSAL`이 target entry 참조 없이 notes 기반으로만 남아 audit성이 약해질 수 있음. - 완화: 사용자 결정(2026-07-14)에 따라 `target_ledger_entry_id`를 필수로 한다. REQ에서는 컬럼/metadata 저장 위치와 중복 reversal 방지 규칙을 구체화한다. - R-6 (Low): `PROFIT` legacy action과 `BUFFER_IN`/`WITHDRAW` 의미가 사용자 UI에서 혼동. @@ -173,9 +174,11 @@ - REQ 세부화 항목: target이 같은 portfolio 소속인지 검증, 이미 reversed 된 entry의 재 reversal 금지 여부, REVERSAL 자체 reversal 허용 여부, target reference 저장 위치(정식 컬럼 vs metadata)를 확정한다. - 종료 조건: 완료 - OQ-3: manual `BUY`/`SELL`에서 잔고/수량 부족을 거부할 것인가, 표시 음수 허용 정책과 맞춰 결과 음수를 허용할 것인가? - - 사용자 정책: trex-web UI 입력 음수 금지, 기존/결과 표시 음수 허용. - - 상태: Open - - 종료 조건: portfolio-hub validation policy 확정 + - 상태: Answered + - 결정: manual endpoint 1차에서는 부족 cash/quantity/buffer를 거부한다. `BUY`는 required cash(`quantity * price + fee + tax`)가 `cash_balance`를 초과하면 HTTP 409, `SELL`은 requested quantity가 `asset_quantity`를 초과하면 HTTP 409, `BUFFER_OUT`/`WITHDRAW`는 amount가 `profit_buffer`를 초과하면 HTTP 409, `BUFFER_IN`은 amount가 `cash_balance`를 초과하면 HTTP 409로 거부한다. `INVEST`는 amount > 0이면 허용한다. + - 사용자 정책 정합: trex-web UI 입력 음수 금지, 기존/결과 표시 음수 허용. 즉 read/display에서는 기존 음수 상태를 숨기지 않지만, manual write가 새 음수 상태를 만드는 것은 1차에서 금지한다. + - 근거: 수동 입력은 사전 검증 가능한 operation이고, `QUANTITY_ADJUSTMENT`를 1차 제외했으므로 부족 수량 SELL 허용은 우회 보정 기능이 될 수 있다. + - 종료 조건: 완료 - OQ-4: daemon-managed portfolio write 시 API가 `warning_required`/`confirmation_token` 같은 기계적 확인 필드를 요구할 것인가, 아니면 trex-web UI 경고만으로 충분한가? - 상태: Open - 종료 조건: API-level safety contract 확정 @@ -207,7 +210,7 @@ # 8. REQ로 넘기기 전 확인 체크 - [x] API endpoint shape 확정(OQ-1) — 기존 `/ledger/trades` 유지 + 신규 `POST /v1/portfolios/{portfolio_id}/ledger/manual` 추가 - [x] REVERSAL target/reference policy 확정(OQ-2) — `target_ledger_entry_id` 필수 -- [ ] 부족 잔고/수량 validation policy 확정(OQ-3) +- [x] 부족 잔고/수량 validation policy 확정(OQ-3) — manual write가 새 음수 상태를 만드는 것은 1차 거부 - [ ] daemon-managed confirmation contract 확정(OQ-4) - [ ] history response fields 확정(OQ-5) - [ ] legacy `PROFIT` mapping policy 확정(OQ-6) @@ -230,7 +233,7 @@ ## DECIDE - ~~API shape: 단일 action-dispatch endpoint vs action별 endpoint~~ → 기존 `/ledger/trades` 유지, 신규 `POST /v1/portfolios/{portfolio_id}/ledger/manual` + `action` enum 추가 - ~~REVERSAL target ledger id/reference 필수 여부~~ → `target_ledger_entry_id` 필수 -- 부족 cash/quantity 시 validation 거부 vs 결과 음수 허용 +- ~~부족 cash/quantity 시 validation 거부 vs 결과 음수 허용~~ → manual write는 부족 cash/quantity/buffer 409 거부, read/display 음수 표시는 허용 - daemon-managed portfolio warning/confirmation을 API-level로 강제할지 UI-level로 둘지 - history response에 `total_value_after` 포함 여부 - legacy `PROFIT` action 노출/매핑 정책 @@ -246,7 +249,7 @@ # 11. Discovery Freeze - Handoff Decision: 보류(draft) -- Handoff Rationale: trex-web dcy-011의 backend-first 후속 Discovery로 생성했다. 현행 portfolio-hub 구조와 action/effect는 확인했고, 기존 `/ledger/trades` 유지 + 신규 `/ledger/manual` 추가 방향은 확정했다. 남은 결정은 validation, daemon-managed confirmation contract, history fields, legacy PROFIT mapping이다. +- Handoff Rationale: trex-web dcy-011의 backend-first 후속 Discovery로 생성했다. 현행 portfolio-hub 구조와 action/effect는 확인했고, 기존 `/ledger/trades` 유지 + 신규 `/ledger/manual` 추가 방향은 확정했다. 남은 결정은 daemon-managed confirmation contract, history fields, legacy PROFIT mapping이다. - Ready for REQ Drafting: false - Confirmed By: 미정 - Confirmed At (KST): 미정