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:
2026-05-11 09:27:57 +00:00
parent 9ed307555a
commit 829629fa8f
46 changed files with 3260 additions and 220 deletions
+29 -2
View File
@@ -4,8 +4,8 @@
- Baseline Seed: .stagepilot/bootstrap/baseline.yaml
- Status: confirmed
- Owner: repository-maintainers
- Last Updated (KST): 2026-05-01 00:00
- Source Discovery / Batch: bootstrap-baseline, bat-001
- Last Updated (KST): 2026-05-11 00:00
- Source Discovery / Batch: bootstrap-baseline, bat-001, bat-006, bat-007
## Project Summary
- PortfolioHub exposes portfolio management and trading ledger workflows through a FastAPI service and a companion CLI.
@@ -95,6 +95,7 @@
- Holds framework-light domain models shared by services, routes, and repositories.
- app/repositories/
- Provides the repository protocol, repository factory, and concrete Postgres persistence implementation.
- Key methods added in bat-006: `get_portfolio_by_name_and_user(owner_user_id, name) -> Portfolio | None` for (owner_user_id, name) → portfolio_id (UUID) resolution used by CLI commands.
- app/schemas/
- Defines request and response schemas for HTTP contracts.
- `v1.py`: Contract schemas for v1 API (AssetItem, UserInfoResponse, BrokerItem, LedgerTradeRequest/Response).
@@ -122,6 +123,30 @@
- docs/ holds SDLC source-of-truth artifacts, while temp/ remains scratch or legacy material outside the active document flow.
- .vendor/stage-pilot/ is a vendored upstream toolkit and should not be treated as the active host source of truth.
## Schema Ownership Boundary
`app/repositories/postgres.py`의 `ensure_schema()`와 `migrations/versions/` Alembic revision 양쪽이 일부 DB 객체를 다룬다.
### 소유 경계
| 소유 경로 | 관리 객체 | 비고 |
|-----------|-----------|------|
| ensure_schema() 전용 | `idx_auth_tokens_service_name_unique` (partial index) | Alembic revision에 없음 |
| Alembic 전용 | `portfolios.market`, `auth_tokens.runtime_id`, `idx_auth_tokens_runtime_id_unique`, `broker_credentials`, `ledger_trades` | ensure_schema()에 없음 — v1 API 전제 조건 |
| 양쪽 공유 (IF NOT EXISTS 보호) | users, auth_tokens, strategy_sets, portfolios, portfolio_ledger, portfolio_comments, portfolio_tags + 대부분의 인덱스 | ensure_schema() 우선 실행 후 Alembic 실행 시 충돌 없음 |
### 허용 실행 순서
1. `init-db` 선행 → App 시작 → 정상 운영 (권장)
2. App 시작 (ensure_schema() 선행) → `migrate-db` 후속 실행 (legacy stamp 경로)
3. 이미 Alembic 관리 DB → `migrate-db` 증분 upgrade
### 운영 제약
- ensure_schema()만 실행한 환경은 v1 API 스키마(`broker_credentials`, `ledger_trades`, `runtime_id`)가 없어 v1 엔드포인트가 동작하지 않는다. `migrate-db`로 보완 필요.
- `alembic_version` 테이블을 수동으로 삭제한 뒤 `migrate-db`를 재실행하면 legacy stamp 오판이 발생할 수 있다.
- legacy DB(bot_principals 등 구 revision 0006~0013 구조)와 신규 revision 간 호환성 검증은 이번 batch 범위 밖이다.
## Current Gaps / Planned Changes
- The non-DB repository path intentionally raises a feature-not-ready error when persistence is disabled.
@@ -136,4 +161,6 @@
## Change Log
- 2026-05-11 KST: bat-007 — Added "Schema Ownership Boundary" section documenting ensure_schema() vs Alembic ownership zones, allowed/forbidden execution sequences, and legacy scope exclusion.
- 2026-05-11 KST: bat-006 — Added get_portfolio_by_name_and_user() to repositories section; noted that portfolio_id is now a server-generated UUID.
- 2026-04-30 KST: Bootstrap baseline created from repository observation for initial StagePilot adoption.