docs(batch): start manual ledger API delivery
This commit is contained in:
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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이며 순입금액 계산에는 포함하지 않는다.
|
||||
@@ -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 가능.
|
||||
@@ -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.
|
||||
@@ -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/) |
|
||||
|
||||
Reference in New Issue
Block a user