diff --git a/docs/batches/bat-024_20260714_manual-ledger-api/design.md b/docs/batches/bat-024_20260714_manual-ledger-api/design.md new file mode 100644 index 0000000..2fd7ba7 --- /dev/null +++ b/docs/batches/bat-024_20260714_manual-ledger-api/design.md @@ -0,0 +1,69 @@ +# BAT-024 Design + +## 결정해야 할 구현 설계점 + +### D-1: reversal target / confirmation metadata 저장 위치 + +REQ-056은 `target_ledger_entry_id` 필수와 confirmation evidence 저장을 요구한다. 구현 전 아래 중 하나를 선택한다. + +- Option A: 기존 metadata/note/context 필드가 있다면 구조화된 JSON metadata로 저장 +- Option B: `portfolio_ledger`에 컬럼 추가(`target_ledger_entry_id`, `source`, `confirmation_metadata`) — migration 필요 +- Option C: note에만 저장 — 감사성이 약하므로 비권장 + +권장: 기존 구조화 metadata가 없고 중복 reversal을 DB 수준에서 검증해야 한다면 Option B를 설계하고 migration을 batch에 포함하되, 운영 DB 적용은 release gate에서 별도 승인한다. + +### D-2: manual endpoint shape + +```http +POST /v1/portfolios/{portfolio_id}/ledger/manual +``` + +단일 action-dispatch body: + +```json +{ + "action": "BUY", + "amount": null, + "quantity": 10, + "price": 80000, + "fee": 100, + "tax": 0, + "target_ledger_entry_id": null, + "note": "manual buy", + "confirm_daemon_managed_manual_write": false, + "confirmation_evidence": null +} +``` + +### D-3: response shape + +```json +{ + "ledger_entry_id": "...", + "portfolio_id": "...", + "action": "BUY", + "source": "manual", + "cash_balance_after": 199900, + "asset_quantity_after": 10, + "profit_buffer_after": 0, + "total_value_after": 999900, + "recorded_at": "..." +} +``` + +### D-4: error codes + +- 403: non-owner or service-token manual endpoint access +- 409 `PORTFOLIO_DISABLED` +- 409 `MANUAL_WRITE_REQUIRES_CONFIRMATION` +- 409 `INSUFFICIENT_CASH` +- 409 `INSUFFICIENT_QUANTITY` +- 409 `INSUFFICIENT_BUFFER` +- 409 `LEDGER_ENTRY_ALREADY_REVERSED` +- 422: invalid action/field/value + +### D-5: verification strategy + +- API TestClient tests for AC-1~17. +- repository/concurrency test for row lock/lost update when feasible. +- regression tests for existing `/ledger/trades`, list/read, CLI/domain flows. diff --git a/docs/batches/bat-024_20260714_manual-ledger-api/implementation.md b/docs/batches/bat-024_20260714_manual-ledger-api/implementation.md new file mode 100644 index 0000000..6b2c909 --- /dev/null +++ b/docs/batches/bat-024_20260714_manual-ledger-api/implementation.md @@ -0,0 +1,6 @@ +# BAT-024 Implementation + +- Status: not-started +- Owner: portfolio-hub-dev / delivery-runner + +Implementation evidence will be filled by the delivery owner. diff --git a/docs/batches/bat-024_20260714_manual-ledger-api/index.md b/docs/batches/bat-024_20260714_manual-ledger-api/index.md new file mode 100644 index 0000000..b652b77 --- /dev/null +++ b/docs/batches/bat-024_20260714_manual-ledger-api/index.md @@ -0,0 +1,47 @@ +# BAT-024 — owner-scoped 수동 장부 입력 HTTP API + +- Batch ID: BAT-024 +- Profile: standard +- Status: in-progress +- Discovery: dcy-012_20260714_manual-ledger-write-api-owner-scoped +- Included REQ: REQ-056 +- Folder: docs/batches/bat-024_20260714_manual-ledger-api/ +- Created: 2026-07-14 + +## Summary + +REQ-056 구현: trex-web이 user/session token으로 자기 소유 portfolio에 수동 장부 entry를 append/read할 수 있는 portfolio-hub v1 API를 추가한다. + +기존 `POST /v1/portfolios/{portfolio_id}/ledger/trades`는 trex-core/daemon/service-token broker 체결 보고 전용으로 유지한다. 신규 manual API는 owner-scoped user/session token 전용으로 분리한다. + +## Included REQ + +| REQ | 제목 | Type | 의존 | +| --- | --- | --- | --- | +| REQ-056 | owner-scoped 수동 장부 입력 HTTP API | Interface | dcy-012 confirmed, existing portfolio_ledger/snapshot model | + +## DoR + +- [x] dcy-012 confirmed by Justin Ko +- [x] REQ-056 Approved +- [x] 기존 `/ledger/trades` 보존 정책 확정 +- [x] action/effect, PROFIT/WITHDRAW 수익률 의미, confirmation, validation 정책 확정 + +## DoD + +- [ ] REQ-056 AC-1~19 테스트 전수 통과 +- [ ] 기존 `/ledger/trades`, `GET /v1/portfolios`, CLI/domain flow 회귀 없음 +- [ ] baseline docs(`interface-contract`, `runtime-flows`, `data-model`) 갱신 +- [ ] draft-batch-verification 문서에 AC별 PASS/FAIL evidence 기록 +- [ ] independent QC PASS 후 lead `confirm-batch-verification` + +## 비가역 결재 게이트 + +- DB migration 가능성: reversal target reference/confirmation metadata 저장 방식에 따라 migration 필요 가능. migration이 필요하면 design에서 명시하고, 운영 DB 적용은 release gate로 분리한다. +- HTTP API 계약: 신규 additive endpoint. 기존 `/ledger/trades` semantics는 변경하지 않는다. +- Security: owner-scoped write API 및 service-token fail-closed가 핵심 gate다. + +## Notes + +- `QUANTITY_ADJUSTMENT`는 1차 제외. +- `PROFIT`은 신규 manual API 필수 action이며 순입금액 계산에는 포함하지 않는다. diff --git a/docs/batches/bat-024_20260714_manual-ledger-api/planning.md b/docs/batches/bat-024_20260714_manual-ledger-api/planning.md new file mode 100644 index 0000000..b628ce6 --- /dev/null +++ b/docs/batches/bat-024_20260714_manual-ledger-api/planning.md @@ -0,0 +1,67 @@ +# BAT-024 Planning + +## 구현 의존 순서 + +1. **현재 구조 재확인** + - `CLAUDE.md`, `README.md`, `pyproject.toml` + - `app/api/v1_portfolios.py`, `app/schemas/v1.py` + - `app/domain/services.py`, `app/repositories/postgres.py`, `app/repositories/portfolio_repository.py` + - auth dependency와 기존 `/ledger/trades` tests +2. **스키마/API 계약** + - `ManualLedgerRequest`, `ManualLedgerResponse`, history/summary response field 정의 + - action enum: `INVEST`, `BUFFER_OUT`, `BUFFER_IN`, `BUY`, `SELL`, `WITHDRAW`, `PROFIT`, `REVERSAL` +3. **domain/repository 회계 helper** + - 기존 invest/transfer/buy/sell flow 재사용 또는 공통 helper 추출 + - 부족 cash/quantity/buffer validation + - PROFIT vs WITHDRAW classification + - REVERSAL target lookup/opposite effect/dedup +4. **auth/route 구현** + - `POST /v1/portfolios/{portfolio_id}/ledger/manual` + - owner-scoped user/session token only + - service-token/daemon-token fail-closed + - disabled portfolio 409 + - daemon-managed confirmation 409/allowed flow +5. **history/summary read 구현** + - history response에 `total_value_after` + - `cumulative_profit_withdrawn` 별도 지표 +6. **baseline docs 업데이트** + - `docs/interface-contract.md` + - `docs/runtime-flows.md` + - `docs/data-model.md` +7. **tests** + - API AC-1~17 + - repository/concurrency AC-18 + - regression AC-19 + +## Task Breakdown + +### T-1: Contract/schema +- manual request/response schema와 error body shape 작성. +- extra numeric fields는 schema 또는 validation에서 422로 실패. + +### T-2: Accounting helper/repository +- ledger append + portfolio snapshot update를 단일 transaction/row lock으로 보장. +- accepted action만 허용하고 `QUANTITY_ADJUSTMENT`는 422. +- `target_ledger_entry_id` 저장 위치는 design에서 확정. migration 필요 시 별도 명시. + +### T-3: Route/auth +- owner token만 허용. +- service-token/daemon-token은 manual endpoint 403. +- non-owner 403, disabled 409. +- daemon-managed confirmation 없으면 409 `MANUAL_WRITE_REQUIRES_CONFIRMATION`. + +### T-4: History/summary +- history items에 after-snapshot 4종 포함. +- summary/return response에 `cumulative_profit_withdrawn` 포함. + +### T-5: Docs/tests/verification +- baseline docs 갱신. +- `uv run pytest` 또는 repo 표준 test command로 targeted + regression 수행. +- `verification.md`에 AC별 evidence 기록. + +## Risks / Constraints + +- Auth regression: existing daemon `/ledger/trades`와 user manual endpoint 권한을 혼동하면 보안 결함. +- Accounting regression: PROFIT/WITHDRAW effect는 유사하지만 performance classification이 다름. +- Migration risk: reversal/confirmation metadata를 기존 구조로 담을 수 없으면 migration이 필요하다. +- Concurrency risk: row lock 없이 simultaneous manual writes는 lost update 가능. diff --git a/docs/batches/bat-024_20260714_manual-ledger-api/verification.md b/docs/batches/bat-024_20260714_manual-ledger-api/verification.md new file mode 100644 index 0000000..1bd6ac0 --- /dev/null +++ b/docs/batches/bat-024_20260714_manual-ledger-api/verification.md @@ -0,0 +1,18 @@ +# BAT-024 Verification + +- Status: draft +- Verification owner: portfolio-hub-dev first pass; independent qc-reviewer required before lead confirmation. + +## Test Evidence + +_To be filled by delivery owner._ + +## AC Matrix + +| AC | Status | Evidence | +| --- | --- | --- | +| REQ-056 AC-1~19 | Pending | Not yet implemented | + +## Result + +- Pending implementation. diff --git a/docs/batches/index.md b/docs/batches/index.md index 80a22ab..9b8a757 100644 --- a/docs/batches/index.md +++ b/docs/batches/index.md @@ -31,3 +31,4 @@ | BAT-021 | standard | release-candidate | REQ-047 | dcy-010 | [bat-021](./bat-021_20260628_req047-step2-integration-and-runbook/) | | BAT-022 | standard | release-candidate | REQ-052, REQ-053, REQ-054 | dcy-011 | [bat-022](./bat-022_20260628_daemon-crud-self-service-credential-api/) | | BAT-023 | batch-lite | in-progress | REQ-055 | trex-tvr-v1 dcy-001 | [bat-023](./bat-023_20260704_portfolios-strategy-market-meta/) | +| BAT-024 | standard | in-progress | REQ-056 | dcy-012 | [bat-024](./bat-024_20260714_manual-ledger-api/) |