# BAT-016 Verification - Status: confirmed - Batch: BAT-016 > **재검증 (2026-06-05)**: 초기 검증은 mock-only 테스트만 근거로 "passed" 표기했으나, verify 단계에서 신 path가 실 DB에서 깨지는 결함 2건이 발견됨(ON CONFLICT on hypertable 불가, 공유 connection close). 재구현 + 실 DB 통합 테스트 후 아래 재검증. ## Acceptance Mapping - REQ-036: - AC-1: `\d portfolio_ledger`에 `ledger_entry_id`(Identity, 비-PK — CHG-20260605-03), `order_id`/`execution_id`(NULL), `side`/`executed_at`(NOT NULL) 존재. 마이그레이션 `20260605_0025` + `ensure_schema()` 일치. - AC-2: 수치 8컬럼 NUMERIC(20,8) — 실 DB `\d portfolio_ledger`로 확인. - AC-3 (CHG-20260605-03 재정의): partial unique index/PK는 **존재하지 않음**(hypertable 제약). idempotency는 application layer + `tests/test_ledger_consolidation_integration.py::test_duplicate_broker_write_is_idempotent`(실 DB)로 검증 — duplicate 시 row 1건 유지 확인. - AC-4: `action` 컬럼 제거 + `side` 대체 — 확인. - AC-5: `ledger_trades` 테이블 부재 — 실 DB 확인. - AC-6~7: ensure_schema/마이그레이션 backfill 정합 + 전체 회귀 통과. - REQ-037: - AC-1: `test_new_trade_updates_portfolio_and_returns_state`(실 DB) — buy 10@80,000 fee 100 → cash_balance_after=199,900, asset_quantity_after=10, portfolios 동일 갱신. - AC-2 (OQ-4 b): `test_duplicate_broker_write_is_idempotent`(실 DB) — 재호출 시 row 재생성 없이 현재 권위 상태 반환. - AC-3 (OQ-3 음수 허용): `test_negative_balance_allowed`(실 DB) — oversell → asset_quantity_after=-999, 거부 없음. - AC-4: 응답에 기존 필드 + cash_balance_after/asset_quantity_after 추가 — schema + 실 DB 응답 확인. - AC-5: daemon 3단계 인가 보존 — `tests/test_daemon_assignment.py` 회귀. - AC-6: `LedgerTrade` 참조 0건 — grep 확인, `LedgerEntry` 단일. - AC-7: row lock(`SELECT ... FOR UPDATE`) + `conn.transaction()`로 원자성/직렬화. - REQ-038: - AC-1~2: 레거시 buy/sell `deprecated=True` + `Deprecation: true` 헤더 — `app/api/portfolios.py` 확인. - AC-3~4: `tests/test_auth.py::test_legacy_buy_sell_routes_emit_deprecation_header` 통과. ## Evidence - Test: - 실 DB 통합: `.venv/bin/python -m pytest -q tests/test_ledger_consolidation_integration.py` → `3 passed` (실 Postgres — new/duplicate/음수) - mock 회귀: `tests/test_v1_portfolios_ledger.py tests/test_daemon_assignment.py tests/test_domain_services.py` → 24 passed - 전체: `.venv/bin/python -m pytest -q` → **376 passed, 3 warnings** (기존 373 + 통합 3) - Manual / 실 DB 직접 검증: - 수정 전: `ON CONFLICT (portfolio_id, order_id, execution_id) WHERE order_id IS NOT NULL` → 실 DB에서 `there is no unique or exclusion constraint matching the ON CONFLICT specification` 에러 재현. - hypertable 제약 확인: `CREATE UNIQUE INDEX ... WHERE order_id IS NOT NULL` → `cannot create a unique index without the column "recorded_at"`. - 수정 후: 통합 테스트로 new/duplicate/음수 정상 동작. - Logs: - pytest 출력 + docker psql 검증 출력 (터미널). ## Result - Ready for Release: true (실 DB 통합 검증 기준) - Blocking Issues: none - Deferred (prod staging): alembic `20260605_0025`의 fresh-DB 적용 + DOUBLE→NUMERIC 정밀도/action 분포는 release staging에서 검증(workspace_purpose 메모리). ensure_schema가 이미 적용된 개발 DB에서는 alembic 경로 충돌 가능 — 기존 ensure_schema vs alembic 이중 경로 패턴.