docs(batch): start manual ledger API delivery

This commit is contained in:
2026-07-14 18:52:34 +09:00
parent 0c00f851e7
commit 762cf11376
6 changed files with 208 additions and 0 deletions
@@ -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.
+1
View File
@@ -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/) |