Deliver BAT-005: KIS token Redis cache (REQ-016, minor-change)

Port the trex-orbit Redis token-cache pattern so the KIS access token
survives daemon restarts and is shared across processes, avoiding KIS
token-issuance rate limits. KISBroker._ensure_token now resolves L1
in-memory -> L2 cache -> issue, storing issued tokens back to the cache.

- adapters/broker/token_cache.py: TokenCache protocol + RedisTokenCache
  (key trex:broker:kis:{account_ref}:token, token+expiry+app_key suffix
  JSON, ex=ttl, best-effort with graceful fallback) + InMemoryTokenCache.
- kis.py: optional token_cache injection.
- runtime config/daemon: TREX_KIS_REDIS_URL wires a RedisTokenCache.
- pyproject: redis>=5.

Verification: 96 passed, ruff clean — cache hit avoids issuance, cache is
shared across instances (restart/multi-process survival), backend errors
fall back to issuance (no regression), and app_key-suffix mismatch
invalidates a stale cache. Tested deterministically with an in-memory
double (no Redis server required). Processed via the minor-change fast
path: REQ-016 -> Implemented, BAT-005 (batch-lite) -> release-candidate.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-04 18:44:09 +09:00
co-authored by Claude Opus 4.8
parent 97d58318db
commit ac6061f510
13 changed files with 475 additions and 3 deletions
@@ -0,0 +1,153 @@
# req-016: KIS 인증 토큰 Redis 캐시
- Status: Implemented
- Type: Integration
- Priority: Medium
- Owner: project maintainers
## Intent
- KIS 접속 토큰을 Redis 에 캐시해 데몬 재기동·다중 프로세스에서도 토큰을 공유/생존시켜, KIS 토큰 발급 rate-limit(약 1회/분, EGW00133)을 피한다. trex-orbit 의 Redis 토큰 캐시 패턴을 trex-core 로 이식한다.
## Requirement
- KISBroker 에 선택적 토큰 캐시(`TokenCache`)를 주입한다. `_ensure_token` 은 ① 인메모리(L1) → ② Redis 캐시(L2, 키 `trex:broker:kis:{account_ref}:token`, 토큰+만료+app_key suffix JSON, `ex=ttl`) → ③ 신규 발급 순으로 해석한다. Redis 미설정/미설치/오류 시 기존 인메모리 동작으로 graceful fallback 한다. config 는 `TREX_KIS_REDIS_URL` 로 캐시를 활성화한다.
## Acceptance Criteria
1. Given Redis 캐시에 유효 토큰이 있음, When `_ensure_token`, Then HTTP 발급 없이 캐시 토큰을 사용한다.
2. Given 두 KISBroker 가 같은 캐시를 공유, When 하나가 발급·저장 후 다른 하나가 호출, Then 재발급 없이 캐시 토큰을 재사용한다(재기동/다중 프로세스 생존).
3. Given Redis 미설정/미설치/오류, When `_ensure_token`, Then 기존 인메모리 발급 동작으로 동작한다(회귀 없음).
4. Given 캐시된 토큰의 app_key suffix 가 현재와 불일치, When load, Then 캐시를 무시하고 재발급한다(자격증명 교체 안전).
## Impacted Area
- Docs: docs/interface-contract.md(KIS 어댑터 노트) — 필요 시
- Modules: trex_core/adapters/broker/token_cache.py(신규), kis.py(token_cache 주입), runtime/config.py(TREX_KIS_REDIS_URL), runtime/daemon.py(캐시 wiring), pyproject(redis 의존)
- Tests: tests/adapters/broker/test_token_cache.py (캐시 히트/공유/폴백/suffix)
## Notes
- minor-change: 기존 BrokerPort 뒤 토큰 캐시 계층 추가(외부 인터페이스/슬롯 흐름 변경 없음). batch-lite, design 불요.
- dcy-003 가 단일 인스턴스를 가정해 슬라이스에서 분산 캐시를 미포팅했던 갭의 후속 보완. 실 Redis 없을 때도 폴백으로 안전.
- 맥락: REQ-012(KIS 어댑터) 운영 견고성 개선.
## Change Log
### CHG-20260604-01
- Date: 2026-06-04
- Author: Justin Ko
#### Change Summary
- 최초 생성(Proposed) — KIS 토큰 Redis 캐시(재기동/다중프로세스 생존) Integration 요구사항.
#### Intent
- orbit Redis 토큰 캐시 패턴 이식으로 토큰 rate-limit·재발급 위험 완화.
#### Acceptance Criteria Delta
- Added:
- 캐시 히트, 공유 재사용, graceful fallback, app_key suffix 안전 4개 기준
- Updated:
- 없음
- Removed:
- 없음
#### Impacted Area Delta
- Docs:
- docs/interface-contract.md(필요 시)
- Modules:
- adapters/broker/token_cache.py, kis.py, runtime/config.py, runtime/daemon.py, pyproject
- Tests:
- tests/adapters/broker/test_token_cache.py
#### Delivery Trace Delta
- Batches:
- none
- Releases:
- none
#### Revalidation Impact
- Reverification Needed: no
- Existing Implementation Invalidated: no
- Status Recommendation: keep-current
- Follow-up Action: batch-lite 편성
#### Validation Plan
- 캐시 히트/공유/폴백/suffix 단위테스트(인메모리 캐시 더블)로 검증.
### CHG-20260604-02
- Date: 2026-06-04
- Author: Justin Ko
#### Change Summary
- Status Proposed → Approved (minor-change 저위험 단일 REQ, 외부 인터페이스/런타임 흐름 변경 없음).
#### Intent
- 승인 게이트 충족. batch-lite 로 즉시 delivery.
#### Acceptance Criteria Delta
- Added:
- 없음
- Updated:
- 없음
- Removed:
- 없음
#### Impacted Area Delta
- Docs:
- docs/srs/index.md (Register Approved)
- Modules:
- 없음
- Tests:
- 없음
#### Delivery Trace Delta
- Batches:
- none (batch-lite 편성 예정)
- Releases:
- none
#### Revalidation Impact
- Reverification Needed: no
- Existing Implementation Invalidated: no
- Status Recommendation: keep-current
- Follow-up Action: draft-batch 로 batch-lite 생성
#### Validation Plan
- batch-lite verification 에서 AC 검증.
### CHG-20260604-03
- Date: 2026-06-04
- Author: Justin Ko
#### Change Summary
- Status Approved → Implemented (confirm-req-implemented, 근거 batch BAT-005 release-candidate).
#### Intent
- BAT-005 verification 의 AC↔evidence(캐시 히트/공유/폴백/suffix, 96 pass)로 모든 AC 충족.
#### Acceptance Criteria Delta
- Added:
- 없음
- Updated:
- 없음
- Removed:
- 없음
#### Impacted Area Delta
- Docs:
- docs/srs/index.md (Register Implemented)
- Modules:
- 없음
- Tests:
- 없음
#### Delivery Trace Delta
- Batches:
- BAT-005 (release-candidate)
- Releases:
- none
#### Revalidation Impact
- Reverification Needed: no
- Existing Implementation Invalidated: no
- Status Recommendation: keep-current
- Follow-up Action: draft-release 로 release 편성
#### Validation Plan
- BAT-005 verification evidence 재참조로 충분.
+4 -3
View File
@@ -74,7 +74,7 @@
## Next Requirement ID
- Current: `REQ-016`
- Current: `REQ-017`
- Rule: `Requirement Register`에 있는 가장 큰 REQ 번호보다 정확히 1 커야 한다.
## Requirement Register
@@ -96,11 +96,12 @@
| REQ-013 | 주문 집행 루프 (claim·송신·체결·롤백) | Integration | Implemented | High | project maintainers | [req-013](./Integration/req-013_order-execution-loop.md) |
| REQ-014 | 주문 핸드오프 durability + reconciliation | Exception | Implemented | High | project maintainers | [req-014](./Exception/req-014_order-handoff-durability-reconciliation.md) |
| REQ-015 | 브로커/집행 baseline 문서 정합 | Documentation | Implemented | Medium | project maintainers | [req-015](./Documentation/req-015_broker-execution-baseline-alignment.md) |
| REQ-016 | KIS 인증 토큰 Redis 캐시 | Integration | Implemented | Medium | project maintainers | [req-016](./Integration/req-016_kis-token-redis-cache.md) |
## Recent Change Log Summary
- 2026-06-04 :: REQ-016 생성 + Approved — KIS 토큰 Redis 캐시 (minor-change). (draft-req/confirm-req)
- 2026-06-04 :: REQ-011~015 Approved → Implemented — BAT-004 verification evidence 기반. (confirm-req-implemented)
- 2026-06-04 :: REQ-011~015 Proposed → Approved — 승인 게이트 통과. (confirm-req)
- 2026-06-04 :: REQ-011~015 최초 생성(Proposed) — dcy-003 FR-1~FR-6 분해. (draft-req)
- 2026-06-04 :: REQ-010 Approved → Implemented — BAT-003 verification evidence 기반. (confirm-req-implemented)
- 2026-06-04 :: REQ-010 생성 + Approved — 데몬 .env 로딩 (minor-change). (draft-req/confirm-req)
- 2026-06-04 :: REQ-010 Approved → Implemented — BAT-003 verification evidence 기반. (confirm-req-implemented)