import { loadStrategyTimeframes, pinCandleWatch, repairStrategyTimeframes, type StrategyDto } from './backendApi'; import { normalizeStartCandleType } from './strategyStartNodes'; import { collectUiEvaluationTimeframes, syncStrategyTimeframesFromLayoutIfNeeded } from './strategyTimeframeSync'; /** 전략 DSL 평가 분봉 전체 pin — 1m 집계·상위 봉 warm-up */ export async function pinStrategyEvaluationTimeframes( market: string, strategyId: number, ): Promise { const synced = await syncStrategyTimeframesFromLayoutIfNeeded(strategyId); if (!synced) return ['1m']; await repairStrategyTimeframes(strategyId); const raw = await loadStrategyTimeframes(strategyId); const timeframes = [...new Set(raw.map(tf => normalizeStartCandleType(tf)))]; if (timeframes.length === 0) timeframes.push('1m'); for (const tf of timeframes) { await pinCandleWatch(market, tf); } if (!timeframes.includes('1m')) { await pinCandleWatch(market, '1m'); } return timeframes; } /** 알림 목록 — DB sync/repair 없이 평가 분봉만 pin (서버 read-only 안전) */ export async function pinReadOnlyStrategyTimeframes( market: string, strategyId: number, strategy?: StrategyDto, ): Promise { let timeframes: string[] = []; try { timeframes = collectUiEvaluationTimeframes(strategyId, strategy); } catch { /* ignore */ } if (timeframes.length === 0) { try { const raw = await loadStrategyTimeframes(strategyId); timeframes = raw.length ? raw : ['1m']; } catch { timeframes = ['1m']; } } const unique = [...new Set(timeframes.map(tf => normalizeStartCandleType(tf)))]; if (!unique.includes('1m')) unique.unshift('1m'); for (const tf of unique) { await pinCandleWatch(market, tf); } }