fix(chart): 10분봉 페이지네이션, 장외 캐시, 예측 horizon 캡 일치

reviewer 지적사항 반영:

1. KIS 분봉이 한 번에 30개만 와서 10분봉이 최대 3개만 나오던 문제 →
   fetch_minute_range() 추가. FID_INPUT_HOUR_1 을 30분씩 후퇴시키며
   페이지네이션, 중복 ts 자연 dedupe, max_pages=20 으로 무한루프 방지.
   _ensure_intraday_fresh 는 last_ts+1m ~ now 빈 구간만 채우므로 평소엔
   1~2 페이지로 끝남.

2. 장외/주말에 매번 KIS 를 때리던 문제 →
   - 주말: 'weekend' 반환, KIS 안 부름 (분봉 endpoint 는 당일만 지원)
   - 평일 장외 + 오늘 데이터 있음: 'cached_closed' 반환
   - 장중 + 10분 이내: 'fresh' 반환
   토큰/조회 제한 다시 밟지 않음.

3. 프론트 horizon 입력 60 vs 백엔드 30 불일치 →
   PredictionPanel 의 cap 을 30 으로 맞춤. 백엔드 predict.py 의 학습/검증
   범위와 일치. placeholder 도 '1~30' 으로 명시.
This commit is contained in:
claude-owner
2026-05-23 01:41:43 +09:00
parent 0a5c634680
commit e610599879
3 changed files with 101 additions and 18 deletions

View File

@@ -58,10 +58,12 @@ export function PredictionPanel({ code, initial, onResult }: Props) {
function effectiveHorizons(): number[] {
if (useCustom) {
// 백엔드 predict.py 가 1~30 만 허용 (모델 학습/검증 범위와 일치).
// 프론트에서 동일 cap 으로 끊어서 400 안 나게 한다.
const parsed = customRaw
.split(",")
.map((s) => Number(s.trim()))
.filter((n) => Number.isFinite(n) && n >= 1 && n <= 60);
.filter((n) => Number.isFinite(n) && n >= 1 && n <= 30);
if (parsed.length > 0) return Array.from(new Set(parsed)).sort((a, b) => a - b);
}
return HORIZON_PRESETS[presetIdx].value;
@@ -137,11 +139,11 @@ export function PredictionPanel({ code, initial, onResult }: Props) {
<input
type="text"
placeholder="예: 1,2,3,7"
placeholder="1~30, 예: 1,2,3,7"
value={customRaw}
onChange={(e) => setCustomRaw(e.target.value)}
onFocus={() => setUseCustom(true)}
className="ml-1 w-24 rounded border border-zinc-700 bg-zinc-900 px-1 py-0.5 text-xs text-zinc-100"
className="ml-1 w-28 rounded border border-zinc-700 bg-zinc-900 px-1 py-0.5 text-xs text-zinc-100"
/>
</label>
</div>