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
7.3 KiB
7.3 KiB
req-016: portfolios 테이블 UUID 전환 및 데이터 마이그레이션
- Status: Implemented
- Type: Migration
- Priority: High
- Owner: repository-maintainers
Intent
- 현재 사용자가 직접 지정하는 TEXT PRIMARY KEY(
portfolio_id)를 서버 생성 UUID로 교체하고, 기존portfolio_id문자열을name컬럼으로 이전한다. (owner_user_id, name)복합 UNIQUE 제약을 DB 레벨에서 도입해 사용자 범위 내 이름 유일성을 보장한다.- 기존 데이터와 FK 참조 테이블(
portfolio_ledger,portfolio_comments,portfolio_tags,ledger_trades)을 단일 Alembic revision으로 atomic하게 마이그레이션한다.
Requirement
- 단일 Alembic revision을 추가해 아래를 수행한다.
portfolios테이블에nameTEXT 컬럼을 추가한다.- 기존
portfolio_id값을name컬럼으로 복사한다 (변환 없이 그대로). - 각 기존 레코드에
uuid.uuid4()로 새 UUID를 생성해portfolio_id컬럼 값을 교체한다. - FK 참조 테이블(
portfolio_ledger,portfolio_comments,portfolio_tags,ledger_trades)의portfolio_id컬럼 값도 새 UUID로 함께 갱신한다. (owner_user_id, name)복합 UNIQUE 제약을portfolios테이블에 추가한다.Portfoliodataclass(app/domain/models.py)의portfolio_id필드를 UUID 문자열로 유지하고name필드를 명확히 선언한다.app/repositories/postgres.py의create_portfolio()메서드가 서버에서uuid.uuid4()로 생성된 UUID를portfolio_id로 사용한다.
- 마이그레이션은 IF NOT EXISTS 패턴을 준수해 재실행 시 오류가 없어야 한다(REQ-002 준수).
- FK 참조 테이블과의 갱신은 단일 트랜잭션 내에서 atomic하게 처리한다.
- 마이그레이션 완료 후 FK 고아 레코드(orphan) 0건을 검증하는 쿼리를 revision 안에 포함한다.
Acceptance Criteria
- Given 기존
portfolio_id문자열로 운영 중인 portfolios 레코드가 있을 때, When 신규 Alembic revision을alembic upgrade head로 실행하면, Then 각 레코드의name컬럼에 기존portfolio_id값이 그대로 복사되고,portfolio_id는 UUID 형식(re.match(r'^[0-9a-f-]{36}$', ...))으로 교체된다. - Given 마이그레이션 완료 후, When
portfolio_ledger,portfolio_comments,portfolio_tags,ledger_trades의portfolio_id컬럼을 확인하면, Then 고아 레코드(FK 불일치 레코드)가 0건이다. - Given
(owner_user_id, name)복합 UNIQUE 제약이 적용된 상태에서, When 동일owner_user_id와 동일name으로 portfolio 레코드를 추가하면, Then DB 레벨에서 UNIQUE 제약 위반 오류가 발생한다. - Given 동일
name이지만 다른owner_user_id로 portfolio 레코드를 추가하면, Then 정상 삽입된다. - Given 신규 Alembic revision을 이미 적용한 환경에서, When 동일 revision을 재실행하면, Then 오류 없이 완료된다(IF NOT EXISTS 준수).
- Given
app/repositories/postgres.py의create_portfolio()메서드가 실행되면, Then 서버에서uuid.uuid4()로 생성된 UUID가portfolio_id로 저장된다.
Impacted Area
- Docs:
docs/data-model.md(portfolios 테이블 스키마 변경 반영 — REQ-019에서 처리) - Modules:
migrations/versions/: 신규 Alembic revision 파일app/domain/models.py: Portfolio dataclassportfolio_id및name필드app/repositories/postgres.py:create_portfolio()UUID 생성,get_portfolio_by_name_and_user()신규 메서드
- Tests:
- 신규
tests/test_portfolio_uuid.py또는tests/test_cli.py— portfolio_id UUID 형식 검증, 동일 name 독립 생성 테스트, (owner_user_id, name) UNIQUE 제약 동작 확인
- 신규
Notes
- 기존
portfolio_id문자열은name컬럼으로 변환 없이 복사한다(Discovery A-3 확정). portfolio_id컬럼 타입은 TEXT 유지(PostgreSQL UUID 타입으로의 전환은 이번 범위 밖).app/domain/models.py의Portfolio.portfolio_id는 UUID 문자열로 의미가 바뀌나 Python 타입(str)은 유지.get_portfolio_by_name_and_user()메서드는 REQ-017(CLI 식별 방식 전환)에서도 사용한다.- Source Discovery: dcy-004_20260511_portfolio-id-uuid-migration-and-user-scoped-name-resolution (FR-1, FR-5, NFR-1)
Change Log
CHG-20260511-01
- Date: 2026-05-11
- Author: repository-maintainers
Change Summary
- 최초 생성 — dcy-004 draft-req에 의해 생성
Intent
- dcy-004 Discovery의 FR-1(portfolios.portfolio_id UUID 교체 및 name 컬럼 추가), FR-5(기존 데이터 마이그레이션), NFR-1(단일 revision, IF NOT EXISTS, atomic 트랜잭션) 반영
Acceptance Criteria Delta
- Added:
- 1~6 (최초 생성)
Impacted Area Delta
- Docs:
- docs/data-model.md: portfolios 테이블 스키마 변경 (REQ-019에서 처리)
- Modules:
- migrations/versions/: 신규 revision 추가
- app/domain/models.py: Portfolio dataclass 변경
- app/repositories/postgres.py: create_portfolio UUID 생성, get_portfolio_by_name_and_user() 추가
- Tests:
- tests/test_portfolio_uuid.py 또는 tests/test_cli.py: UUID 형식 검증, UNIQUE 제약 동작 확인
Delivery Trace Delta
- Batches: none (batch 미결정)
- Releases: none
Revalidation Impact
- Reverification Needed: no
- Existing Implementation Invalidated: no
- Status Recommendation: keep-current
- Follow-up Action: confirm-req → suggest-batch-reqs → draft-batch
Validation Plan
- pytest: portfolio_id UUID 형식 검증, FK 고아 레코드 0건 확인, (owner_user_id, name) UNIQUE 제약 동작 확인, IF NOT EXISTS 재실행 안전성 확인
CHG-20260511-02
- Date: 2026-05-11
- Author: repository-maintainers
Change Summary
- Approved 전환 — confirm-req 게이트 통과
Intent
- Delivery 입력으로 사용할 수 있도록 REQ-016을 승인 상태로 승격한다.
Acceptance Criteria Delta
- Added:
- none
- Updated:
- none
- Removed:
- none
Impacted Area Delta
- Docs:
- none
- Modules:
- none
- Tests:
- none
Delivery Trace Delta
- Batches:
- none
- Releases:
- none
Revalidation Impact
- Reverification Needed: no
- Existing Implementation Invalidated: no
- Status Recommendation: keep-current
- Follow-up Action: suggest-batch-reqs로 batch grouping 검토
Validation Plan
- confirm-req 게이트 재평가 결과: 필수 메타데이터, 구체적 Acceptance Criteria, Impacted Area, Change Log, blocker 없음 확인
CHG-20260511-03
- Date: 2026-05-11
- Author: repository-maintainers
Change Summary
- Implemented 전환 — BAT-006 verification passed, confirm-req-implemented 게이트 통과
Intent
- BAT-006 verification.md의 REQ-016 Acceptance Mapping이 모든 AC에 대해 test evidence를 포함하고 있으며, Blocking Issues 없음으로 구현 완료 상태로 전환한다.
Acceptance Criteria Delta
- none
Impacted Area Delta
- none
Delivery Trace Delta
- Batches: BAT-006 (release-candidate)
- Releases: none
Revalidation Impact
- Reverification Needed: no
- Existing Implementation Invalidated: no
- Status Recommendation: implemented
- Follow-up Action: draft-release (BAT-006)
Validation Plan
- BAT-006 verification.md AC-1~6 모두 test evidence 연결 확인 (tests/test_portfolio_uuid.py 14/14 passed, full suite 129/129 passed)