Deliver BAT-002: slot-core daemon + HTTP intent API + PostgreSQL

Implement REQ-005~009 (dcy-002 slice 1) as an onion stack on top of the
BAT-001 pure domain:
- application: IntentService (admission + single-writer transition +
  intent_id idempotency via durable intent_log)
- adapters/persistence: PostgreSQLSlotRepository + PostgreSQLIntentStore +
  trex-core-owned migrations (daily_slot per Appendix A, daily_symbol_entries,
  slot_transition_log, intent_log) + in-memory intent store
- adapters/api: FastAPI /v1 (healthz, intents/buy|sell|{id}, slots, capacity)
- runtime: trex-core-daemon entrypoint with lifespan migrate+preallocate

Verification (against local PostgreSQL 18): 74 passed, ruff clean, domain
import sweep shows zero web/db deps (NFR-1), 20-thread concurrency admits
exactly the idle count (NFR-2), idempotent resubmit causes no double
transition (NFR-3), EXPECTED_SLOT_FIELDS<->information_schema drift test
(realizes dcy-001 OQ-2's deferred DB-side check), and a daemon E2E smoke.

Align all four baseline docs to the new daemon/API/persistence layers.
BAT-002 -> release-candidate; REQ-005~009 -> Implemented. Full async outbox,
broker execution, safety floor, and strategy daemons remain deferred to a
follow-up Discovery.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-04 13:46:08 +09:00
co-authored by Claude Opus 4.8
parent a44f9fddb7
commit a4e263c8e7
41 changed files with 1778 additions and 38 deletions
+25 -3
View File
@@ -4,9 +4,9 @@
- Baseline Seed: .stage-pilot/bootstrap/baseline.yaml
- Status: draft
- Owner: project maintainers
- Last Updated (KST): 2026-06-03
- Source Discovery / Batch: bootstrap-baseline (pre-Discovery)
- Primary Runtime: library
- Last Updated (KST): 2026-06-03 (BAT-002)
- Source Discovery / Batch: bootstrap-baseline (pre-Discovery); 데몬/HTTP 흐름 = dcy-002 / BAT-002
- Primary Runtime: daemon (HTTP API) + library (slot 도메인)
## Project Summary
- trex 제품군의 공용 베이스로, 첫 도메인으로 trex-orbit 의 일일 거래 슬롯 생명주기(slot) 순수 도메인을 storage-agnostic 하게 이식한 코어다.
@@ -21,9 +21,30 @@
## Covered Entry Points
- `trex-core-daemon` :: 슬롯 코어 데몬 (lifecycle + HTTP `/v1` 서빙, BAT-002)
- HTTP `/v1` :: intent 제출/조회 경계 (전략 데몬 클라이언트)
- SlotService :: 슬롯 생명주기 도메인 서비스 (preallocate / transit / capacity / entry-count)
- SlotRepository (Protocol) :: 저장소 구현체 주입 경계
## Flow: `데몬 lifecycle` (BAT-002)
1. `trex-core-daemon` 기동 → `DaemonConfig.from_env()`(TREX_POSTGRESQL_DSN 등).
2. startup(lifespan): `apply_migrations(dsn)`(멱등) → 거래일 슬롯 `preallocate_daily_slots`(멱등, 공개 엔드포인트 아님).
3. uvicorn 이 FastAPI `/v1` 앱 서빙(`GET /v1/healthz` 200).
4. shutdown: 연결-당-호출 어댑터라 풀 정리 없음, graceful 종료.
## Flow: `매수 intent` (POST /v1/intents/buy, BAT-002)
1. 전략 데몬이 intent(intent_id 포함)를 POST.
2. IntentService: `intent_log.try_insert`(intent_id) dedup 게이트 — 중복이면 기존 decision 동기 반환(슬롯 무전이).
3. 신규면 admission: `find_idle_slot` → `SlotService.transit_slot(idle→pending_buy)`(advisory lock 단일 writer). last-idle 경합 시 StateMismatch 재시도.
4. `intent_log.finalize(admitted/rejected, slot_id)` → admit/reject 동기 응답.
## Flow: `매도 intent` (POST /v1/intents/sell, BAT-002)
1. 전략 데몬이 holding 슬롯을 `GET /v1/slots?status=holding` 로 조회 후 sell intent POST.
2. dedup 게이트 → 검증(slot 이 holding 인가) → `transit_slot(holding→pending_sell)` → finalize → 동기 응답.
## Shared Components
- SlotRepository Protocol :: 저장소 추상화. 구현체(InMemorySlotRepository, 향후 PostgreSQLSlotRepository)를 주입.
@@ -71,3 +92,4 @@
- 2026-06-03 :: bootstrap-baseline 으로 초기 흐름 baseline 생성(slot 도메인 in-process API 흐름 기준).
- 2026-06-03 :: BAT-001 이식 완료 반영 — preallocate/transit 흐름이 `trex_core.domain.slot` 실제 코드로 구현됨(REQ-004). 영속화/CLI 흐름은 여전히 미구현(범위 밖).
- 2026-06-03 :: BAT-002 — 데몬 lifecycle + 매수/매도 intent HTTP 흐름 추가, Primary Runtime=daemon+library(REQ-005~009). 브로커 집행/safety floor 흐름은 후속 Discovery.