# 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.