feat: implement portfolio UUID migration and v1 API finalization (BAT-006, BAT-001 re-verified)
Core Changes: - Migrate portfolio_id from string to UUID in schema and repository layer - Update portfolio CLI commands to use name+user combination for identification - Update HTTP API to accept portfolio_id as UUID path parameter - Implement portfolio ownership validation in repository queries Requirements Completed (REQ-016 to REQ-019): - REQ-016: portfolios table UUID schema migration with data migration script - REQ-017: CLI portfolio commands with name+user identification - REQ-018: HTTP API portfolio path parameters and v1 asset_id UUID returns - REQ-019: Portfolio UUID baseline documentation updates BAT-001 Re-verification: - REQ-004~010 marked as Implemented after verification evidence validation - All v1 API endpoints verified with comprehensive test coverage Documentation Updates: - Update data-model.md with portfolio UUID structure - Update interface-contract.md with UUID path parameters - Update runtime-flows.md with ownership-based resolution flows - Update project-structure.md with database layer changes - Add migration script for portfolio UUID transition Testing: - Add test_portfolio_uuid.py for migration validation - Update test_cli.py and test_portfolio_ownership.py for ownership checks
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
# BAT-008 Design
|
||||
|
||||
- Status: confirmed
|
||||
- Batch: BAT-008
|
||||
- Profile: batch-lite
|
||||
|
||||
## Architecture Summary
|
||||
|
||||
BAT-008은 신규 코드/스키마/런타임 변경이 없는 doc-only batch다. REQ-004~010 구현(BAT-001)과 BAT-006(UUID migration) 완료 후 미반영 상태인 baseline 문서 3개를 실제 구현 결과와 동기화한다.
|
||||
|
||||
- **Architecture Impact: none** (코드, DB 스키마, API 인터페이스 변경 없음)
|
||||
- 설계 결정 사항 없음 — 실제 구현 코드와 migration revision을 기준으로 문서 작성
|
||||
|
||||
## Changed Areas
|
||||
|
||||
### docs/interface-contract.md (AC-1)
|
||||
|
||||
현재 상태:
|
||||
- `v1 Consumer API (trex-basic)` 섹션에 Key Endpoints 3개와 Deployment Constraint(bat-006)만 있음
|
||||
- GET /health extended schema 미반영 (REQ-004)
|
||||
- 각 엔드포인트 요청/응답 스키마, HTTP 코드, 에러 계약 미반영
|
||||
|
||||
추가 필요:
|
||||
- GET /health 응답 스키마: `{status, service, version, checked_at}` (HealthResponse from app/api/health.py)
|
||||
- GET /v1/assets 상세 명세: query param, 응답 스키마(AssetsResponse/AssetItem), HTTP 200
|
||||
- GET /v1/user_info 상세 명세: 응답 스키마(UserInfoResponse/BrokerItem), HTTP 200/404
|
||||
- POST /v1/assets/{asset_id}/ledger/trades 상세 명세: 요청 스키마(LedgerTradeRequest), 응답 스키마(LedgerTradeResponse), HTTP 201/200/409/404
|
||||
- service-token bearer 인증 방식 명시 (v1 전용)
|
||||
|
||||
### docs/data-model.md (AC-2)
|
||||
|
||||
현재 상태:
|
||||
- Entity: Portfolio — `market` 컬럼 누락
|
||||
- Entity: User — `auth_tokens` 관련 AuthToken entity 없음
|
||||
- broker_credentials 테이블 미문서화
|
||||
- ledger_trades 테이블 미문서화
|
||||
|
||||
추가 필요:
|
||||
- Portfolio Key Fields에 `market :: text|null` 추가
|
||||
- Entity: `AuthToken` 추가 — `id`, `user_id`, `token_type`, `runtime_id`, `permission`, `expires_at` 등 핵심 필드
|
||||
- Entity: `BrokerCredential` 추가 — 스키마 기준: `(user_id, broker)` PK, `account_ref`, `encrypted_payload`, `credential_version`, `last_rotated_at`
|
||||
- Entity: `LedgerTrade` 추가 — 스키마 기준: `ledger_entry_id` BigInt Identity PK, `asset_id`, `order_id`, `execution_id`, `side`, `quantity`, `price`, `fee_amount`, `tax_amount`, `executed_at`, `recorded_at`; `uq_ledger_trades_idempotency` unique constraint
|
||||
|
||||
### docs/runtime-flows.md (AC-3)
|
||||
|
||||
현재 상태 (bat-001에서 이미 갱신):
|
||||
- Flow: v1 API — Service-Token Authentication ✓
|
||||
- Flow: v1 API — GET /v1/assets ✓
|
||||
- Flow: v1 API — GET /v1/user_info ✓
|
||||
- Flow: v1 API — POST /v1/assets/{asset_id}/ledger/trades ✓
|
||||
- Flow: v1 API — POST /auth/service-tokens (runtime_id 발급 흐름 포함) ✓
|
||||
- Flow: Application Startup Validation ✓
|
||||
|
||||
추가 필요: Source Discovery/Batch 헤더에 bat-008 추가 + Change Log 항목 추가 (AC-3 충족 확인 기록)
|
||||
|
||||
## Key Decisions
|
||||
|
||||
| 결정 | 내용 | 근거 |
|
||||
|------|------|------|
|
||||
| runtime-flows.md 내용 보완 불필요 | bat-001에서 v1 API 처리 흐름과 runtime_id 발급 흐름이 이미 추가됨 | 현행 파일 확인 |
|
||||
| interface-contract.md 갱신 방식 | `v1 Consumer API (trex-basic)` 섹션 내에 endpoint별 상세 명세 subsection 추가 | 기존 섹션 구조 유지 |
|
||||
| data-model.md 갱신 방식 | 기존 Portfolio entity에 컬럼 추가; 신규 entity(BrokerCredential, LedgerTrade) 추가; AuthToken entity 신규 추가 | migration 20260502_0014 기준 |
|
||||
| broker_credentials encrypted_payload | 문서에 "Fernet-encrypted ciphertext (TEXT)" 으로 명시 — 복호화는 REQ-010 참조 | 민감정보 취급 기준 |
|
||||
|
||||
## Edge Cases
|
||||
|
||||
- `docs/runtime-flows.md`의 bat-001 추가 내용과 bat-007 추가 내용이 공존 — 섹션 충돌 없음. bat-008은 Change Log와 Source Discovery만 갱신.
|
||||
- `auth_tokens` 테이블은 bootstrap baseline에 Users entity와 함께 암묵적으로 존재하나 명시적 entity 섹션이 없음 — bat-008에서 AuthToken entity 추가.
|
||||
- `ledger_trades.asset_id`는 BAT-006 이후 UUID portfolio_id를 참조하나 TEXT 타입 — 문서에 "TEXT (UUID-format after BAT-006)" 으로 명시.
|
||||
|
||||
## Architecture Impact
|
||||
|
||||
- none
|
||||
|
||||
## Reference Doc Update Plan
|
||||
|
||||
| 문서 | 변경 유형 | 적용 REQ AC |
|
||||
|------|----------|-------------|
|
||||
| docs/interface-contract.md | 기존 섹션 내 endpoint 상세 명세 추가 | REQ-011 AC-1 |
|
||||
| docs/data-model.md | Portfolio entity 컬럼 추가, 신규 entity 3개 추가 | REQ-011 AC-2 |
|
||||
| docs/runtime-flows.md | Source Discovery/Batch 헤더 + Change Log만 갱신 (내용은 bat-001 기준 이미 충족) | REQ-011 AC-3 |
|
||||
@@ -0,0 +1,68 @@
|
||||
# BAT-008 Implementation
|
||||
|
||||
- Status: completed
|
||||
- Batch: BAT-008
|
||||
- Profile: batch-lite
|
||||
|
||||
## Plan Summary
|
||||
|
||||
REQ-011 AC-1~3에 대응하는 3개 baseline 문서 갱신. 코드/스키마/런타임 변경 없음.
|
||||
|
||||
## Changed Files
|
||||
|
||||
| 파일 | 변경 유형 | 대응 AC |
|
||||
|------|----------|---------|
|
||||
| `docs/interface-contract.md` | 기존 섹션 내 endpoint 상세 명세 추가 | REQ-011 AC-1 |
|
||||
| `docs/data-model.md` | portfolios.market 컬럼 추가; AuthToken, BrokerCredential, LedgerTrade entity 추가 | REQ-011 AC-2 |
|
||||
| `docs/runtime-flows.md` | Source Discovery/Batch 헤더 + Change Log 갱신 (내용은 bat-001에서 이미 충족) | REQ-011 AC-3 |
|
||||
|
||||
## Execution Log
|
||||
|
||||
### docs/interface-contract.md
|
||||
|
||||
- Source Discovery/Batch 헤더: `bootstrap-baseline, bat-006` → `bootstrap-baseline, bat-001, bat-006, bat-008`
|
||||
- GET /health 응답 스키마 갱신: `{"status": "ok"}` 단순 설명 → `{status, service, version, checked_at}` 명시 (HealthResponse 기준)
|
||||
- `v1 Consumer API (trex-basic)` 섹션 확장:
|
||||
- `### Authentication` 추가: service-token bearer, DB-issued 조건, trade-write 권한 명시
|
||||
- `### Endpoint: GET /v1/assets` 추가: query param, AssetsResponse/AssetItem 스키마, HTTP 200/401/403
|
||||
- `### Endpoint: GET /v1/user_info` 추가: UserInfoResponse/BrokerItem 스키마, HTTP 200/401/403/404
|
||||
- `### Endpoint: POST /v1/assets/{asset_id}/ledger/trades` 추가: LedgerTradeRequest/LedgerTradeResponse 스키마, HTTP 201/200/409/404/401/403
|
||||
- `### Idempotency Contract` 추가: deduplication key, duplicate/conflict 처리 방식
|
||||
- Change Log 항목 추가
|
||||
|
||||
### docs/data-model.md
|
||||
|
||||
- Source Discovery/Batch 헤더: `bootstrap-baseline, bat-006` → `bootstrap-baseline, bat-001, bat-006, bat-008`
|
||||
- Model Summary: AuthToken, BrokerCredential, LedgerTrade 추가
|
||||
- Entity: Portfolio — `market :: text|null` 필드 추가 (migration 20260502_0014 기준)
|
||||
- Entity: `AuthToken` 신규 추가:
|
||||
- Key Fields: id, user_id, token_type, token_source, permission, service_name, runtime_id, expires_at, created_at
|
||||
- Uniqueness Constraints: idx_auth_tokens_service_name_unique, idx_auth_tokens_runtime_id_unique
|
||||
- State Rules: runtime_id 없는 토큰 v1 거부 명시
|
||||
- Entity: `BrokerCredential` 신규 추가:
|
||||
- Key Fields: user_id, broker, account_ref, encrypted_payload, credential_version, last_rotated_at
|
||||
- PK: (user_id, broker)
|
||||
- State Rules: 평문 저장 금지, 복호화 실패 처리 명시
|
||||
- Entity: `LedgerTrade` 신규 추가:
|
||||
- Key Fields: ledger_entry_id, asset_id, order_id, execution_id, side, quantity, price, fee_amount, tax_amount, executed_at, recorded_at
|
||||
- Unique Constraint: uq_ledger_trades_idempotency
|
||||
- Index: idx_ledger_trades_asset_executed
|
||||
- State Rules: immutable rows, payload conflict → 409
|
||||
- Change Log 항목 추가
|
||||
|
||||
### docs/runtime-flows.md
|
||||
|
||||
- Source Discovery/Batch 헤더: `bat-007` 뒤에 `bat-008` 추가
|
||||
- Change Log 항목 추가: "REQ-011 AC-3 confirmed: v1 API flows and runtime_id issuance flow already present from bat-001"
|
||||
- 내용 변경 없음 — bat-001에서 추가된 v1 API 처리 흐름 5개, Application Startup Validation, bat-007에서 추가된 Local DB 흐름 2개 모두 현행 유지
|
||||
|
||||
## Validation
|
||||
|
||||
- `docs/interface-contract.md`: REQ-011 AC-1 대상 4개 엔드포인트 명세 + 인증 방식 포함 확인 ✓
|
||||
- `docs/data-model.md`: broker_credentials, ledger_trades, portfolios.market, auth_tokens.runtime_id 모두 반영 확인 ✓
|
||||
- `docs/runtime-flows.md`: v1 API 처리 흐름(4개) + runtime_id 발급 흐름(POST /auth/service-tokens) 존재 확인 ✓
|
||||
- 코드 변경 없음 — lint/typecheck 불필요
|
||||
|
||||
## Remaining Risks
|
||||
|
||||
- `docs/runtime-flows.md` v1 API flows는 bat-001에서 최초 작성됨. 이후 구현 변경 시 해당 흐름도 갱신 필요 (현재 기준 코드와 일치 확인됨).
|
||||
@@ -0,0 +1,41 @@
|
||||
# BAT-008 Index
|
||||
|
||||
- Status: release-candidate
|
||||
- Batch: BAT-008
|
||||
- Profile: batch-lite
|
||||
- Created: 2026-05-11
|
||||
|
||||
## Included REQ
|
||||
|
||||
| REQ | 제목 | Type | Priority |
|
||||
|-----|------|------|----------|
|
||||
| REQ-011 | trex-basic 계약 반영을 위한 baseline 문서 갱신 | Documentation | Medium |
|
||||
|
||||
## Source Discovery
|
||||
|
||||
- [dcy-002](../../discovery/) (trex-basic v1 API contract — FR/NFR 구현 완료 후 documentation closure)
|
||||
|
||||
## Scope Summary
|
||||
|
||||
- docs/interface-contract.md: GET /health, GET /v1/assets, GET /v1/user_info, POST /v1/assets/{asset_id}/ledger/trades 엔드포인트 명세 및 service-token bearer 인증 방식 추가 (REQ-011 AC-1)
|
||||
- docs/data-model.md: broker_credentials, ledger_trades 테이블, portfolios.market, auth_tokens.runtime_id 컬럼 추가 (REQ-011 AC-2)
|
||||
- docs/runtime-flows.md: v1 API 처리 흐름, runtime_id 발급 흐름 추가 (REQ-011 AC-3)
|
||||
- 신규 코드/모듈/스키마 변경 없음 — 구현 완료(REQ-004~010 Implemented) 후 문서 동기화
|
||||
|
||||
## Impacted Area
|
||||
|
||||
- Docs:
|
||||
- `docs/interface-contract.md` — v1 API 엔드포인트 명세, service-token 인증 방식 추가
|
||||
- `docs/data-model.md` — broker_credentials, ledger_trades 테이블 및 컬럼 추가
|
||||
- `docs/runtime-flows.md` — v1 API 처리 흐름 및 runtime_id 발급 흐름 추가
|
||||
- Modules: 없음
|
||||
- Tests: 없음
|
||||
|
||||
## Stage Documents
|
||||
|
||||
| Stage | File | Status |
|
||||
|-------|------|--------|
|
||||
| Planning | [planning.md](./planning.md) | confirmed |
|
||||
| Design | [design.md](./design.md) | confirmed |
|
||||
| Implementation | [implementation.md](./implementation.md) | completed |
|
||||
| Verification | [verification.md](./verification.md) | passed |
|
||||
@@ -0,0 +1,70 @@
|
||||
# BAT-008 Planning
|
||||
|
||||
- Status: confirmed
|
||||
- Batch: BAT-008
|
||||
- Profile: batch-lite
|
||||
|
||||
## Included REQ
|
||||
|
||||
- REQ-011: trex-basic 계약 반영을 위한 baseline 문서 갱신
|
||||
|
||||
## Out of Scope
|
||||
|
||||
- REQ-004~010 구현 자체 변경 (이미 Implemented 상태)
|
||||
- 신규 API 엔드포인트 또는 스키마 추가
|
||||
- runtime-flows.md 중 BAT-007에서 이미 갱신한 Alembic/ensure_schema() 경계 흐름 재작성
|
||||
- docs/project-structure.md (BAT-007 범위)
|
||||
|
||||
## 구현 순서
|
||||
|
||||
### 1단계: 현황 파악
|
||||
|
||||
- `docs/interface-contract.md` 현재 상태 확인 — v1 API 엔드포인트 명세 누락 여부 점검
|
||||
- `docs/data-model.md` 현재 상태 확인 — broker_credentials, ledger_trades, portfolios.market, auth_tokens.runtime_id 누락 여부 점검
|
||||
- `docs/runtime-flows.md` 현재 상태 확인 — v1 API 처리 흐름 및 runtime_id 발급 흐름 누락 여부 점검
|
||||
|
||||
### 2단계: docs/interface-contract.md 갱신 (REQ-011 AC-1)
|
||||
|
||||
- GET /health 응답 스키마 (extended) 추가
|
||||
- GET /v1/assets 엔드포인트 명세 추가
|
||||
- GET /v1/user_info 엔드포인트 명세 추가
|
||||
- POST /v1/assets/{asset_id}/ledger/trades 엔드포인트 명세 추가
|
||||
- service-token bearer 인증 방식 섹션 추가 또는 갱신
|
||||
|
||||
### 3단계: docs/data-model.md 갱신 (REQ-011 AC-2)
|
||||
|
||||
- broker_credentials 테이블 스키마 추가 (user_id, broker, account_ref, encrypted_payload, credential_version, last_rotated_at)
|
||||
- ledger_trades 테이블 스키마 추가 (ledger_entry_id, asset_id, order_id, execution_id, side, quantity, price, fee_amount, tax_amount, executed_at, recorded_at; unique constraint 포함)
|
||||
- portfolios.market 컬럼 추가
|
||||
- auth_tokens.runtime_id 컬럼 추가
|
||||
|
||||
### 4단계: docs/runtime-flows.md 갱신 (REQ-011 AC-3)
|
||||
|
||||
- v1 API 요청 처리 흐름(인증 → 서비스 → DB) 추가 (GET /v1/assets, GET /v1/user_info, POST /v1/assets/{asset_id}/ledger/trades)
|
||||
- service-token 발급 시 runtime_id 동시 생성 흐름 추가 (REQ-005 반영)
|
||||
- BAT-007에서 추가된 기존 섹션과 충돌 없이 통합
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Internal:
|
||||
- REQ-004~010: 모두 Implemented 상태 확인됨 (BAT-001 release-candidate) — 선행 조건 충족
|
||||
- `app/api/v1_assets.py`, `app/api/v1_user_info.py`, `app/api/v1_ledger.py` — 실제 구현 기준으로 명세 작성
|
||||
- `app/domain/models.py` — broker_credentials, ledger_trades 모델 기준으로 data-model 작성
|
||||
- `migrations/versions/` — Alembic revision 기준으로 컬럼/테이블 정의 확인
|
||||
- External: 없음
|
||||
|
||||
## Design Gate
|
||||
|
||||
- Design Required Before Implementation: no
|
||||
- Reason: 신규 코드/인터페이스/DB 스키마/런타임 흐름 변경 없음. 구현 완료된 REQ-004~010 결과를 기존 3개 문서에 반영하는 doc-only 작업. 구조적 결정 사항 없음.
|
||||
|
||||
## Milestones
|
||||
|
||||
1. docs/interface-contract.md 갱신 완료 (v1 API 엔드포인트 4개 + 인증 방식)
|
||||
2. docs/data-model.md 갱신 완료 (테이블 2개 + 컬럼 2개)
|
||||
3. docs/runtime-flows.md 갱신 완료 (v1 API 처리 흐름 + runtime_id 발급 흐름)
|
||||
|
||||
## Risks
|
||||
|
||||
- `docs/runtime-flows.md`에 BAT-007에서 추가된 섹션과 중복 또는 충돌이 생길 수 있음 — 1단계 현황 파악에서 확인 후 통합 방식 결정
|
||||
- 실제 구현 코드와 문서 내용 불일치 시 코드 기준으로 작성
|
||||
@@ -0,0 +1,59 @@
|
||||
# BAT-008 Verification
|
||||
|
||||
- Status: passed
|
||||
- Batch: BAT-008
|
||||
- Profile: batch-lite
|
||||
- Architecture Impact: none (confirmed — doc-only, no code/schema/runtime changes)
|
||||
- Design Gate: no (planning.md confirmed — no structural decisions required)
|
||||
|
||||
## Acceptance Mapping
|
||||
|
||||
### REQ-011 AC-1: docs/interface-contract.md에 4개 엔드포인트 명세 포함
|
||||
|
||||
| Criterion | Evidence | Result |
|
||||
|-----------|----------|--------|
|
||||
| GET /health 응답 스키마 포함 | `docs/interface-contract.md` Interface: Primary HTTP API — Outputs 섹션에 `{status, service, version, checked_at}` 명시 (HealthResponse from app/api/health.py 기준) | PASS |
|
||||
| GET /v1/assets 요청/응답 명세 포함 | `docs/interface-contract.md` Endpoint: GET /v1/assets — query param, AssetsResponse/AssetItem 스키마, HTTP 200/401/403 명시 | PASS |
|
||||
| GET /v1/user_info 요청/응답 명세 포함 | `docs/interface-contract.md` Endpoint: GET /v1/user_info — UserInfoResponse/BrokerItem 스키마, HTTP 200/401/403/404 명시 | PASS |
|
||||
| POST /v1/assets/{asset_id}/ledger/trades 요청/응답 명세 포함 | `docs/interface-contract.md` Endpoint: POST /v1/assets/{asset_id}/ledger/trades — LedgerTradeRequest/LedgerTradeResponse 스키마, HTTP 201/200/409/404/401/403 명시 | PASS |
|
||||
| service-token bearer 인증 방식 포함 | `docs/interface-contract.md` Authentication 섹션 — DB-issued service token 조건, trade-write 권한 명시 | PASS |
|
||||
|
||||
**REQ-011 AC-1: PASS**
|
||||
|
||||
### REQ-011 AC-2: docs/data-model.md에 신규 테이블/컬럼 문서화
|
||||
|
||||
| Criterion | Evidence | Result |
|
||||
|-----------|----------|--------|
|
||||
| broker_credentials 테이블 문서화 | `docs/data-model.md` Entity: BrokerCredential — (user_id, broker) PK, account_ref, encrypted_payload, credential_version, last_rotated_at; migration 20260502_0014 기준 | PASS |
|
||||
| ledger_trades 테이블 문서화 | `docs/data-model.md` Entity: LedgerTrade — ledger_entry_id (BigInt Identity), asset_id, order_id, execution_id, side, quantity, price, fee_amount, tax_amount, executed_at, recorded_at; uq_ledger_trades_idempotency unique constraint 명시 | PASS |
|
||||
| portfolios.market 컬럼 문서화 | `docs/data-model.md` Entity: Portfolio Key Fields — `market :: text\|null` 추가 | PASS |
|
||||
| auth_tokens.runtime_id 컬럼 문서화 | `docs/data-model.md` Entity: AuthToken — `runtime_id :: text\|null` 및 idx_auth_tokens_runtime_id_unique 명시 | PASS |
|
||||
|
||||
**REQ-011 AC-2: PASS**
|
||||
|
||||
### REQ-011 AC-3: docs/runtime-flows.md에 v1 API 처리 흐름과 runtime_id 발급 흐름 포함
|
||||
|
||||
| Criterion | Evidence | Result |
|
||||
|-----------|----------|--------|
|
||||
| v1 API 처리 흐름 포함 | `docs/runtime-flows.md` — Flow: v1 API — Service-Token Authentication, GET /v1/assets, GET /v1/user_info, POST /v1/assets/{asset_id}/ledger/trades (bat-001에서 추가, 현행 코드와 일치) | PASS |
|
||||
| runtime_id 발급 흐름 포함 | `docs/runtime-flows.md` — Flow: v1 API — POST /auth/service-tokens: "Calls AuthService.issue_service_token() which creates a new DB token with runtime_id" (bat-001에서 추가) | PASS |
|
||||
|
||||
**REQ-011 AC-3: PASS**
|
||||
|
||||
## Architecture Impact Confirmation
|
||||
|
||||
- batch-lite, Design Gate = no
|
||||
- 코드/DB 스키마/런타임 흐름 변경 없음
|
||||
- architecture impact: none ✓
|
||||
|
||||
## Blocking Issues
|
||||
|
||||
- 없음
|
||||
|
||||
## Ready for Release
|
||||
|
||||
- true
|
||||
|
||||
## Notes
|
||||
|
||||
- docs/runtime-flows.md의 v1 API flows는 bat-001 (BAT-001 scope) 에서 이미 작성됨. REQ-011이 명시한 "v1 API 처리 흐름과 runtime_id 발급 흐름" 조건은 bat-001 결과로 충족되어 있었으며, bat-008은 이를 공식 확인하고 Source Discovery를 갱신함.
|
||||
Reference in New Issue
Block a user