docs: batch 상태 released 동기화(REL-001/002) + README 현행화(거래내역/실현PnL API)

batch drift 정합 — REL-001(BAT-001~016)·REL-002(BAT-017) released에 맞춰
batches/index 및 개별 index 상태를 release-candidate→released 동기화(17건).
README: bootstrap 문구 제거, dcy-007 엔드포인트(GET /trades·/pnl/realized) 추가,
planned-next 현행화. 코드 무변경.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VHtM5Ws1HKCKQ4JGi6GRb5
This commit is contained in:
2026-06-22 09:51:13 +09:00
co-authored by Claude Opus 4.8
parent 16746008cc
commit b1c34068e5
19 changed files with 87 additions and 39 deletions
+53 -5
View File
@@ -4,13 +4,13 @@ Portfolio Hub is a FastAPI service that extracts portfolio management from `jsbo
## Current status
This repository is in bootstrap phase.
- FastAPI application entrypoint is available.
- Token-based authentication and role checks are implemented.
- Portfolio and user management API contracts are implemented.
- Core portfolio domain services are ported from `jsbot-kis`.
- Postgres-backed portfolio and user persistence is implemented and gated behind `pfhub_DB_ENABLED=true`.
- Alembic-managed schema migrations are applied in production (head: `20260605_0025`).
- Trade history and realized PnL query API is implemented (`GET /v1/portfolios/{id}/trades`, `GET /v1/portfolios/{id}/pnl/realized`).
## Configuration
@@ -425,6 +425,52 @@ The default `.env.example` includes example tokens for development.
When `pfhub_DB_ENABLED=true` and both `pfhub_BOOTSTRAP_USERNAME` and `pfhub_BOOTSTRAP_PASSWORD` are set, the app creates that admin user automatically on startup only if the `users` table is empty. This is intended for first-run bootstrap, not recurring synchronization.
## Portfolio API
Portfolio management and ledger access are exposed through `/v1/portfolios`.
- `POST /v1/portfolios`: create a portfolio (requires `trade-write` or session token)
- `GET /v1/portfolios`: list portfolios for the authenticated user
- `PATCH /v1/portfolios/{id}`: update portfolio metadata
- `DELETE /v1/portfolios/{id}`: delete a portfolio (requires `admin`)
- `POST /v1/portfolios/{id}/ledger/trades`: record a trade entry with accounting (`cash_balance_after`, `asset_quantity_after`)
- `GET /v1/portfolios/{id}/tags`: list tags on a portfolio
- `POST /v1/portfolios/{id}/tags`: apply a tag to a portfolio
- `DELETE /v1/portfolios/{id}/tags/{tag_id}`: remove a tag from a portfolio
- `POST /v1/portfolios/{id}/comments`: add a comment
- `GET /v1/portfolios/{id}/comments`: list comments
- `PATCH /v1/portfolios/{id}/comments/{comment_id}`: update a comment
- `DELETE /v1/portfolios/{id}/comments/{comment_id}`: delete a comment
- `GET /v1/portfolios/{id}/trades`: query trade history with date filter (requires `read` or higher)
- `GET /v1/portfolios/{id}/pnl/realized`: compute WAC-based realized PnL over a date range (requires `read` or higher)
### Trade history query (`GET /v1/portfolios/{id}/trades`)
Supports single-date and range queries via query parameters. At least one date parameter is required.
```bash
# Single date
curl -X GET "http://localhost:8000/v1/portfolios/<id>/trades?date=2026-06-19" \
-H "Authorization: Bearer <READ_TOKEN>"
# Date range
curl -X GET "http://localhost:8000/v1/portfolios/<id>/trades?from=2026-06-01&to=2026-06-19" \
-H "Authorization: Bearer <READ_TOKEN>"
```
Response fields per trade item: `trade_id`, `side`, `quantity`, `price`, `executed_at`, `fee_amount`, `tax_amount`.
### Realized PnL query (`GET /v1/portfolios/{id}/pnl/realized`)
Computes weighted-average cost (WAC) based realized PnL over the specified date range. `from` and `to` are required. `symbol` is an optional filter.
```bash
curl -X GET "http://localhost:8000/v1/portfolios/<id>/pnl/realized?from=2026-06-01&to=2026-06-19" \
-H "Authorization: Bearer <READ_TOKEN>"
```
Response fields: `total_realized_pnl`, `cost_basis_from`, `items` (per-sell realized PnL), `data_completeness_warning` (set when buy history before `from` is incomplete).
## Production Operator Runbook
이 섹션은 실배포 환경에서 admin 접근, release smoke credential 관리, provenance 확인, 로그 증적 수집을 반복 가능한 절차로 정리한다.
@@ -514,6 +560,8 @@ curl -X POST "<BASE_URL>/auth/service-tokens" \
## Planned next steps
1. Apply and verify Alembic migrations against a real PostgreSQL/Timescale instance.
2. Add integration tests for DB-backed portfolio and user flows.
3. Design token-to-user mapping if ownership or user-scoped authorization is needed later.
1. Add integration tests for DB-backed portfolio and user flows.
2. Add unrealized PnL (current price integration) — deferred from dcy-007.
3. Add pagination for trade history and PnL endpoints.
4. Remove legacy `POST /portfolios/{id}/buy` and `POST /portfolios/{id}/sell` endpoints (currently deprecated-only).
5. Fix `pfhub tag apply asset` / `pfhub tag remove asset` CLI mismatch (targets portfolios table instead of assets).