// 종목별 목표가/손절가 저장 (브라우저 한정 — 비로그인 앱). // // 키: `targets:` → { target?: number, stop?: number, savedAt: ISO } // 차트 오버레이 라인과 손익 미리보기에 사용. 알림 없음 (그건 AlertsPanel 담당). const PREFIX = "targets:"; export type Targets = { target?: number | null; // 익절가 (선택) stop?: number | null; // 손절가 (선택) savedAt?: string; }; export function readTargets(code: string): Targets { if (typeof window === "undefined") return {}; try { const raw = window.localStorage.getItem(`${PREFIX}${code}`); return raw ? (JSON.parse(raw) as Targets) : {}; } catch { return {}; } } export function writeTargets(code: string, t: Targets): void { if (typeof window === "undefined") return; // 둘 다 비어 있으면 키 자체를 지움 → 빈 객체 잔여물 제거. // 양수 유한값만 통과. UI 가 이미 가드하지만 lib 자체도 방어 — 외부에서 직접 호출돼도 안전. const cleaned: Targets = {}; if (t.target != null && Number.isFinite(t.target) && t.target > 0) cleaned.target = t.target; if (t.stop != null && Number.isFinite(t.stop) && t.stop > 0) cleaned.stop = t.stop; try { if (cleaned.target == null && cleaned.stop == null) { window.localStorage.removeItem(`${PREFIX}${code}`); return; } cleaned.savedAt = new Date().toISOString(); window.localStorage.setItem(`${PREFIX}${code}`, JSON.stringify(cleaned)); } catch { /* quota 초과 등 — 무시 */ } } export function clearTargets(code: string): void { if (typeof window === "undefined") return; try { window.localStorage.removeItem(`${PREFIX}${code}`); } catch { /* ignore */ } }