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
135 lines
7.8 KiB
Markdown
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
|