docs: advance dcy-005 asset snapshot discovery
This commit is contained in:
@@ -5,7 +5,7 @@
|
|||||||
- 문서 ID: dcy-005_20260604_portfolio-hub-asset-snapshot-api
|
- 문서 ID: dcy-005_20260604_portfolio-hub-asset-snapshot-api
|
||||||
- 이슈명: portfolio-hub 종목 스냅샷 read API — 전략 모듈에 전략 실행 대상 자산 리스트 제공
|
- 이슈명: portfolio-hub 종목 스냅샷 read API — 전략 모듈에 전략 실행 대상 자산 리스트 제공
|
||||||
- 작성 시각(KST): 2026-06-04 22:46
|
- 작성 시각(KST): 2026-06-04 22:46
|
||||||
- 마지막 갱신 시각(KST): 2026-06-05 21:02
|
- 마지막 갱신 시각(KST): 2026-06-05 22:36
|
||||||
- 대체됨: 없음
|
- 대체됨: 없음
|
||||||
- 후속 Discovery 참조: 없음
|
- 후속 Discovery 참조: 없음
|
||||||
- 생성된 REQ 참조: 없음
|
- 생성된 REQ 참조: 없음
|
||||||
@@ -15,9 +15,10 @@
|
|||||||
|
|
||||||
- 연계 문서 현황:
|
- 연계 문서 현황:
|
||||||
- 관련 점수 파일: 미생성
|
- 관련 점수 파일: 미생성
|
||||||
- 관련 TODO/메모: dcy-004(portfolio-hub ledger write 통합, BAT-006 진행 중)의 Out of Scope `asset master 동기화·get_assets/get_portfolios 연동`. orbit `app/clients/portfolio_client.py`(read 계약 get_assets/get_portfolios 패턴)
|
- 관련 TODO/메모: dcy-004(portfolio-hub ledger write 통합, BAT-006 진행 중)의 Out of Scope `asset master 동기화·get_assets/get_portfolios 연동`. orbit `app/clients/portfolio_client.py`(read 계약 get_assets/get_portfolios 패턴). **dcy-006(confirmed) — trex-core ↔ 전략 모듈 통신 transport 를 RabbitMQ 로 확정(HTTP 표면 0). 본 Discovery 의 스냅샷 read 는 그 transport(RabbitMQ request-reply RPC) 위에서 전달된다.**
|
||||||
- 해석:
|
- 해석:
|
||||||
- dcy-004 는 체결을 portfolio-hub 원장에 기록하는 **write 방향**이었고, 본 Discovery 는 그 반대인 **read 방향** — portfolio-hub 종목 스냅샷을 trex-core API 로 매수 전략 모듈에 제공한다. dcy-004 가 명시적으로 후속으로 미룬 영역을 이어받는다.
|
- dcy-004 는 체결을 portfolio-hub 원장에 기록하는 **write 방향**이었고, 본 Discovery 는 그 반대인 **read 방향** — portfolio-hub 종목 스냅샷을 trex-core 가 전략 모듈에 제공한다. dcy-004 가 명시적으로 후속으로 미룬 영역을 이어받는다.
|
||||||
|
- **transport/계약 분리**: 본 Discovery 는 스냅샷의 **logical 계약**(응답 단위·필드·마스킹·view 모드·strategy_id 필터·신선도)을 정의하며 **transport-무관**이다. 전달 방식(HTTP 아님 — dcy-006 의 RabbitMQ RPC)은 dcy-006 소관이고, 본 문서는 그 transport 위에 logical 계약을 얹는다.
|
||||||
- active-cycle 판정(BAT-006 draft 진행 중)이지만 명시적 신규 입력이고, BAT-006(write)과 read 방향이 분리되어 범위 충돌이 없으므로 병렬 독립 주기로 진행한다. core 경유의 핵심 가치는 단순 패스스루가 아니라 **core 의 권위 슬롯 상태를 겹쳐(slot overlay) 전략 실행 대상 자산을 선별(pending·warning·pause 마스킹)** 해 제공하는 것이다.
|
- active-cycle 판정(BAT-006 draft 진행 중)이지만 명시적 신규 입력이고, BAT-006(write)과 read 방향이 분리되어 범위 충돌이 없으므로 병렬 독립 주기로 진행한다. core 경유의 핵심 가치는 단순 패스스루가 아니라 **core 의 권위 슬롯 상태를 겹쳐(slot overlay) 전략 실행 대상 자산을 선별(pending·warning·pause 마스킹)** 해 제공하는 것이다.
|
||||||
|
|
||||||
# 2. 요구사항 판정 결과
|
# 2. 요구사항 판정 결과
|
||||||
@@ -26,13 +27,13 @@
|
|||||||
- 판정: 신규
|
- 판정: 신규
|
||||||
- 근거
|
- 근거
|
||||||
- dcy-004 는 write 방향(원장 기록)만 In Scope 였고 read 방향(get_assets/get_portfolios)은 명시적으로 Out of Scope(후속)였다. 본 Discovery 는 그 후속 read 통합이다.
|
- dcy-004 는 write 방향(원장 기록)만 In Scope 였고 read 방향(get_assets/get_portfolios)은 명시적으로 Out of Scope(후속)였다. 본 Discovery 는 그 후속 read 통합이다.
|
||||||
- 기존 REQ 본문 수정이 아니라 신규 외부 read 통합 + 신규 read API 엔드포인트라 `change-req` 가 아니라 새 Discovery 다.
|
- 기존 REQ 본문 수정이 아니라 신규 외부 read 통합 + 신규 read 계약(스냅샷 응답)이라 `change-req` 가 아니라 새 Discovery 다.
|
||||||
|
|
||||||
# 3. 문제점의 요약
|
# 3. 문제점의 요약
|
||||||
문제의 현재 상태, 기대 상태, 관련 이해관계자, 제약사항을 정리한다. Discovery의 핵심 맥락을 가장 먼저 이해할 수 있어야 한다.
|
문제의 현재 상태, 기대 상태, 관련 이해관계자, 제약사항을 정리한다. Discovery의 핵심 맥락을 가장 먼저 이해할 수 있어야 한다.
|
||||||
|
|
||||||
- 현재 상태
|
- 현재 상태
|
||||||
- trex-core 의 read API 는 슬롯 자체 조회(`GET /v1/slots`, `/v1/capacity`)와 intent 조회뿐이다(`trex_core/adapters/api/app.py`). portfolio-hub 종목을 노출하는 read 엔드포인트가 없다.
|
- trex-core 의 read 경로는 슬롯/capacity 조회와 intent 조회뿐이고 portfolio-hub 종목을 노출하는 read 경로가 없다. (현재 이 read 들은 HTTP `/v1` 로 제공되나, dcy-006 confirmed 로 통신 transport 가 RabbitMQ 로 대체되고 HTTP 표면은 0 이 된다. 따라서 본 스냅샷 read 는 신규 HTTP 엔드포인트가 아니라 dcy-006 의 RabbitMQ RPC 로 노출한다.)
|
||||||
- portfolio-hub read 어댑터(get_assets/get_portfolios)가 trex-core 에 없다. dcy-004/BAT-006 은 write 방향 `LedgerPort` + portfolio-hub 어댑터만 추가하며, read 포트는 다루지 않는다.
|
- portfolio-hub read 어댑터(get_assets/get_portfolios)가 trex-core 에 없다. dcy-004/BAT-006 은 write 방향 `LedgerPort` + portfolio-hub 어댑터만 추가하며, read 포트는 다루지 않는다.
|
||||||
- 결과적으로 매수 전략 모듈이 "무엇을 살지" 정할 portfolio-hub 종목 정보를 trex-core 를 통해 받을 경로가 없다.
|
- 결과적으로 매수 전략 모듈이 "무엇을 살지" 정할 portfolio-hub 종목 정보를 trex-core 를 통해 받을 경로가 없다.
|
||||||
- 기대 상태
|
- 기대 상태
|
||||||
@@ -45,8 +46,9 @@
|
|||||||
- 매수 전략 모듈(trex-core 외부 소비자) 및 portfolio-hub(외부 자산/포지션 서비스)
|
- 매수 전략 모듈(trex-core 외부 소비자) 및 portfolio-hub(외부 자산/포지션 서비스)
|
||||||
- 제약사항
|
- 제약사항
|
||||||
- 도메인 순수성 — `trex_core.domain` 은 portfolio-hub/네트워크 의존 0(read 어댑터 격리).
|
- 도메인 순수성 — `trex_core.domain` 은 portfolio-hub/네트워크 의존 0(read 어댑터 격리).
|
||||||
- 단일 통합 경계 — portfolio-hub 자격증명/계약 접점은 trex-core 어댑터(dcy-004 재사용)로 한정하며, 매수 전략 등 모든 소비자는 core 스냅샷 API 를 경유한다(portfolio-hub 직접 호출 금지, OQ-3).
|
- 단일 통합 경계 — portfolio-hub 자격증명/계약 접점은 trex-core 어댑터(dcy-004 재사용)로 한정하며, 매수 전략 등 모든 소비자는 core 스냅샷 계약을 경유한다(portfolio-hub 직접 호출 금지, OQ-3).
|
||||||
- core 는 슬롯/capacity 의 권위 단일 writer(불변식 A) — slot overlay 는 이 권위 상태를 사용한다.
|
- core 는 슬롯/capacity 의 권위 단일 writer(불변식 A) — slot overlay 는 이 권위 상태를 사용한다.
|
||||||
|
- transport 종속성 — 스냅샷 read 의 전달은 dcy-006(confirmed)의 RabbitMQ request-reply RPC 를 사용한다(HTTP 아님). 본 Discovery 는 logical 계약만 정의하고 transport 세부(토폴로지·delivery)는 dcy-006 소관이다.
|
||||||
|
|
||||||
## 주요 사용자 시나리오
|
## 주요 사용자 시나리오
|
||||||
사용자 또는 운영자가 실제로 어떤 상황에서 이 변경을 필요로 하는지 대표 시나리오를 적는다.
|
사용자 또는 운영자가 실제로 어떤 상황에서 이 변경을 필요로 하는지 대표 시나리오를 적는다.
|
||||||
@@ -64,17 +66,18 @@
|
|||||||
- portfolio-hub read 포트 + 어댑터: `PortfolioHubReadPort.get_portfolios(daemon_id)` 추상화 + portfolio-hub 어댑터(`managed_by_daemon_id` 로 daemon universe 조회, dcy-004 어댑터/자격증명 재사용) + 결정론 stub. 전략파라미터는 trex-core 가 해석하지 않는 opaque JSON 으로 운반한다.
|
- portfolio-hub read 포트 + 어댑터: `PortfolioHubReadPort.get_portfolios(daemon_id)` 추상화 + portfolio-hub 어댑터(`managed_by_daemon_id` 로 daemon universe 조회, dcy-004 어댑터/자격증명 재사용) + 결정론 stub. 전략파라미터는 trex-core 가 해석하지 않는 opaque JSON 으로 운반한다.
|
||||||
- 일일 스냅샷 갱신: 설정 시각(기본 07:30 KST, .env)에 스케줄러(신규 daemon 컴포넌트)가 universe 를 페치해 스냅샷을 갱신한다. 현금/포지션은 baseline 에 더해, 체결 시 portfolio-hub ledger write 응답이 반환하는 변경 후 권위 cash/position 으로 갱신한다(옵션 D — 당초 옵션 C 의 core 로컬 체결 replay 보정을 대체).
|
- 일일 스냅샷 갱신: 설정 시각(기본 07:30 KST, .env)에 스케줄러(신규 daemon 컴포넌트)가 universe 를 페치해 스냅샷을 갱신한다. 현금/포지션은 baseline 에 더해, 체결 시 portfolio-hub ledger write 응답이 반환하는 변경 후 권위 cash/position 으로 갱신한다(옵션 D — 당초 옵션 C 의 core 로컬 체결 replay 보정을 대체).
|
||||||
- 포지션 정합 검증 + warning: 페치 시 portfolio-hub 포지션 vs 실제 브로커 계좌 포지션을 대조하고, 불일치 자산은 `warning` 상태로 응답 리스트에서 마스킹한다.
|
- 포지션 정합 검증 + warning: 페치 시 portfolio-hub 포지션 vs 실제 브로커 계좌 포지션을 대조하고, 불일치 자산은 `warning` 상태로 응답 리스트에서 마스킹한다.
|
||||||
- 종목 스냅샷 read API: trex-core 가 보유 스냅샷을 read 엔드포인트로 제공하고, **holding 포함·pending·warning·pause 마스킹**한 전략 실행 대상 자산 리스트를 반환한다(slot overlay, OQ-4).
|
- 종목 스냅샷 read 계약: trex-core 가 보유 스냅샷을 read 계약(요청-응답, transport 는 dcy-006 RabbitMQ RPC)으로 제공하고, **holding 포함·pending·warning·pause 마스킹**한 전략 실행 대상 자산 리스트를 반환한다(slot overlay, OQ-4).
|
||||||
- 전략 ID 필터: read 엔드포인트가 선택적 `strategy_id` 파라미터를 받아, 주어지면 해당 전략 ID 가 등록된(= `active_strategy_id` 일치) 자산만 반환하고, 없으면 (pending·warning·pause 마스킹 후) 모든 자산을 반환한다. 전략 ID 의 식별자 형태("이름?")와 "등록" 판정 기준은 OQ-9.
|
- 전략 ID 필터: 스냅샷 read 요청이 선택적 `strategy_id` 파라미터(요청 payload, dcy-006 OQ-2)를 받아, 주어지면 해당 전략 ID 가 등록된(= `active_strategy_id` 일치) 자산만 반환하고, 없으면 (pending·warning·pause 마스킹 후) 모든 자산을 반환한다. 전략 ID 의 식별자 형태("이름?")와 "등록" 판정 기준은 OQ-9.
|
||||||
- 런타임 pause/resume: trex-core 가 보유한 스냅샷 universe 의 개별 항목을 사용자가 런타임에 일시 중단(pause)/재개(resume)할 수 있고, pause 된 항목은 전략 모듈의 포트폴리오 요청 결과에서 제외한다. pause 단위·제어 방식·영속성은 OQ-10.
|
- 런타임 pause/resume: trex-core 가 보유한 스냅샷 universe 의 개별 항목을 사용자가 런타임에 일시 중단(pause)/재개(resume)할 수 있고, pause 된 항목은 전략 모듈의 포트폴리오 요청 결과에서 제외한다. pause 단위·제어 방식·영속성은 OQ-10.
|
||||||
- capacity 0 응답 시맨틱: 가용 슬롯이 0 일 때의 응답은 holding 포함 변경에 맞춰 재정의한다(OQ-11; 빈/표현 형식은 OQ-6).
|
- capacity 0 응답 시맨틱: 가용 슬롯이 0 일 때의 응답은 holding 포함 변경에 맞춰 재정의한다(OQ-11; 빈/표현 형식은 OQ-6).
|
||||||
- baseline 갱신: interface-contract(read 포트/엔드포인트)·runtime-flows(스냅샷 조회 흐름)·project-structure(read 어댑터) 갱신.
|
- baseline 갱신: interface-contract(read 포트/메시지 계약)·runtime-flows(스냅샷 조회 흐름, RabbitMQ RPC)·project-structure(read 어댑터) 갱신. (dcy-006 의 transport baseline 갱신과 정합.)
|
||||||
|
|
||||||
## 영향 범위
|
## 영향 범위
|
||||||
변경이 미칠 코드/문서/운영 범위를 명시해 REQ 정제와 batch planning에서 추정 누락을 줄인다.
|
변경이 미칠 코드/문서/운영 범위를 명시해 REQ 정제와 batch planning에서 추정 누락을 줄인다.
|
||||||
|
|
||||||
- 코드 영향:
|
- 코드 영향:
|
||||||
- 신규: `trex_core/application` read 포트, 신규 `adapters/portfolio` read 어댑터 + stub, `trex_core/adapters/api` 스냅샷 read 엔드포인트 + 응답 스키마, slot overlay(점유 종목 제외) + 현금/포지션 write-응답 갱신 로직(`cash_balance_after`/`asset_quantity_after`, 옵션 D), 일일 스냅샷 스케줄러(런타임 신규), 포지션 정합 검증 + `warning` 상태, `config` 에 `daemon_id` + 스냅샷 페치 시각 주입, `strategy_id` 필터(쿼리 파라미터 → `active_strategy_id` 매칭), 스냅샷 항목 pause/resume 상태 저장 + 제어 표면(제어 API/CLI) + 응답 산출 시 pause 마스킹.
|
- 신규: `trex_core/application` read 포트, 신규 `adapters/portfolio` read 어댑터 + stub, 스냅샷 read 를 dcy-006 messaging transport(RabbitMQ RPC, `adapters/messaging`)로 노출 + 응답 스키마(transport-무관), slot overlay(점유 종목 제외) + 현금/포지션 write-응답 갱신 로직(`cash_balance_after`/`asset_quantity_after`, 옵션 D), 일일 스냅샷 스케줄러(런타임 신규), 포지션 정합 검증 + `warning` 상태, `config` 에 `daemon_id` + 스냅샷 페치 시각 주입, `strategy_id` 필터(요청 payload → `active_strategy_id` 매칭), 스냅샷 항목 pause/resume 상태 저장 + 제어 표면(제어 메시지/CLI) + 응답 산출 시 pause 마스킹.
|
||||||
|
- (주의: dcy-006 가 `adapters/api` HTTP 어댑터를 제거하므로, 스냅샷 read 는 신규 HTTP 엔드포인트가 아니라 dcy-006 의 RPC consumer 로 구현한다.)
|
||||||
- 기존: capacity/slot 조회 재사용(점유 종목·가용 슬롯 판정), 브로커 계좌 포지션 조회(BrokerPort 잔고조회 — 정합 검증용) 재사용/확장.
|
- 기존: capacity/slot 조회 재사용(점유 종목·가용 슬롯 판정), 브로커 계좌 포지션 조회(BrokerPort 잔고조회 — 정합 검증용) 재사용/확장.
|
||||||
- 문서 영향:
|
- 문서 영향:
|
||||||
- interface-contract/runtime-flows/project-structure 갱신.
|
- interface-contract/runtime-flows/project-structure 갱신.
|
||||||
@@ -85,14 +88,14 @@
|
|||||||
실제로 구현과 검증으로 이어질 요구사항을 기능/비기능으로 나누어 정리하고, 범위 경계를 명확히 적는다.
|
실제로 구현과 검증으로 이어질 요구사항을 기능/비기능으로 나누어 정리하고, 범위 경계를 명확히 적는다.
|
||||||
|
|
||||||
## 기능 요구사항
|
## 기능 요구사항
|
||||||
- FR-1: trex-core 가 종목 스냅샷을 read API 엔드포인트로 제공한다(GET, 매수 전략 모듈이 HTTP 로 소비). 스냅샷 단위는 daemon 이 관리하는 portfolio universe 이며, 항목당 symbol, asset_id(=portfolio_id), 현금(cash_balance), 포지션(asset_quantity), active_strategy_id, 전략파라미터(opaque JSON)를 담고 가격(price)은 제외한다. (OQ-1 Answered)
|
- FR-1: trex-core 가 종목 스냅샷을 read 계약(요청-응답)으로 제공한다. transport 는 dcy-006 의 RabbitMQ request-reply RPC 이며(HTTP 아님), 매수 전략 모듈이 메시지로 소비한다. 스냅샷 단위는 daemon 이 관리하는 portfolio universe 이며, 항목당 symbol, asset_id(=portfolio_id), 현금(cash_balance), 포지션(asset_quantity), active_strategy_id, 전략파라미터(opaque JSON)를 담고 가격(price)은 제외한다. (OQ-1 Answered)
|
||||||
- FR-2: 스냅샷 응답(전략 실행 대상 portfolio 자산 리스트)은 **portfolio-hub 에 보유된 자산을 기본 포함하며, holding 슬롯의 자산도 포함**한다(전략 모듈이 보유 포지션까지 받아 관리). 단 다음 상태의 자산은 **마스킹**하여 응답에서 제외한다: (a) 슬롯 상태 pending(미체결 in-flight), (b) 자산 상태 warning(브로커 실제 position 불일치, FR-7), (c) 사용자 pause(FR-9). 포함/마스킹 판정은 core 권위 슬롯 상태 + 정합 검증 + pause 상태를 사용하며 portfolio-hub 보유 여부보다 우선한다(slot overlay). 본 조항은 기본(default) view 의 구성 규칙이며, 응답 베이스 집합은 요청 view 모드 파라미터(OQ-11/OQ-12)로 선택될 수 있고 마스킹은 선택된 베이스 위에 적용된다. (변경 2026-06-05, OQ-4 결정: 종전 'pending·holding 점유 종목 제외, 매수 후보 리스트' → 'holding 포함, pending·warning·pause 만 마스킹'.)
|
- FR-2: 스냅샷 응답(전략 실행 대상 portfolio 자산 리스트)은 **portfolio-hub 에 보유된 자산을 기본 포함하며, holding 슬롯의 자산도 포함**한다(전략 모듈이 보유 포지션까지 받아 관리). 단 다음 상태의 자산은 **마스킹**하여 응답에서 제외한다: (a) 슬롯 상태 pending(미체결 in-flight), (b) 자산 상태 warning(브로커 실제 position 불일치, FR-7), (c) 사용자 pause(FR-9). 포함/마스킹 판정은 core 권위 슬롯 상태 + 정합 검증 + pause 상태를 사용하며 portfolio-hub 보유 여부보다 우선한다(slot overlay). 본 조항은 기본(default) view 의 구성 규칙이며, 응답 베이스 집합은 요청 view 모드 파라미터(OQ-11/OQ-12)로 선택될 수 있고 마스킹은 선택된 베이스 위에 적용된다. (변경 2026-06-05, OQ-4 결정: 종전 'pending·holding 점유 종목 제외, 매수 후보 리스트' → 'holding 포함, pending·warning·pause 만 마스킹'.)
|
||||||
- FR-3: 가용 슬롯이 0(capacity 소진)일 때의 응답은 **고정값이 아니라 전략 모듈이 요청 시 지정하는 view 모드 파라미터**에 따른다(OQ-11 결정). 최소 3개 모드: (a) 빈 리스트 `[]`, (b) 슬롯 점유 자산만, (c) portfolio 스냅샷 − 슬롯 점유 자산. 파라미터 이름/enum·기본 모드·마스킹(OQ-4)·strategy_id 필터(FR-8)와의 합성은 OQ-12, 빈/표현 형식은 OQ-6 에서 확정한다. (종전 'capacity 0 → 매수 후보 빈 리스트'는 OQ-4 holding 포함 + 본 결정으로 대체.)
|
- FR-3: 가용 슬롯이 0(capacity 소진)일 때의 응답은 **고정값이 아니라 전략 모듈이 요청 시 지정하는 view 모드 파라미터**에 따른다(OQ-11 결정). 최소 3개 모드: (a) 빈 리스트 `[]`, (b) 슬롯 점유 자산만, (c) portfolio 스냅샷 − 슬롯 점유 자산. 파라미터 이름/enum·기본 모드·마스킹(OQ-4)·strategy_id 필터(FR-8)와의 합성은 OQ-12, 빈/표현 형식은 OQ-6 에서 확정한다. (종전 'capacity 0 → 매수 후보 빈 리스트'는 OQ-4 holding 포함 + 본 결정으로 대체.)
|
||||||
- FR-4: portfolio-hub read 접근을 `PortfolioHubReadPort.get_portfolios(daemon_id)` 추상화 + portfolio-hub 어댑터(`managed_by_daemon_id` 기준) + 결정론 stub 로 제공하고, dcy-004 의 portfolio-hub 어댑터/자격증명을 재사용한다. 전략파라미터는 opaque JSON 으로 통과시킨다(trex-core 가 스키마를 해석하지 않음).
|
- FR-4: portfolio-hub read 접근을 `PortfolioHubReadPort.get_portfolios(daemon_id)` 추상화 + portfolio-hub 어댑터(`managed_by_daemon_id` 기준) + 결정론 stub 로 제공하고, dcy-004 의 portfolio-hub 어댑터/자격증명을 재사용한다. 전략파라미터는 opaque JSON 으로 통과시킨다(trex-core 가 스키마를 해석하지 않음).
|
||||||
- FR-5: baseline 문서(interface-contract/runtime-flows/project-structure)를 read 포트·스냅샷 엔드포인트·read 어댑터·일일 스케줄러에 맞게 갱신한다.
|
- FR-5: baseline 문서(interface-contract/runtime-flows/project-structure)를 read 포트·스냅샷 read 계약(RabbitMQ RPC)·read 어댑터·일일 스케줄러에 맞게 갱신한다(dcy-006 transport baseline 과 정합).
|
||||||
- FR-6: trex-core daemon 이 설정 가능한 시각(기본 07:30 KST, .env 로 지정)에 일일 스케줄로 `daemon_id` universe 를 페치해 스냅샷을 보유한다. universe 멤버십·전략파라미터는 일일 스냅샷으로 고정하고, 현금/포지션은 스냅샷 baseline 에 더해 **체결 시 portfolio-hub ledger write 응답의 `cash_balance_after` / `asset_quantity_after` 권위 값으로 갱신한다(옵션 D)**. (포지션/현금의 ground truth 는 portfolio-hub 이며 응답값으로 덮어써 로컬 누적 보정 drift 를 제거. portfolio-hub 가 ledger write 를 회계 단일 권위로 단일 트랜잭션 처리하고 `*_after` 를 반환하기로 확정 — A-7, portfolio-hub#8. portfolio-hub 배포(REL-003 등) 시점까지 구현 대기.)
|
- FR-6: trex-core daemon 이 설정 가능한 시각(기본 07:30 KST, .env 로 지정)에 일일 스케줄로 `daemon_id` universe 를 페치해 스냅샷을 보유한다. universe 멤버십·전략파라미터는 일일 스냅샷으로 고정하고, 현금/포지션은 스냅샷 baseline 에 더해 **체결 시 portfolio-hub ledger write 응답의 `cash_balance_after` / `asset_quantity_after` 권위 값으로 갱신한다(옵션 D)**. (포지션/현금의 ground truth 는 portfolio-hub 이며 응답값으로 덮어써 로컬 누적 보정 drift 를 제거. portfolio-hub 가 ledger write 를 회계 단일 권위로 단일 트랜잭션 처리하고 `*_after` 를 반환하기로 확정 — A-7, portfolio-hub#8. portfolio-hub 배포(REL-003 등) 시점까지 구현 대기.)
|
||||||
- FR-7: 스냅샷 페치 시 각 portfolio 의 portfolio-hub 포지션과 실제 브로커 계좌 포지션이 일치하는지 검증한다. 불일치하는 자산은 `warning` 상태로 표시하고 응답 리스트에서 마스킹해 해당 자산에 매매 전략을 수행하지 않는다.
|
- FR-7: 스냅샷 페치 시 각 portfolio 의 portfolio-hub 포지션과 실제 브로커 계좌 포지션이 일치하는지 검증한다. 불일치하는 자산은 `warning` 상태로 표시하고 응답 리스트에서 마스킹해 해당 자산에 매매 전략을 수행하지 않는다.
|
||||||
- FR-8: 스냅샷 read API 는 선택적 `strategy_id` 파라미터를 받는다. `strategy_id` 가 주어지면 해당 전략 ID 가 등록된(= 자산의 `active_strategy_id` 와 일치) 자산만 응답 리스트에 포함하고, `strategy_id` 가 없으면 (pending·warning·pause 마스킹 후) 모든 자산을 반환한다. 여러 전략 모듈이 같은 스냅샷 API 를 공유하되 각자 자기 책임 자산만 받는다. 전략 ID 의 식별자 형태(ID vs 이름)와 "등록" 판정 기준(단일 `active_strategy_id` 일치 vs 다중 등록)은 OQ-9.
|
- FR-8: 스냅샷 read 요청은 선택적 `strategy_id` 파라미터(요청 payload, dcy-006 OQ-2 매핑)를 받는다. `strategy_id` 가 주어지면 해당 전략 ID 가 등록된(= 자산의 `active_strategy_id` 와 일치) 자산만 응답 리스트에 포함하고, `strategy_id` 가 없으면 (pending·warning·pause 마스킹 후) 모든 자산을 반환한다. 여러 전략 모듈이 같은 스냅샷 API 를 공유하되 각자 자기 책임 자산만 받는다. 전략 ID 의 식별자 형태(ID vs 이름)와 "등록" 판정 기준(단일 `active_strategy_id` 일치 vs 다중 등록)은 OQ-9.
|
||||||
- FR-9: trex-core 가 보유한 스냅샷 universe 의 개별 항목을 사용자가 런타임에 일시 중단(pause)/재개(resume)할 수 있다. pause 된 항목은 전략 모듈의 포트폴리오 요청 결과(FR-2)에서 제외한다. 응답 리스트는 holding 포함을 기본으로 (pending 마스킹) ∧ (warning 마스킹) ∧ (pause 마스킹) ∧ (strategy_id 필터, 주어진 경우)의 합성으로 산출된다. pause 단위(portfolio/asset/symbol), 제어 방식(제어 API vs CLI vs config), 영속성(스냅샷 갱신·daemon 재시작 후 유지 여부), 전략별 vs 전역 적용은 OQ-10.
|
- FR-9: trex-core 가 보유한 스냅샷 universe 의 개별 항목을 사용자가 런타임에 일시 중단(pause)/재개(resume)할 수 있다. pause 된 항목은 전략 모듈의 포트폴리오 요청 결과(FR-2)에서 제외한다. 응답 리스트는 holding 포함을 기본으로 (pending 마스킹) ∧ (warning 마스킹) ∧ (pause 마스킹) ∧ (strategy_id 필터, 주어진 경우)의 합성으로 산출된다. pause 단위(portfolio/asset/symbol), 제어 방식(제어 API vs CLI vs config), 영속성(스냅샷 갱신·daemon 재시작 후 유지 여부), 전략별 vs 전역 적용은 OQ-10.
|
||||||
|
|
||||||
## 비기능 요구사항
|
## 비기능 요구사항
|
||||||
@@ -132,7 +135,7 @@
|
|||||||
|
|
||||||
- A-1: portfolio-hub 는 daemon 인증(`auth_tokens.daemon_id`)으로 자신이 관리하는 portfolio 집합을 조회하는 read 계약을 제공한다. (근거: portfolio-hub `app/api/v1_portfolios.py`·`v1_user_info.py` 의 `auth.daemon_id` 스코프)
|
- A-1: portfolio-hub 는 daemon 인증(`auth_tokens.daemon_id`)으로 자신이 관리하는 portfolio 집합을 조회하는 read 계약을 제공한다. (근거: portfolio-hub `app/api/v1_portfolios.py`·`v1_user_info.py` 의 `auth.daemon_id` 스코프)
|
||||||
- A-2: trex-core 는 슬롯/capacity 의 권위 단일 소스이며, 점유 종목·가용 슬롯 판정에 자기 상태를 사용할 수 있다.
|
- A-2: trex-core 는 슬롯/capacity 의 권위 단일 소스이며, 점유 종목·가용 슬롯 판정에 자기 상태를 사용할 수 있다.
|
||||||
- A-3: 매수 전략 모듈은 trex-core 외부 소비자이며 HTTP 로 스냅샷을 받는다.
|
- A-3: 매수 전략 모듈은 trex-core 외부 소비자이며 dcy-006 transport(RabbitMQ request-reply RPC)로 스냅샷을 받는다(HTTP 아님). logical 계약(필드/마스킹/view 모드/strategy_id)은 transport-무관.
|
||||||
- A-4: dcy-004 의 portfolio-hub 어댑터/자격증명(.env `TREX_PORTFOLIO_HUB_*`)을 read 방향에서도 재사용한다.
|
- A-4: dcy-004 의 portfolio-hub 어댑터/자격증명(.env `TREX_PORTFOLIO_HUB_*`)을 read 방향에서도 재사용한다.
|
||||||
- A-5: portfolio-hub 의 `daemon` 은 1급 엔티티이며 portfolio 가 `managed_by_daemon_id` 로 daemon 에 귀속된다(1 daemon : N portfolio, 각 portfolio ≈ 1 asset, asset_id == portfolio_id). 전략파라미터는 portfolio-hub 가 `strategy_params` JSONB 로 보관한다. trex-core daemon 의 universe = 자신이 관리하는 portfolio 집합이다. (근거: portfolio-hub `app/domain/models.py` Daemon/Portfolio, `strategy_params` JSONB migration)
|
- A-5: portfolio-hub 의 `daemon` 은 1급 엔티티이며 portfolio 가 `managed_by_daemon_id` 로 daemon 에 귀속된다(1 daemon : N portfolio, 각 portfolio ≈ 1 asset, asset_id == portfolio_id). 전략파라미터는 portfolio-hub 가 `strategy_params` JSONB 로 보관한다. trex-core daemon 의 universe = 자신이 관리하는 portfolio 집합이다. (근거: portfolio-hub `app/domain/models.py` Daemon/Portfolio, `strategy_params` JSONB migration)
|
||||||
- A-6: 이 trex-core daemon 은 자신이 관리하는 portfolio 의 유일한 매매 주체이며, 장중 거래 외 현금 변동(입출금)은 없다. 따라서 일일 baseline + 체결 시 portfolio-hub write 응답 갱신으로 현금/포지션을 정확히 유지할 수 있다(옵션 D 전제). (사용자 확인 2026-06-04)
|
- A-6: 이 trex-core daemon 은 자신이 관리하는 portfolio 의 유일한 매매 주체이며, 장중 거래 외 현금 변동(입출금)은 없다. 따라서 일일 baseline + 체결 시 portfolio-hub write 응답 갱신으로 현금/포지션을 정확히 유지할 수 있다(옵션 D 전제). (사용자 확인 2026-06-04)
|
||||||
@@ -164,7 +167,7 @@
|
|||||||
- 종료 조건: degrade 동작이 NFR-3/R-3 에 반영되면 Answered.
|
- 종료 조건: degrade 동작이 NFR-3/R-3 에 반영되면 Answered.
|
||||||
- OQ-6: 빈 리스트 표현 시맨틱 — 응답 리스트가 비었을 때 빈 배열(`[]`)을 반환하는가, null 을 반환하는가, 별도 메타 필드(예: `available_slots: 0`)로 신호하는가?
|
- OQ-6: 빈 리스트 표현 시맨틱 — 응답 리스트가 비었을 때 빈 배열(`[]`)을 반환하는가, null 을 반환하는가, 별도 메타 필드(예: `available_slots: 0`)로 신호하는가?
|
||||||
- 상태: Open
|
- 상태: Open
|
||||||
- 처리 방안: 매수 전략 모듈 소비 계약에 맞춰 결정(REST 관례상 빈 배열 + 메타 필드 권장안 검토).
|
- 처리 방안: 매수 전략 모듈 소비 계약에 맞춰 결정(메시지 응답 관례상 빈 배열 + 메타 필드 권장안 검토).
|
||||||
- 종료 조건: 표현 방식이 FR-3 에 반영되면 Answered.
|
- 종료 조건: 표현 방식이 FR-3 에 반영되면 Answered.
|
||||||
- OQ-7: trex-core daemon 의 `daemon_id` 주입 방식 — .env 설정값으로 직접 주입하는가, portfolio-hub 인증 토큰(`auth_tokens.daemon_id`)에서 도출하는가?
|
- OQ-7: trex-core daemon 의 `daemon_id` 주입 방식 — .env 설정값으로 직접 주입하는가, portfolio-hub 인증 토큰(`auth_tokens.daemon_id`)에서 도출하는가?
|
||||||
- 상태: Open
|
- 상태: Open
|
||||||
@@ -178,7 +181,7 @@
|
|||||||
- 상태: Open
|
- 상태: Open
|
||||||
- 처리 방안: 운영자/전략 모듈 계약 확인. 1차안은 안정적 `strategy_id` 식별자 + 단일 `active_strategy_id` 동등 비교. 다중 등록이 필요하면 등록 목록 필드 도입 검토.
|
- 처리 방안: 운영자/전략 모듈 계약 확인. 1차안은 안정적 `strategy_id` 식별자 + 단일 `active_strategy_id` 동등 비교. 다중 등록이 필요하면 등록 목록 필드 도입 검토.
|
||||||
- 종료 조건: 식별자 형태와 등록 판정 기준이 FR-8 에 반영되면 Answered.
|
- 종료 조건: 식별자 형태와 등록 판정 기준이 FR-8 에 반영되면 Answered.
|
||||||
- OQ-10: 런타임 pause/resume 메커니즘 — pause 단위(portfolio/asset/symbol), 제어 방식(전용 제어 API 엔드포인트 vs CLI vs config 리로드), 영속성(스냅샷 일일 갱신·daemon 재시작 후 pause 유지 여부와 저장소), 적용 범위(전역 vs 특정 전략 요청에만), resume 시 즉시 응답 복귀 규칙.
|
- OQ-10: 런타임 pause/resume 메커니즘 — pause 단위(portfolio/asset/symbol), 제어 방식(전용 제어 메시지(dcy-006 RPC) vs CLI vs config 리로드), 영속성(스냅샷 일일 갱신·daemon 재시작 후 pause 유지 여부와 저장소), 적용 범위(전역 vs 특정 전략 요청에만), resume 시 즉시 응답 복귀 규칙.
|
||||||
- 상태: Open
|
- 상태: Open
|
||||||
- 처리 방안: 운영자 결정. 1차안은 자산(=portfolio_id) 단위 pause + 제어 API + Postgres 영속(재시작·일일 갱신 후 유지) + 전역 적용. 사용 시나리오(운영 중 특정 종목만 일시 정지)에 맞춰 확정.
|
- 처리 방안: 운영자 결정. 1차안은 자산(=portfolio_id) 단위 pause + 제어 API + Postgres 영속(재시작·일일 갱신 후 유지) + 전역 적용. 사용 시나리오(운영 중 특정 종목만 일시 정지)에 맞춰 확정.
|
||||||
- 종료 조건: pause 단위·제어 방식·영속성·적용 범위가 FR-9 에 반영되면 Answered.
|
- 종료 조건: pause 단위·제어 방식·영속성·적용 범위가 FR-9 에 반영되면 Answered.
|
||||||
@@ -189,7 +192,7 @@
|
|||||||
- 잔여(→ OQ-12): 파라미터 이름/enum 값, 기본 모드(생략 시), 각 모드와 마스킹(pending·warning·pause, OQ-4)·strategy_id 필터의 합성 규칙, capacity 신호 메타 필드(OQ-6) 동반 여부.
|
- 잔여(→ OQ-12): 파라미터 이름/enum 값, 기본 모드(생략 시), 각 모드와 마스킹(pending·warning·pause, OQ-4)·strategy_id 필터의 합성 규칙, capacity 신호 메타 필드(OQ-6) 동반 여부.
|
||||||
- OQ-12: 응답 view/scope 파라미터 설계 — OQ-11 의 모드 선택을 어떤 요청 파라미터로 노출하는가.
|
- OQ-12: 응답 view/scope 파라미터 설계 — OQ-11 의 모드 선택을 어떤 요청 파라미터로 노출하는가.
|
||||||
- 상태: Open
|
- 상태: Open
|
||||||
- 처리 방안: 전략 모듈 소비 계약에 맞춰 결정. 정의 대상: (1) 파라미터 이름·enum(예: `view=buyable|held|remainder|all`), (2) 생략 시 기본 모드, (3) 각 모드 베이스 집합에 OQ-4 마스킹(pending·warning·pause)과 FR-8 strategy_id 필터를 어떻게 합성하는지(특히 'held' 모드에서 pending 포함 여부), (4) capacity 가용성 메타 필드(OQ-6) 동반 여부. 매수/매도/position 전략 구분(trex-core#1)과도 연계 — view 모드가 전략 타입별 뷰를 제공.
|
- 처리 방안: 전략 모듈 소비 계약에 맞춰 결정. 정의 대상: (1) 요청 파라미터 이름·enum(예: `view` = buyable|held|remainder|all, 요청 payload — dcy-006 OQ-2 매핑), (2) 생략 시 기본 모드, (3) 각 모드 베이스 집합에 OQ-4 마스킹(pending·warning·pause)과 FR-8 strategy_id 필터를 어떻게 합성하는지(특히 'held' 모드에서 pending 포함 여부), (4) capacity 가용성 메타 필드(OQ-6) 동반 여부. 매수/매도/position 전략 구분(trex-core#1)과도 연계 — view 모드가 전략 타입별 뷰를 제공.
|
||||||
- 종료 조건: 파라미터 스펙·기본 모드·합성 규칙이 FR-2/FR-3/FR-8 에 반영되면 Answered.
|
- 종료 조건: 파라미터 스펙·기본 모드·합성 규칙이 FR-2/FR-3/FR-8 에 반영되면 Answered.
|
||||||
|
|
||||||
### 오픈 질문 처리 기준
|
### 오픈 질문 처리 기준
|
||||||
@@ -220,7 +223,7 @@
|
|||||||
- S-2 측정 방식: 슬롯 holding/pending 진입 후 스냅샷 호출 테스트 / 데이터 출처: 응답 리스트(holding 포함·pending 마스킹) vs 슬롯 상태.
|
- S-2 측정 방식: 슬롯 holding/pending 진입 후 스냅샷 호출 테스트 / 데이터 출처: 응답 리스트(holding 포함·pending 마스킹) vs 슬롯 상태.
|
||||||
- S-3 측정 방식: 슬롯 소진(capacity 0) 후 스냅샷 호출 테스트 / 데이터 출처: 응답 리스트·capacity 신호 메타(OQ-11 확정안 기준).
|
- S-3 측정 방식: 슬롯 소진(capacity 0) 후 스냅샷 호출 테스트 / 데이터 출처: 응답 리스트·capacity 신호 메타(OQ-11 확정안 기준).
|
||||||
- S-4 측정 방식: 정적 import 스윕 / 데이터 출처: `trex_core/domain` import 목록.
|
- S-4 측정 방식: 정적 import 스윕 / 데이터 출처: `trex_core/domain` import 목록.
|
||||||
- S-5 측정 방식: 문서-코드 정합 점검(리뷰) / 데이터 출처: baseline 문서 vs 실제 엔드포인트/포트.
|
- S-5 측정 방식: 문서-코드 정합 점검(리뷰) / 데이터 출처: baseline 문서 vs 실제 메시지 계약(RPC)/read 포트.
|
||||||
- S-6 측정 방식: 포지션 불일치 주입 후 스냅샷 페치 테스트 / 데이터 출처: 자산 `warning` 상태·응답 리스트.
|
- S-6 측정 방식: 포지션 불일치 주입 후 스냅샷 페치 테스트 / 데이터 출처: 자산 `warning` 상태·응답 리스트.
|
||||||
- S-7 측정 방식: `strategy_id` 유/무 호출 비교 테스트 / 데이터 출처: 응답 리스트 vs 자산 `active_strategy_id`.
|
- S-7 측정 방식: `strategy_id` 유/무 호출 비교 테스트 / 데이터 출처: 응답 리스트 vs 자산 `active_strategy_id`.
|
||||||
- S-8 측정 방식: pause→호출→resume→호출 시퀀스 테스트 / 데이터 출처: 응답 리스트 포함/제외 여부.
|
- S-8 측정 방식: pause→호출→resume→호출 시퀀스 테스트 / 데이터 출처: 응답 리스트 포함/제외 여부.
|
||||||
@@ -246,6 +249,7 @@ REQ 초안 작성 단계로 넘기기 전에 무엇이 확정되어야 하는지
|
|||||||
- 생성 경로: docs/discovery/dcy-005_20260604_portfolio-hub-asset-snapshot-api.md
|
- 생성 경로: docs/discovery/dcy-005_20260604_portfolio-hub-asset-snapshot-api.md
|
||||||
- 참조 문서:
|
- 참조 문서:
|
||||||
- docs/discovery/dcy-004_20260604_portfolio-hub-ledger-integration.md (write 방향 — 본 Discovery 가 read 방향으로 이어받음)
|
- docs/discovery/dcy-004_20260604_portfolio-hub-ledger-integration.md (write 방향 — 본 Discovery 가 read 방향으로 이어받음)
|
||||||
|
- docs/discovery/dcy-006_20260605_strategy-module-rabbitmq-transport.md (confirmed — 스냅샷 read 의 전달 transport(RabbitMQ RPC, HTTP 0). 본 Discovery 는 logical 계약, dcy-006 은 transport)
|
||||||
- docs/interface-contract.md, docs/runtime-flows.md, docs/project-structure.md (baseline — 본 Discovery 가 갱신 요구)
|
- docs/interface-contract.md, docs/runtime-flows.md, docs/project-structure.md (baseline — 본 Discovery 가 갱신 요구)
|
||||||
- trex-orbit `app/clients/portfolio_client.py` (get_assets/get_portfolios read 계약 참고)
|
- trex-orbit `app/clients/portfolio_client.py` (get_assets/get_portfolios read 계약 참고)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
# req-021: messaging 토폴로지 + 메시지 계약 매핑
|
||||||
|
|
||||||
|
- Status: Proposed
|
||||||
|
- Type: Integration
|
||||||
|
- Priority: High
|
||||||
|
- Owner: project maintainers
|
||||||
|
|
||||||
|
## Intent
|
||||||
|
- trex-core ↔ 전략 모듈 통신을 RabbitMQ(AMQP) 메시지 기반으로 정의해, 스냅샷·intent admission 은 request-reply 로, 체결/슬롯 상태는 이벤트(pub/sub)로 전달한다. 기존 logical 계약(스냅샷 필드/마스킹/view 모드/strategy_id 필터, intent 스키마)은 transport-무관하게 보존하고 메시지 payload/속성/routing key 로 의미 손실 없이 매핑한다.
|
||||||
|
|
||||||
|
## Requirement
|
||||||
|
- 통신 토폴로지를 아래 3 패턴으로 확정한다(dcy-006 OQ-2).
|
||||||
|
1. 스냅샷 RPC(request-reply): 요청 queue `trex.snapshot.req`(direct/default exchange), 응답은 RabbitMQ direct reply-to(`amq.rabbitmq.reply-to`) + `correlation_id`. 요청 payload 에 `strategy_id` 와 `view` 모드(dcy-005 OQ-11/FR-8).
|
||||||
|
2. intent admission RPC(request-reply): 요청 queue `trex.intent.req`, 응답 = admission 결과(`status`, `slot_id`, `reason`). `correlation_id` = intent 멱등키(dcy-003 패턴) 로 RPC 상관과 dedup 일원화. 체결/종료(fill/close) 결과는 응답이 아니라 이벤트(③)로 전달해 admission 동기 + fill 비동기 2단계 시맨틱을 보존한다.
|
||||||
|
3. 이벤트 pub/sub: trex-core 가 체결·슬롯 상태 변화를 topic exchange `trex.events` 에 발행한다. routing key 는 `{event_type}.{strategy_id}.{symbol}` 형식이며, 전략 queue 는 `*.{strategy_id}.#` 패턴으로 바인딩해 자기 자산 이벤트만 수신한다(broker 단 필터).
|
||||||
|
- 매핑 원칙을 다음과 같이 고정한다: 요청 메시지(①·②) 의 `view` 모드와 `strategy_id` 는 message **payload** 에, 이벤트(③) 의 `strategy_id`·`symbol` 은 **routing key** 에 싣는다.
|
||||||
|
- 위 토폴로지/매핑은 transport-무관 logical 계약(스냅샷 필드/마스킹/view 모드/strategy_id, intent 스키마)을 변경하지 않는다.
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
1. Given trex-core daemon, When 기동, Then 스냅샷 RPC 요청 큐(`trex.snapshot.req`), intent RPC 요청 큐(`trex.intent.req`), 이벤트 토픽 익스체인지(`trex.events`)가 선언되어 있다.
|
||||||
|
2. Given stub/실 어댑터로 발행한 스냅샷 RPC 요청, When trex-core 가 응답, Then 응답 메시지가 HTTP 응답과 동일한 logical 필드(필드/마스킹/view 모드 적용)를 운반하고 `correlation_id` 가 요청과 일치한다.
|
||||||
|
3. Given intent admission RPC 요청 메시지, When trex-core 가 처리, Then 슬롯 전이 후 admission 응답(`status, slot_id?, reason?`)이 reply-to 큐로 반환되고 체결/종료는 응답이 아니라 후속 이벤트로 발행된다.
|
||||||
|
4. Given 동일 종목·이벤트가 전략 A 와 전략 B 의 queue 에 각각 `*.A.#`/`*.B.#` 패턴으로 바인딩된 상태, When trex-core 가 strategy_id=A 의 이벤트를 발행, Then A 의 queue 만 수신하고 B 의 queue 는 수신하지 않는다.
|
||||||
|
5. Given 요청 메시지, When 페이로드를 검사, Then `view`/`strategy_id` 가 payload 에 있고 routing key 에 들어가 있지 않다(요청 매핑 원칙).
|
||||||
|
|
||||||
|
## Impacted Area
|
||||||
|
- Docs: docs/interface-contract.md(메시지 계약), docs/runtime-flows.md(RPC/이벤트 흐름) — REQ-026 에서 정합.
|
||||||
|
- Modules: 신규 `trex_core/adapters/messaging/` 토폴로지 선언(exchange/queue/binding) 및 routing key 생성 로직.
|
||||||
|
- Tests: stub 어댑터로 RPC 요청-응답 매핑, 이벤트 routing key 바인딩 필터링, 요청/이벤트 매핑 원칙 검사.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
- 출처: dcy-006 FR-1, FR-2, OQ-2.
|
||||||
|
- 토폴로지 선언과 어댑터 구현 분리: 본 REQ 는 "무엇을/어떻게 매핑하나" 계약을 다루고, RabbitMQ 어댑터 + 런타임 통합 자체는 REQ-022 에서 다룬다.
|
||||||
|
- logical 계약(스냅샷 필드/마스킹/view 모드/strategy_id, intent 스키마)은 dcy-005/002/003 소관이며 본 REQ 가 변경하지 않는다.
|
||||||
|
- dcy-005 의 스냅샷 read 계약이 아직 REQ 로 정규화되지 않았으면 본 REQ 의 AC-2 검증은 stub 응답 셰이프 수준에서 시작하고, 정식 계약 확정 후 evidence 를 보강한다.
|
||||||
|
|
||||||
|
## Change Log
|
||||||
|
|
||||||
|
### CHG-20260605-01
|
||||||
|
- Date: 2026-06-05
|
||||||
|
- Author: Justin Ko
|
||||||
|
|
||||||
|
#### Change Summary
|
||||||
|
- dcy-006 FR-1/FR-2 로부터 최초 생성(Proposed). 통신 토폴로지(스냅샷 RPC + intent RPC + 이벤트 topic) 와 요청/이벤트 매핑 원칙(view·strategy_id payload, event routing key)을 backlog 로 정규화.
|
||||||
|
|
||||||
|
#### Intent
|
||||||
|
- transport 추상화의 메시지 계약과 토폴로지 결정을 별도 REQ 로 분리해 어댑터 구현(REQ-022) 및 신뢰성(REQ-023)과 독립 진척.
|
||||||
|
|
||||||
|
#### Acceptance Criteria Delta
|
||||||
|
- Added:
|
||||||
|
- 토폴로지 선언 4종, RPC 응답 매핑 1종, 이벤트 routing key 필터링 1종, 매핑 원칙 검사 1종 (총 5개 기준)
|
||||||
|
- Updated:
|
||||||
|
- 없음
|
||||||
|
- Removed:
|
||||||
|
- 없음
|
||||||
|
|
||||||
|
#### Impacted Area Delta
|
||||||
|
- Docs:
|
||||||
|
- docs/interface-contract.md, docs/runtime-flows.md
|
||||||
|
- Modules:
|
||||||
|
- adapters/messaging 토폴로지 선언
|
||||||
|
- Tests:
|
||||||
|
- RPC 요청-응답, 이벤트 routing key 필터링, 매핑 원칙 검사
|
||||||
|
|
||||||
|
#### Delivery Trace Delta
|
||||||
|
- Batches:
|
||||||
|
- none
|
||||||
|
- Releases:
|
||||||
|
- none
|
||||||
|
|
||||||
|
#### Revalidation Impact
|
||||||
|
- Reverification Needed: no
|
||||||
|
- Existing Implementation Invalidated: no
|
||||||
|
- Status Recommendation: keep-current
|
||||||
|
- Follow-up Action: confirm-req 후 batch 편성
|
||||||
|
|
||||||
|
#### Validation Plan
|
||||||
|
- stub 어댑터 통합테스트로 RPC 매핑·이벤트 routing key 필터링·매핑 원칙을 검증.
|
||||||
Reference in New Issue
Block a user