검증게시판 단계 추가

This commit is contained in:
Macbook
2026-05-28 16:24:14 +09:00
parent f64dc1e983
commit 7e3644cb62
375 changed files with 4539 additions and 251294 deletions
@@ -3,6 +3,8 @@ export type VerificationIssueStage =
| 'REGISTERED'
| 'IN_FIX'
| 'FIX_COMPLETE'
| 'CONFIRM_REQUEST'
| 'RE_VERIFY_REQUEST'
| 'RE_REGISTERED'
| 'COMPLETE';
@@ -13,11 +15,13 @@ export interface VerificationIssueStageMeta {
}
export const VERIFICATION_ISSUE_STAGES: VerificationIssueStageMeta[] = [
{ value: 'REGISTERED', label: '등록', color: '#42a5f5' },
{ value: 'IN_FIX', label: '수정중', color: '#ffa726' },
{ value: 'FIX_COMPLETE', label: '수정완료', color: '#66bb6a' },
{ value: 'RE_REGISTERED', label: '재등록', color: '#ab47bc' },
{ value: 'COMPLETE', label: '완료', color: '#78909c' },
{ value: 'REGISTERED', label: '등록', color: '#42a5f5' },
{ value: 'IN_FIX', label: '수정중', color: '#ffa726' },
{ value: 'FIX_COMPLETE', label: '수정완료', color: '#66bb6a' },
{ value: 'CONFIRM_REQUEST', label: '확인요청', color: '#29b6f6' },
{ value: 'RE_VERIFY_REQUEST', label: '재검증 요청', color: '#ec407a' },
{ value: 'RE_REGISTERED', label: '재등록', color: '#ab47bc' },
{ value: 'COMPLETE', label: '완료', color: '#78909c' },
];
export const STAGE_BY_VALUE = Object.fromEntries(
@@ -0,0 +1,86 @@
/**
* ui_preferences.virtual.targets 가 비었을 때 서버·레거시에서 투자대상 복구
*/
import { loadActiveLiveStrategySettings, loadWatchlist } from './backendApi';
import {
loadVirtualSession,
loadVirtualTargets,
type VirtualTargetItem,
} from './virtualTradingStorage';
import { resolveVirtualTargetNames } from './virtualTargetNames';
function readLegacyTargets(): VirtualTargetItem[] {
try {
const raw = localStorage.getItem('gc_virtual_targets_v1');
if (!raw) return [];
const parsed = JSON.parse(raw) as VirtualTargetItem[];
return Array.isArray(parsed) ? parsed : [];
} catch {
return [];
}
}
function fromLiveSettings(
list: Awaited<ReturnType<typeof loadActiveLiveStrategySettings>>,
globalStrategyId: number | null,
): VirtualTargetItem[] {
return list.map(s => {
const { koreanName, englishName } = resolveVirtualTargetNames(s.market);
return {
market: s.market,
strategyId: s.strategyId ?? globalStrategyId,
candleType: s.candleType,
koreanName,
englishName,
pinned: !!s.isPinned,
};
});
}
function fromWatchlist(
list: Awaited<ReturnType<typeof loadWatchlist>>,
globalStrategyId: number | null,
): VirtualTargetItem[] {
return list.map(w => {
const market = w.symbol;
const { koreanName, englishName } = resolveVirtualTargetNames(
market,
w.koreanName,
w.englishName,
);
return {
market,
strategyId: globalStrategyId,
koreanName,
englishName,
};
});
}
/** DB·로컬 비어 있을 때 서버 실시간 설정·관심종목에서 목록 구성 */
export async function hydrateVirtualTargetsIfEmpty(): Promise<VirtualTargetItem[]> {
const existing = loadVirtualTargets();
if (existing.length > 0) return existing;
const legacy = readLegacyTargets();
if (legacy.length > 0) return legacy;
const session = loadVirtualSession();
const globalId = session.globalStrategyId;
try {
const active = await loadActiveLiveStrategySettings();
if (active.length > 0) return fromLiveSettings(active, globalId);
} catch (e) {
console.warn('[virtualTargets] active live settings load failed', e);
}
try {
const watchlist = await loadWatchlist();
if (watchlist.length > 0) return fromWatchlist(watchlist, globalId);
} catch (e) {
console.warn('[virtualTargets] watchlist load failed', e);
}
return [];
}