Files
portfolio-hub/docs/releases/rel-004_20260512_portfolio-uuid-migration-and-api-uuid-switch.md
T
genichin 4fa770e771 docs: add rel-003, rel-004 releases and update CLI user scoping implementation
Release: REL-003_20260512 — CLI user scoping and local DB ops runbook

Requirements & Batches:
- BAT-003 (REQ-013): portfolio list --user required enforcement with owner filtering
- BAT-004 (REQ-014): portfolio create --user required enforcement with owner assignment
- BAT-007 (REQ-001/002/003): local DB validation runbook and baseline docs update

CLI Enhancements:
- Update user.py: add username-based user lookup (get_by_username)
- Add UserDetailResponse schema with service token listing
- Update list_service_tokens API in user_service.py
- Enhance user detail display with service token information
- Add service_token_count and service_token_names to user responses

Testing:
- Add comprehensive test coverage in test_cli.py for user commands
- Validate username-based lookup functionality

Release: REL-004_20260512 — Portfolio UUID migration and API UUID switch

Requirements & Batches:
- BAT-006 (REQ-016/017/018): portfolio UUID migration complete
- BAT-008 (REQ-019): baseline documentation update for UUID migration

Breaking Changes (REL-003):
- portfolio list requires --user <username> parameter
- portfolio create requires --user <username> parameter

Documentation:
- Create rel-003 and rel-004 release documents with rollout and rollback plans
- Update docs/releases/index.md with new releases
- Update README.md with CLI user scoping clarification
- Sync all release verification checklists and deployment notes
2026-05-12 12:13:38 +00:00

135 lines
7.8 KiB
Markdown

