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:
@@ -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).
|
||||
|
||||
Reference in New Issue
Block a user