107 lines
3.6 KiB
TypeScript
107 lines
3.6 KiB
TypeScript
/**
|
|
* 역할·메뉴 접근 권한
|
|
*/
|
|
import type { MenuPage } from '../components/TopMenuBar';
|
|
|
|
export type UserRole = 'ADMIN' | 'USER' | 'GUEST';
|
|
|
|
export type TopMenuId = MenuPage;
|
|
|
|
export type SettingsCategoryId =
|
|
| 'general' | 'chart' | 'indicators' | 'backtest' | 'strategy'
|
|
| 'trading' | 'paper' | 'virtual' | 'live' | 'trend-search' | 'llm' | 'alert' | 'network' | 'admin';
|
|
|
|
export const TOP_MENU_IDS: TopMenuId[] = [
|
|
'dashboard', 'widget-dashboard', 'chart', 'paper', 'virtual', 'trend-search', 'strategy-editor', 'strategy-evaluation', 'backtest', 'analysis-report', 'notifications', 'settings', 'verification-board',
|
|
];
|
|
|
|
export const SETTINGS_MENU_IDS: SettingsCategoryId[] = [
|
|
'general', 'chart', 'indicators', 'backtest', 'strategy', 'trading', 'live',
|
|
'trend-search', 'llm', 'alert', 'network', 'admin',
|
|
];
|
|
|
|
export const ALL_MENU_IDS = [
|
|
'dashboard', 'widget-dashboard', 'chart', 'paper', 'virtual', 'trend-search', 'verification-board', 'strategy', 'strategy-editor', 'strategy-evaluation', 'backtest', 'analysis-report', 'notifications', 'settings',
|
|
...SETTINGS_MENU_IDS.map(id => `settings_${id}` as const),
|
|
] as const;
|
|
|
|
export type MenuPermissionId = typeof ALL_MENU_IDS[number];
|
|
|
|
export const MENU_LABELS: Record<string, string> = {
|
|
dashboard: '대시보드',
|
|
'widget-dashboard': '위젯',
|
|
chart: '실시간차트',
|
|
paper: '투자관리',
|
|
virtual: '가상매매',
|
|
'trend-search': '추세검색',
|
|
'verification-board': '검증게시판',
|
|
strategy: '투자전략',
|
|
'strategy-editor': '전략편집기',
|
|
'strategy-evaluation': '전략 평가',
|
|
backtest: '백테스팅',
|
|
'analysis-report': '분석레포트',
|
|
notifications: '알림목록',
|
|
settings: '설정',
|
|
settings_general: '설정 · 일반',
|
|
settings_chart: '설정 · 차트',
|
|
settings_indicators: '설정 · 보조지표',
|
|
settings_backtest: '설정 · 백테스팅',
|
|
settings_strategy: '설정 · 전략',
|
|
settings_trading: '설정 · 매매설정',
|
|
settings_paper: '설정 · 모의투자',
|
|
settings_virtual: '설정 · 가상매매',
|
|
settings_live: '설정 · 실거래',
|
|
'settings_trend-search': '설정 · 추세검색',
|
|
settings_llm: '설정 · LLM',
|
|
settings_alert: '설정 · 알림',
|
|
settings_network: '설정 · 네트워크',
|
|
settings_admin: '설정 · 관리자',
|
|
};
|
|
|
|
export const ROLE_LABELS: Record<UserRole, string> = {
|
|
ADMIN: '관리자',
|
|
USER: '사용자',
|
|
GUEST: '게스트',
|
|
};
|
|
|
|
export interface MenuPermissionsDto {
|
|
role: UserRole;
|
|
permissions: Record<string, boolean>;
|
|
}
|
|
|
|
export function settingsCategoryToMenuId(cat: SettingsCategoryId): string {
|
|
return `settings_${cat}`;
|
|
}
|
|
|
|
export function canAccessMenu(
|
|
permissions: Record<string, boolean> | null | undefined,
|
|
menuId: string,
|
|
): boolean {
|
|
if (menuId === 'strategy') return false;
|
|
if (!permissions) return menuId === 'chart';
|
|
if (menuId === 'strategy-editor') {
|
|
if (permissions['strategy-editor'] === true) return true;
|
|
return permissions.strategy === true;
|
|
}
|
|
if (menuId === 'strategy-evaluation') {
|
|
if (permissions['strategy-evaluation'] === true) return true;
|
|
return permissions.backtest === true || permissions['strategy-editor'] === true;
|
|
}
|
|
return permissions[menuId] === true;
|
|
}
|
|
|
|
export function firstAllowedTopMenu(
|
|
permissions: Record<string, boolean> | null | undefined,
|
|
): TopMenuId {
|
|
for (const id of TOP_MENU_IDS) {
|
|
if (canAccessMenu(permissions, id)) return id;
|
|
}
|
|
return 'chart';
|
|
}
|
|
|
|
export function normalizeRole(role?: string | null): UserRole {
|
|
const r = (role ?? 'GUEST').toUpperCase();
|
|
if (r === 'ADMIN' || r === 'USER' || r === 'GUEST') return r;
|
|
return 'USER';
|
|
}
|