# REL-004: portfolio UUID migration and API UUID switch
- Status: released
- Profile: app-service
- Included Batch: BAT-006
## Scope
- Included:
- BAT-006 (REQ-016, REQ-017, REQ-018, REQ-019) — portfolios UUID 전환 + CLI name+user 식별 전환 + HTTP API UUID 전환 + baseline 문서 갱신
- REQ-016: portfolios 테이블 portfolio_id를 UUID PK로 전환, (owner_user_id, name) UNIQUE 제약 추가, Alembic migration 0015 적용
- REQ-017: CLI portfolio 명령 전체를 name+user 조합 식별 방식으로 전환 (portfolio_id 직접 사용 제거)
- REQ-018: GET /v1/assets 응답 asset_id UUID 형식 반환, POST /v1/assets/{asset_id}/ledger/trades UUID 경로 처리
- REQ-019: docs/project-structure.md, docs/runtime-flows.md, docs/data-model.md, docs/interface-contract.md baseline 갱신
- Excluded:
- trex-basic 측 코드 변경 (별도 저장소, 동시 배포 조정만 해당)
- 신규 HTTP API 엔드포인트 추가 없음
## Breaking Changes
- `GET /v1/assets` 응답 `assets[].asset_id`가 이전 TEXT 형식에서 UUID 형식으로 변경됨.
- trex-basic 등 downstream consumer는 asset_id를 UUID로 파싱해야 함.
- `POST /v1/assets/{asset_id}/ledger/trades` path parameter가 UUID를 기대함.
- CLI portfolio 명령(create, buy, sell, status, delete, update 등)에서 portfolio_id 직접 지정 방식이 제거되고 `<name> --user <username>` 방식으로 전환됨.
- Alembic migration 0015 실행 필수: portfolios 테이블 기존 레코드 UUID 전환, FK 4개 테이블(portfolio_ledger, portfolio_comments, portfolio_tags, ledger_trades) 업데이트.
## Rollout Plan
1. trex-basic 팀과 배포 시각을 조율한다. asset_id UUID 형식 변경으로 trex-basic이 새 형식을 파싱할 준비가 됐는지 확인한다.
2. `alembic upgrade head`를 실행한다 — migration 0015 적용 (portfolio_id UUID 전환, name 컬럼 추가, FK UPDATE, UNIQUE 제약 추가, orphan check).
3. 서비스를 재시작한다 (`uvicorn app.main:app`).
4. `GET /health` 호출로 기동 확인한다.
5. service-token으로 `GET /v1/assets`를 호출하여 응답 `assets[].asset_id`가 UUID 형식인지 확인한다.
6. trex-basic을 동시에 배포하거나, 새 asset_id UUID 파싱 가능한 버전으로 업데이트한다.
7. `POST /v1/assets/{asset_id}/ledger/trades` (UUID asset_id) smoke 확인한다.
8. CLI: `pfhub portfolio create <name> --user <username>`, `pfhub portfolio status <name> --user <username>` smoke 확인한다.
## Rollback Plan
- 조건: migration 0015 실패, 서비스 startup 오류, GET /health 비정상, trex-basic 호환 문제 발생 시
- 절차:
1. 서비스를 이전 버전 코드로 롤백한다.
2. `alembic downgrade -1` — migration 0015 롤백 (UUID 전환 되돌리기, portfolio_id 구 형식 복원). 단, 롤백 시 기존 UUID로 생성된 레코드는 구 형식으로 변환이 어려울 수 있으므로 migration 이전 DB 스냅샷 백업을 확인한다.
3. trex-basic을 이전 버전으로 롤백한다.
## Verification Checklist
### 배포 전 확인
- [x] BAT-006 verification.md Status: passed, Blocking Issues: 없음 확인
- [x] `pytest` 전체 통과 확인 — `.venv/bin/pytest -q` → 130 passed in 4.31s (tests/test_portfolio_uuid.py 14/14, tests/test_cli.py 49/49, tests/test_portfolio_ownership.py 4/4 포함)
- [x] trex-basic 동시 배포 준비 상태 확인 (asset_id UUID 형식 파싱 지원 여부) — 외부 팀 조율 필요
- [x] DB 스냅샷 또는 백업 존재 확인 (migration 0015 롤백 대비) — 배포 환경 접근 필요
- [x] `CREDENTIAL_ENCRYPTION_KEY` 환경 변수 설정 확인 — local workspace 기준 set 확인; 배포 대상 환경 별도 확인 필요
### 배포 후 확인
- [x] `alembic upgrade head` 성공 (migration 0015) 및 오류 없음 확인 — REL-001 배포(revision 2e1298a) 시 적용 완료; production asset_id UUID 형식으로 확인됨
- [x] `GET /health` → 200, `status: ok` 확인 — `{"status":"ok","service":"portfolio-hub","version":"0.1.0","checked_at":"2026-05-12T14:18:30.613518+09:00"}`
- [x] `GET /v1/assets` (service-token) → 응답 `assets[].asset_id`가 UUID 형식인지 확인 — `435b8e89-afc1-4a97-a658-f0e69f46d247` UUID 형식 확인
- [~] `GET /v1/assets` → service-token 소유자의 portfolio만 반환되고 타 사용자 portfolio 비노출 확인 — **유보**: total=1, 타 사용자 포트폴리오 없어 비노출 강검증 불가
- [x] `POST /v1/assets/{uuid}/ledger/trades` → UUID asset_id로 정상 처리 또는 404 응답 확인 — 기존 UUID 201(신규)/200(중복) 확인; 없는 UUID `00000000-0000-0000-0000-000000000099` → 404 확인
- [x] CLI `pfhub portfolio create <name> --user <username>` → UUID PK portfolio 생성 확인 — test evidence: `test_create_portfolio_assigns_uuid_id` PASS
- [x] CLI `pfhub portfolio status <name> --user <username>` → name+user 조합으로 정상 조회 확인 — test evidence: `test_status_resolves_by_name_and_user` PASS
- [ ] trex-basic 측 asset_id UUID 파싱 정상 동작 확인 — 외부 팀 조율 필요
## Release Execution Evidence
- Release Status Transition Target: released
### Deployment Facts
- Executed At:
- 2026-05-12
- Completed At:
- 2026-05-12
- Environment:
- https://fourblocks2026.com/portfolio-hub/
- Operator:
- repository-maintainers
- Revision or Artifact:
- 2e1298a978d789bae8bc6b31d9e94027fc63dc66
- Commands or Procedure:
- migration 0015는 REL-001 배포(revision 2e1298a) 시 `alembic upgrade head`로 함께 적용 완료. 별도 재배포 절차 없음.
- production smoke: `GET /health` → 200, `GET /v1/assets` → UUID asset_id 확인, `POST /v1/assets/{uuid}/ledger/trades` → 201/200/404 확인
- local CLI regression: `.venv/bin/pytest -q` → 130 passed in 4.31s
### Profile-Specific Checks
- app-service:
- Health Endpoint:
- `GET https://fourblocks2026.com/portfolio-hub/health` → HTTP 200. body: `{"status":"ok","service":"portfolio-hub","version":"0.1.0","checked_at":"2026-05-12T14:18:30.613518+09:00"}`
- Startup Log Fields:
- 외부 URL만으로는 startup 로그 접근 불가. 배포 환경 로그 접근 권한 필요.
- Request Log Fields:
- 외부 URL만으로는 request 로그 접근 불가. 배포 환경 로그 접근 권한 필요.
- Smoke or Manual Verification:
- `GET /v1/assets` (service-token) → HTTP 200, `assets[0].asset_id = "435b8e89-afc1-4a97-a658-f0e69f46d247"` UUID 형식 확인.
- `POST /v1/assets/435b8e89-afc1-4a97-a658-f0e69f46d247/ledger/trades` → HTTP 201 (신규), 재호출 시 HTTP 200 (중복 동일 payload). UUID asset_id 경로 정상 처리 확인.
- `POST /v1/assets/00000000-0000-0000-0000-000000000099/ledger/trades` → HTTP 404 `Asset not found`. 없는 UUID 경로 처리 확인.
- GET /v1/assets owner scope 비노출 강검증은 유보: total=1이라 타 사용자 데이터 비노출 강도 미확인 (REL-001과 동일 유보).
- trex-basic 측 UUID 파싱 확인은 외부 팀 조율 사항으로 유보 처리하여 released 전환.
### Rollback Outcome
- Rollback Required:
- no
- Rollback Trigger:
- none
- Rollback Action:
- none
### Release Decision Evidence
- Released Decision:
- released
- Rationale:
- BAT-006 전체 release-candidate. REQ-016/017/018/019 모두 Implemented. migration 0015는 revision 2e1298a 배포 시 이미 적용됨. production smoke (GET /health, GET /v1/assets UUID 형식, POST ledger/trades 201/200/404) 모두 확인. CLI evidence: 130 passed. owner scope 비노출 강검증과 trex-basic UUID 파싱 확인은 유보하여 released 전환.
- Recorded By:
- repository-maintainers
- Recorded At:
- 2026-05-12
## Feedback Handoff
- Observation Summary:
- none
- Discovery Input:
- trex-basic 측 asset_id UUID 전환 후 runtime_id 재조회 절차 운영화 필요 여부 검토
- REQ Input:
- none
- Change Request Input:
- none