전략편집기 템플릿 저장 기능 추가

This commit is contained in:
Macbook
2026-06-11 23:24:29 +09:00
parent 05c15ec92b
commit eb6cf894da
9 changed files with 558 additions and 81 deletions
@@ -0,0 +1,66 @@
/** 전략편집기 — 사용자 저장 템플릿 (DB ui_preferences) */
import type { LogicNode } from './strategyTypes';
import type { EditorConditionState } from './strategyConditionSerde';
import { getUiPreferences, patchUiPreferences } from './uiPreferencesDb';
export type UserStrategyTemplate = {
id: string;
label: string;
description?: string;
signal: 'buy' | 'sell';
editorState: EditorConditionState;
orphans: LogicNode[];
createdAt: number;
};
function cloneJson<T>(value: T): T {
return JSON.parse(JSON.stringify(value)) as T;
}
export function createUserTemplateId(): string {
return `tmpl-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
}
function parseStored(raw: unknown): UserStrategyTemplate[] {
if (!Array.isArray(raw)) return [];
return raw.filter(
(t): t is UserStrategyTemplate =>
t != null
&& typeof t === 'object'
&& typeof (t as UserStrategyTemplate).id === 'string'
&& typeof (t as UserStrategyTemplate).label === 'string'
&& ((t as UserStrategyTemplate).signal === 'buy' || (t as UserStrategyTemplate).signal === 'sell')
&& typeof (t as UserStrategyTemplate).editorState === 'object'
&& Array.isArray((t as UserStrategyTemplate).orphans),
);
}
export function loadUserStrategyTemplates(): UserStrategyTemplate[] {
const raw = getUiPreferences().strategyEditor?.userTemplates;
return parseStored(raw);
}
export function saveUserStrategyTemplates(templates: UserStrategyTemplate[]): void {
patchUiPreferences({ strategyEditor: { userTemplates: templates } });
}
export function addUserStrategyTemplate(
input: Omit<UserStrategyTemplate, 'id' | 'createdAt'>,
): UserStrategyTemplate {
const next: UserStrategyTemplate = {
...input,
id: createUserTemplateId(),
editorState: cloneJson(input.editorState),
orphans: cloneJson(input.orphans),
createdAt: Date.now(),
};
const templates = [...loadUserStrategyTemplates(), next];
saveUserStrategyTemplates(templates);
return next;
}
export function deleteUserStrategyTemplate(id: string): UserStrategyTemplate[] {
const templates = loadUserStrategyTemplates().filter(t => t.id !== id);
saveUserStrategyTemplates(templates);
return templates;
}