// 종목별 사용자 메모 (브라우저 한정 — 비로그인 앱). // // 키: `notes:` → { text, updatedAt } // 투자 결정의 근거/관전 포인트를 짧게 적어두는 용도. 다른 사용자에게는 보이지 않음. const PREFIX = "notes:"; const MAX_LEN = 2000; // 너무 큰 입력 방어 — localStorage quota 보호. export type Note = { text: string; updatedAt: string; // ISO }; export function readNote(code: string): Note | null { if (typeof window === "undefined") return null; try { const raw = window.localStorage.getItem(`${PREFIX}${code}`); if (!raw) return null; const parsed = JSON.parse(raw) as Partial; if (typeof parsed.text !== "string" || typeof parsed.updatedAt !== "string") return null; return { text: parsed.text, updatedAt: parsed.updatedAt }; } catch { return null; } } export type WriteResult = | { status: "saved"; note: Note } | { status: "deleted" } | { status: "failed" }; export function writeNote(code: string, text: string): WriteResult { if (typeof window === "undefined") return { status: "failed" }; const trimmed = text.slice(0, MAX_LEN); // 공백만이면 키 자체 제거 → 빈 잔여물 방지. 의도된 삭제이므로 failed 와 구분. if (!trimmed.trim()) { clearNote(code); return { status: "deleted" }; } const next: Note = { text: trimmed, updatedAt: new Date().toISOString() }; try { window.localStorage.setItem(`${PREFIX}${code}`, JSON.stringify(next)); return { status: "saved", note: next }; } catch { return { status: "failed" }; // quota 등 — UI 가 저장 실패 처리 } } export function clearNote(code: string): void { if (typeof window === "undefined") return; try { window.localStorage.removeItem(`${PREFIX}${code}`); } catch { /* ignore */ } } export const NOTE_MAX_LEN = MAX_LEN;