docs(discovery): decide manual ledger endpoint split
This commit is contained in:
@@ -26,6 +26,7 @@
|
||||
- 해석:
|
||||
- portfolio-hub에는 수동 장부에 필요한 도메인 서비스/CLI 흐름이 상당 부분 존재하지만, trex-web이 사용할 **HTTP v1 user-token owner-scoped API 계약**은 아직 정식 제품 계약으로 정리되어 있지 않다.
|
||||
- 현재 v1 service-token endpoint(`POST /v1/portfolios/{portfolio_id}/ledger/trades`)는 daemon/trade-write 체결 보고용이다. 사용자 수동 장부 입력은 owner-scoped user/session token 기반으로 분리해야 한다.
|
||||
- **사용자 결정(2026-07-14)**: 기존 `POST /v1/portfolios/{portfolio_id}/ledger/trades`는 trex-core/daemon/service-token broker trade write 전용으로 유지한다. trex-web manual BUY/SELL은 이 endpoint를 재사용하지 않고 신규 manual endpoint를 사용한다. 단, 내부 ledger append + snapshot update 회계 helper는 가능한 한 공유한다.
|
||||
|
||||
# 2. 요구사항 판정 결과
|
||||
- 판정: 신규
|
||||
@@ -73,6 +74,7 @@
|
||||
- 변경 3 — **ledger history/read API 계약**: trex-web이 최근 장부 이력을 표시할 수 있는 response shape, pagination/limit, action filter 필요 여부를 정의한다.
|
||||
- 변경 4 — **권한/운영 안전 정책**: owner-scoped authorization, disabled portfolio, daemon-managed portfolio warning/confirmation metadata, negative input policy, reversal policy를 정의한다.
|
||||
- 변경 5 — **기존 domain/CLI와 v1 API 정합화**: 현행 `apply_invest`, `apply_transfer`, `apply_buy`, `apply_sell` 흐름을 재사용/분리할지 결정하고, broker/service-token endpoint와 충돌하지 않도록 source를 분리한다.
|
||||
- 변경 6 — **기존 broker trade endpoint 보존**: `POST /v1/portfolios/{portfolio_id}/ledger/trades`는 기존 trex-core/daemon 체결 보고 계약으로 유지하고, manual endpoint와 auth/source/idempotency 의미를 분리한다.
|
||||
|
||||
## 영향 범위
|
||||
- 코드 영향:
|
||||
@@ -94,6 +96,8 @@
|
||||
# 5. 요구사항 목록
|
||||
## 기능 요구사항
|
||||
- FR-1: user/session token 사용자는 자기 소유 portfolio에 manual ledger entry를 append할 수 있어야 한다. 타 사용자 portfolio는 HTTP 403 또는 동등한 fail-closed 응답이어야 한다.
|
||||
- FR-1a: 기존 `POST /v1/portfolios/{portfolio_id}/ledger/trades`는 daemon/service-token broker trade write 전용으로 유지한다. manual user write를 이 endpoint에 추가 허용하지 않는다.
|
||||
- FR-1b: 신규 manual endpoint를 추가한다. 기본 방향은 `POST /v1/portfolios/{portfolio_id}/ledger/manual` 단일 action-dispatch endpoint이며, request body에 `action` enum을 포함한다.
|
||||
- FR-2: `INVEST` action은 외부자금에서 `profit_buffer`로 유입된 것으로 기록한다. 효과: `profit_buffer += amount`, `cash_balance`/`asset_quantity` 변화 없음.
|
||||
- FR-3: `BUFFER_OUT` action은 `profit_buffer -> cash_balance` 이동을 기록한다. 효과: `profit_buffer -= amount`, `cash_balance += amount`.
|
||||
- FR-4: `BUFFER_IN` action은 `cash_balance -> profit_buffer` 이동을 기록한다. 효과: `cash_balance -= amount`, `profit_buffer += amount`.
|
||||
@@ -112,6 +116,7 @@
|
||||
- NFR-2: 같은 portfolio에 대한 동시 manual ledger write는 lost update가 없어야 한다(row lock 또는 동등한 concurrency control).
|
||||
- NFR-3: action/effect 계산은 기존 portfolio-hub domain/CLI 흐름과 일관되어야 한다.
|
||||
- NFR-4: manual user-token write와 daemon/service-token broker write는 source/permission/path 의미가 분리되어야 한다.
|
||||
- NFR-4a: HTTP endpoint는 분리하되, ledger append + snapshot update의 action/effect 계산은 shared domain helper 또는 동일 test vectors로 중복/divergence를 방지해야 한다.
|
||||
- NFR-5: 모든 write request는 audit 가능한 note/source/requester 정보를 남길 수 있어야 한다.
|
||||
- NFR-6: 기존 `GET /v1/portfolios`, daemon ledger trade write, CLI portfolio flows에 회귀가 없어야 한다.
|
||||
|
||||
@@ -131,6 +136,7 @@
|
||||
- 복잡한 세금/회계 모델
|
||||
- `QUANTITY_ADJUSTMENT` 1차 구현
|
||||
- 기존 daemon/service-token broker ledger endpoint의 의미 변경
|
||||
- 기존 `POST /v1/portfolios/{portfolio_id}/ledger/trades`에 user/session-token manual write 권한을 추가하는 것
|
||||
|
||||
# 6. 리스크/가정 목록
|
||||
## 리스크
|
||||
@@ -156,10 +162,10 @@
|
||||
|
||||
## 오픈 질문
|
||||
- OQ-1: 신규 manual write endpoint shape은 action-dispatch 단일 endpoint인가, action별 endpoint인가?
|
||||
- 후보 A: `POST /v1/portfolios/{portfolio_id}/ledger/manual` with `action` enum
|
||||
- 후보 B: `POST /v1/portfolios/{portfolio_id}/ledger/invest|transfer|buy|sell|withdraw|reversal`
|
||||
- 상태: Open
|
||||
- 종료 조건: REQ draft 전 API path/shape 확정
|
||||
- 상태: Answered
|
||||
- 결정: 기존 `POST /v1/portfolios/{portfolio_id}/ledger/trades`는 유지하고, 신규 manual endpoint를 추가한다. 기본 shape은 `POST /v1/portfolios/{portfolio_id}/ledger/manual` + `action` enum 단일 action-dispatch endpoint로 한다.
|
||||
- 근거: `/ledger/trades`는 trex-core/daemon/service-token broker 체결 보고이며, manual write는 user/session-token owner-scoped operation이다. auth/source/idempotency/audit 의미가 달라 HTTP endpoint는 분리한다. 단, 내부 회계 helper는 공유한다.
|
||||
- 종료 조건: 완료
|
||||
- OQ-2: `REVERSAL`은 target ledger entry id를 필수로 둘 것인가?
|
||||
- 상태: Open
|
||||
- 종료 조건: audit/reference policy 확정
|
||||
@@ -196,7 +202,7 @@
|
||||
- baseline doc diff: interface-contract/runtime-flows/data-model updates
|
||||
|
||||
# 8. REQ로 넘기기 전 확인 체크
|
||||
- [ ] API endpoint shape 확정(OQ-1)
|
||||
- [x] API endpoint shape 확정(OQ-1) — 기존 `/ledger/trades` 유지 + 신규 `POST /v1/portfolios/{portfolio_id}/ledger/manual` 추가
|
||||
- [ ] REVERSAL target/reference policy 확정(OQ-2)
|
||||
- [ ] 부족 잔고/수량 validation policy 확정(OQ-3)
|
||||
- [ ] daemon-managed confirmation contract 확정(OQ-4)
|
||||
@@ -219,7 +225,7 @@
|
||||
|
||||
# 10. 사용자 결정 필요 항목 요약
|
||||
## DECIDE
|
||||
- API shape: 단일 action-dispatch endpoint vs action별 endpoint
|
||||
- ~~API shape: 단일 action-dispatch endpoint vs action별 endpoint~~ → 기존 `/ledger/trades` 유지, 신규 `POST /v1/portfolios/{portfolio_id}/ledger/manual` + `action` enum 추가
|
||||
- REVERSAL target ledger id/reference 필수 여부
|
||||
- 부족 cash/quantity 시 validation 거부 vs 결과 음수 허용
|
||||
- daemon-managed portfolio warning/confirmation을 API-level로 강제할지 UI-level로 둘지
|
||||
@@ -237,7 +243,7 @@
|
||||
|
||||
# 11. Discovery Freeze
|
||||
- Handoff Decision: 보류(draft)
|
||||
- Handoff Rationale: trex-web dcy-011의 backend-first 후속 Discovery로 생성했다. 현행 portfolio-hub 구조와 action/effect는 확인했으나 API shape, reversal reference, validation, daemon-managed confirmation contract 결정이 필요하다.
|
||||
- Handoff Rationale: trex-web dcy-011의 backend-first 후속 Discovery로 생성했다. 현행 portfolio-hub 구조와 action/effect는 확인했고, 기존 `/ledger/trades` 유지 + 신규 `/ledger/manual` 추가 방향은 확정했다. 남은 결정은 reversal reference, validation, daemon-managed confirmation contract, history fields, legacy PROFIT mapping이다.
|
||||
- Ready for REQ Drafting: false
|
||||
- Confirmed By: 미정
|
||||
- Confirmed At (KST): 미정
|
||||
|
||||
Reference in New Issue
Block a user