dcy-019/issue #18: slot 자원을 진입 횟수 기준으로 고르게 재사용하고 idle 소진 시 closed 슬롯을 직접 재할당한다. 거버넌스는 전부 change-req(신규 REQ 없음). - 도메인(REQ-002): Slot.entry_count(기본 0) + EXPECTED_SLOT_FIELDS, 상태 머신 closed→pending_buy 신규 전이(base 8→9, ALLOWED_TRANSITIONS 14→15), _apply_transition_fields closed→pending_buy clean-slate + →pending_buy 시 +1 - 영속화(REQ-006): 멱등 마이그레이션 008(entry_count), flat 매핑, find_allocatable_slot(idle∪closed, entry_count→updated_at→slot_id) + in-memory 동등 - admission(REQ-007): _admit_buy find_idle_slot→find_allocatable_slot + from_state=slot.status - 테스트(REQ-003): 전이 카운트/계약 가드 정합 + test_slot_entry_count.py / test_buy_admission_reallocation.py - 문서(REQ-009): data-model.md / runtime-flows.md 정합 - 기존 daily_symbol_entries(symbol-scoped) 분리·미변경 BAT-025(release-candidate) delivery + change-req REQ-002/003/006/007/009(CHG-20260609-01). REL-005(confirmed, app-service): BAT-024+BAT-025 묶음. operator-facing run-the-app 스모크로 enter --forced-close-at(BAT-024)·closed 재할당(BAT-025) 실 데몬 검증 (실 PG 마이그레이션 008 round-trip 포함). 검증: 단위 366 passed / 35 skipped(KIS sandbox 1건 deselect — live .env 환경 의존), ruff clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
4.8 KiB
4.8 KiB
BAT-025 Verification
- Status: verified
- Batch: BAT-025
Acceptance Mapping
REQ-002 (entry_count 필드 + closed→pending_buy 전이 + 전이 로직, change-req)
| AC | Evidence |
|---|---|
Slot.entry_count 가 EXPECTED_SLOT_FIELDS 에 포함 |
tests/domain/slot/test_contract.py::test_slot_fields_match_expected_contract |
6 상태 / 9 base 전이(closed→pending_buy) |
tests/domain/slot/test_state.py::test_allowed_transition[CLOSED-PENDING_BUY] / ::test_allowed_transitions_set_size(15) |
→pending_buy 시 entry_count +1(idle→/closed→), 그 외 보존 |
tests/domain/slot/test_slot_entry_count.py::TestEntryCount(증분/non-buy/closed→idle 보존) |
| closed→pending_buy clean-slate 점유 초기화 | ::TestClosedReallocation::test_closed_to_pending_buy_clean_slate_and_bumps_count / ::test_closed_to_pending_buy_clears_prior_position_when_not_supplied |
REQ-003 (테스트 계약 정합, change-req)
| AC | Evidence |
|---|---|
전이 집합 테스트 closed→pending_buy allowed + 크기 15 |
tests/domain/slot/test_state.py |
| 컬럼 계약 가드 entry_count 포함 | tests/domain/slot/test_contract.py |
| entry_count/reallocation 신규 단위 | tests/domain/slot/test_slot_entry_count.py, tests/application/test_buy_admission_reallocation.py |
REQ-006 (마이그레이션 + persistence + selector, change-req)
| AC | Evidence |
|---|---|
daily_slot entry_count 컬럼(마이그레이션 008, 멱등) |
sql/008_add_slot_entry_count.sql + tests/adapters/persistence/test_migration_and_drift.py(test DSN 게이트, EXPECTED_SLOT_FIELDS↔information_schema 자동) |
find_allocatable_slot(idle∪closed, entry_count→updated_at→slot_id) |
tests/domain/slot/test_slot_entry_count.py::TestAllocatableSelector(none/idle-only/closed 포함/오름차순) |
| flat slot 매핑(+entry_count) round-trip | tests/adapters/persistence/test_migration_and_drift.py(test DSN) + in-memory selector 단위 |
REQ-007 (_admit_buy 일반화, change-req)
| AC | Evidence |
|---|---|
| idle 소진 시 closed 슬롯으로 admit | tests/application/test_buy_admission_reallocation.py::test_admits_into_closed_slot_when_no_idle_remains |
| idle 우선(closed 보다) | ::test_prefers_idle_over_closed |
| idle·closed 모두 소진 → no_idle_slot 거부 | ::test_rejects_when_no_idle_and_no_closed |
| 마지막 슬롯 경합 동시성 회귀 | tests/application/test_intent_concurrency.py 전체 |
REQ-009 (baseline 문서 정합, change-req)
| AC | Evidence |
|---|---|
| runtime-flows admission selector/transit entry_count step | docs/runtime-flows.md(코드-문서 diff 대조) |
| data-model daily_slot entry_count/lifecycle/state rules | docs/data-model.md(코드-문서 diff 대조) |
Evidence
- Test:
- 단위 전체 회귀:
366 passed / 35 skipped / 1 deselected(신규 entry_count 12 + reallocation 3 포함;::test_sandbox_token_and_submitdeselect — LIVE.envKIS URL 환경 의존, 본 batch 무관). ruff check trex_core tests→ All checks passed.
- 단위 전체 회귀:
- Logs:
366 passed, 35 skipped, 1 deselected in 1.13s.
성공 기준(dcy-019) 대응
- S-1(idle 없고 closed 있을 때 closed 로 admit, 이전엔 no_idle_slot 거부): test_admits_into_closed_slot_when_no_idle_remains.
- S-2(
entry_count최소 선택 + tie-break 결정적): TestAllocatableSelector::test_orders_by_entry_count_ascending + test_prefers_idle_over_closed. - S-3(할당 전이 시 정확히 +1, 동시 경합 중복 없음,
daily_symbol_entries회귀 green): TestEntryCount::test_increments_on_each_pending_buy + test_intent_concurrency.py + test_service.py::TestClosedToIdleRecovery(daily_symbol_entries 보존).
Carried-Over / 비차단
- PG 게이트(마이그레이션 008 round-trip + 드리프트)는 라이브 runtime DSN 미사용(파괴적 truncate 회피) → test DSN 환경에서 자동 검증. 마이그레이션은 004 의 검증된 additive·멱등 패턴과 동일하고, 드리프트 가드는
EXPECTED_SLOT_FIELDS(entry_count 포함)↔information_schema 로 강제되어 코드 단위로 동등 보장. - 실 데몬 + 실 PG full-stack 의 closed 재할당 e2e 는 운영 배포 검증(후속 REL)에서 확인 — 단위(in-memory repo + IntentService)로 admission/전이/카운트 커버.
- snapshot
available_slots(=idle_count) 는 dcy-019 범위 밖(§5 제외)이라 closed 가용분을 보수적으로 under-report — admission 자체는 closed 재할당을 수행. 필요 시 후속 change-req 후보.
Result
- Ready for Release: true
- Blocking Issues:
- 없음. entry_count 필드/closed→pending_buy 전이/selector/admission 일반화 전부 단위 green(366 passed 회귀, flat 매핑·계약 가드 무누락, 동시성 경합 회귀 보존). PG 게이트는 test DSN 자동 검증(라이브 DSN 비파괴 정책). LIVE full-stack 은 운영 배포 검증 비차단.