# BAT-001 Implementation - Status: verified - Batch: BAT-001 ## Plan Summary - 이 batch 구현에서 실제 변경할 범위: 1. `app/domain/models.py` — MarketCode Enum, Asset 모델 추가; Portfolio 모델 symbol/market 제거, asset_id 추가 2. `app/repositories/portfolio_repository.py` — asset CRUD Protocol 선언 추가 3. `app/repositories/postgres.py` — asset CRUD SQL 구현; portfolios JOIN assets 쿼리 반영 4. Alembic rev-A — assets 테이블 생성 + GIN 인덱스 5. Alembic rev-B — portfolios 데이터 이전 + asset_id FK 추가 + symbol/market 컬럼 제거 (단일 트랜잭션) 6. `app/api/portfolios.py`, `app/api/v1_assets.py`, `app/cli/commands/portfolio.py`, `app/schemas/` — symbol/market 참조 제거 7. `tests/test_asset_catalog.py` 신규 — REQ-009 AC-1~5, REQ-011 AC-1~5, REQ-014 AC-1~6 ## Changed Files - `app/domain/models.py` - `app/repositories/portfolio_repository.py` - `app/repositories/postgres.py` - `migrations/versions/_create_assets_table.py` (신규) - `migrations/versions/_portfolios_asset_migration.py` (신규) - `app/api/portfolios.py` - `app/api/v1_assets.py` - `app/cli/commands/portfolio.py` - `app/schemas/` (영향 파일 구현 단계에서 확정) - `tests/test_asset_catalog.py` (신규) ## Changed Files (확정) - `app/domain/models.py` — MarketCode Enum, Asset dataclass 추가; Portfolio.market 제거 → asset_id 추가 - `app/repositories/portfolio_repository.py` — create_portfolio symbol→asset_id; asset CRUD Protocol 선언 5종 - `app/repositories/postgres.py` — _SELECT_PORTFOLIO JOIN assets; save/reset/adjust_buffer/transfer_buffer RETURNING 제거; create_portfolio/update_portfolio 수정; asset CRUD 5종 구현; get_or_create asset 조회 로직 추가 - `migrations/versions/20260519_0017_create_assets_table.py` (신규) — assets 테이블 + GIN 인덱스 (rev-A) - `migrations/versions/20260519_0018_portfolios_asset_migration.py` (신규) — 데이터 이전 + asset_id FK + symbol/market DROP (rev-B) - `app/schemas/v1.py` — AssetItem.market 제거 - `app/api/v1_assets.py` — market=p.market 제거 - `app/schemas/portfolio.py` — PortfolioBase.symbol 제거; CreatePortfolioRequest.asset_id 추가; UpdatePortfolioRequest.symbol 제거 - `app/services/portfolio_service.py` — create_portfolio symbol→asset_id - `app/cli/commands/portfolio.py` — create --symbol→--asset-id; update --symbol 제거 - `tests/test_asset_catalog.py` (신규) — REQ-009 AC-4,5 + REQ-011 AC-4,5 + REQ-014 migration 파일 구조 검증 - `tests/test_cli.py` — FakeRepo create_portfolio symbol→asset_id; _portfolio() name 공백 제거; 테스트 픽스처 업데이트 - `tests/test_portfolio_uuid.py` — FakeRepo create_portfolio symbol→asset_id; --symbol→--asset-id 전환 - `tests/test_v1.py` — market 필드 어서션 제거 - `tests/test_portfolio_ownership.py` — POST body symbol→asset_id - `tests/test_daemon_assignment.py` — Portfolio() market= 제거 ## Execution Log 1. app/domain/models.py: MarketCode Enum, Asset 모델 추가; Portfolio market→asset_id 필드 교체 2. app/repositories/portfolio_repository.py: create_portfolio 시그니처 변경; asset CRUD Protocol 5종 선언 3. app/repositories/postgres.py: JOIN 쿼리, RETURNING 제거 패턴, asset CRUD 5종 구현, get_or_create symbol→asset 조회 4. Alembic rev-A(0017): assets 테이블 + GIN 인덱스 생성 5. Alembic rev-B(0018): 데이터 이전 → asset_id FK → symbol/market DROP (단일 트랜잭션 내 idempotent 가드) 6. 스키마/API/CLI 레이어: symbol/market 참조 전수 제거 7. 기존 테스트 suite 17개 실패 수정: 공백 포함 이름, --symbol→--asset-id, market 어서션 제거, request body 업데이트 8. test_asset_catalog.py 신규 작성: 20개 테스트 ## Validation - pytest 162 passed (tests/test_asset_catalog.py 20, tests/test_cli.py 35, tests/test_portfolio_uuid.py 14, tests/test_v1.py 21, tests/test_portfolio_ownership.py 4, 나머지 기존 suite) - 실행 명령: `.venv/bin/python -m pytest --tb=short` ## Remaining Risks - DB-integration ACs(REQ-009 AC-1,2,3; REQ-011 AC-1,2,3; REQ-014 AC-1~6)는 실제 PostgreSQL 연결 없이 검증 불가 — verification.md에 통합 테스트 항목으로 기록 - R-4(운영 환경 대용량 lock): 로컬 테스트 범위 밖; 운영 배포 시 maintenance window 고려 필요