- 커스텀 탭 → TabBar/TabButton 공통 컴포넌트 교체 (3개 파일)
- hex 색상 맵 → Tailwind 클래스 토큰 전환, style={{ }} 인라인 제거
- 인라인 Badge intent 삼항 → 카탈로그 함수 교체 (getAgentPermTypeIntent 등)
- 신규 카탈로그: mlopsJobStatuses (4종), aiSecurityStatuses (위협3+권한5+결과3)
- catalogRegistry에 4건 등록 → design-system.html 쇼케이스 자동 노출
- statusIntent.ts에 '허용', '위험', '관리자', '중지', '실행' 매핑 추가
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
133 lines
4.5 KiB
TypeScript
133 lines
4.5 KiB
TypeScript
/**
|
|
* AI 보안 / Agent 보안 도메인 상태 카탈로그
|
|
*
|
|
* 사용처: AISecurityPage, AIAgentSecurityPage
|
|
*/
|
|
|
|
import type { BadgeIntent } from '@lib/theme/variants';
|
|
|
|
// ─── 위협 수준 ──────────────
|
|
export type ThreatLevel = 'HIGH' | 'MEDIUM' | 'LOW';
|
|
|
|
export const THREAT_LEVELS: Record<ThreatLevel, { i18nKey: string; fallback: { ko: string; en: string }; intent: BadgeIntent }> = {
|
|
HIGH: {
|
|
i18nKey: 'threatLevel.HIGH',
|
|
fallback: { ko: '높음', en: 'High' },
|
|
intent: 'critical',
|
|
},
|
|
MEDIUM: {
|
|
i18nKey: 'threatLevel.MEDIUM',
|
|
fallback: { ko: '중간', en: 'Medium' },
|
|
intent: 'warning',
|
|
},
|
|
LOW: {
|
|
i18nKey: 'threatLevel.LOW',
|
|
fallback: { ko: '낮음', en: 'Low' },
|
|
intent: 'info',
|
|
},
|
|
};
|
|
|
|
export function getThreatLevelIntent(s: string): BadgeIntent {
|
|
const normalized = s === '높음' ? 'HIGH' : s === '중간' ? 'MEDIUM' : s === '낮음' ? 'LOW' : s;
|
|
return THREAT_LEVELS[normalized as ThreatLevel]?.intent ?? 'muted';
|
|
}
|
|
|
|
export function getThreatLevelLabel(
|
|
s: string,
|
|
t: (k: string, opts?: { defaultValue?: string }) => string,
|
|
lang: 'ko' | 'en' = 'ko',
|
|
): string {
|
|
const normalized = s === '높음' ? 'HIGH' : s === '중간' ? 'MEDIUM' : s === '낮음' ? 'LOW' : s;
|
|
const meta = THREAT_LEVELS[normalized as ThreatLevel];
|
|
if (!meta) return s;
|
|
return t(meta.i18nKey, { defaultValue: meta.fallback[lang] });
|
|
}
|
|
|
|
// ─── Agent 권한 유형 ──────────────
|
|
export type AgentPermType = 'ADMIN' | 'WRITE' | 'READ' | 'EXECUTE' | 'DELETE';
|
|
|
|
export const AGENT_PERM_TYPES: Record<AgentPermType, { i18nKey: string; fallback: { ko: string; en: string }; intent: BadgeIntent }> = {
|
|
ADMIN: {
|
|
i18nKey: 'agentPerm.ADMIN',
|
|
fallback: { ko: '관리자', en: 'Admin' },
|
|
intent: 'high',
|
|
},
|
|
DELETE: {
|
|
i18nKey: 'agentPerm.DELETE',
|
|
fallback: { ko: '삭제', en: 'Delete' },
|
|
intent: 'critical',
|
|
},
|
|
WRITE: {
|
|
i18nKey: 'agentPerm.WRITE',
|
|
fallback: { ko: '쓰기', en: 'Write' },
|
|
intent: 'warning',
|
|
},
|
|
READ: {
|
|
i18nKey: 'agentPerm.READ',
|
|
fallback: { ko: '읽기', en: 'Read' },
|
|
intent: 'info',
|
|
},
|
|
EXECUTE: {
|
|
i18nKey: 'agentPerm.EXECUTE',
|
|
fallback: { ko: '실행', en: 'Execute' },
|
|
intent: 'purple',
|
|
},
|
|
};
|
|
|
|
export function getAgentPermTypeIntent(s: string): BadgeIntent {
|
|
const map: Record<string, AgentPermType> = { '관리자': 'ADMIN', '삭제': 'DELETE', '쓰기': 'WRITE', '조회+쓰기': 'WRITE', '읽기': 'READ', '실행': 'EXECUTE' };
|
|
const key = map[s] ?? s;
|
|
return AGENT_PERM_TYPES[key as AgentPermType]?.intent ?? 'muted';
|
|
}
|
|
|
|
export function getAgentPermTypeLabel(
|
|
s: string,
|
|
t: (k: string, opts?: { defaultValue?: string }) => string,
|
|
lang: 'ko' | 'en' = 'ko',
|
|
): string {
|
|
const map: Record<string, AgentPermType> = { '관리자': 'ADMIN', '삭제': 'DELETE', '쓰기': 'WRITE', '조회+쓰기': 'WRITE', '읽기': 'READ', '실행': 'EXECUTE' };
|
|
const key = map[s] ?? s;
|
|
const meta = AGENT_PERM_TYPES[key as AgentPermType];
|
|
if (!meta) return s;
|
|
return t(meta.i18nKey, { defaultValue: meta.fallback[lang] });
|
|
}
|
|
|
|
// ─── Agent 실행 결과 ──────────────
|
|
export type AgentExecResult = 'BLOCKED' | 'CONDITIONAL' | 'ALLOWED';
|
|
|
|
export const AGENT_EXEC_RESULTS: Record<AgentExecResult, { i18nKey: string; fallback: { ko: string; en: string }; intent: BadgeIntent }> = {
|
|
BLOCKED: {
|
|
i18nKey: 'agentExec.BLOCKED',
|
|
fallback: { ko: '차단', en: 'Blocked' },
|
|
intent: 'critical',
|
|
},
|
|
CONDITIONAL: {
|
|
i18nKey: 'agentExec.CONDITIONAL',
|
|
fallback: { ko: '조건부 승인', en: 'Conditional' },
|
|
intent: 'warning',
|
|
},
|
|
ALLOWED: {
|
|
i18nKey: 'agentExec.ALLOWED',
|
|
fallback: { ko: '정상', en: 'Allowed' },
|
|
intent: 'success',
|
|
},
|
|
};
|
|
|
|
export function getAgentExecResultIntent(s: string): BadgeIntent {
|
|
const map: Record<string, AgentExecResult> = { '차단': 'BLOCKED', '조건부 승인': 'CONDITIONAL', '승인→성공': 'ALLOWED', '정상': 'ALLOWED' };
|
|
const key = map[s] ?? s;
|
|
return AGENT_EXEC_RESULTS[key as AgentExecResult]?.intent ?? 'muted';
|
|
}
|
|
|
|
export function getAgentExecResultLabel(
|
|
s: string,
|
|
t: (k: string, opts?: { defaultValue?: string }) => string,
|
|
lang: 'ko' | 'en' = 'ko',
|
|
): string {
|
|
const map: Record<string, AgentExecResult> = { '차단': 'BLOCKED', '조건부 승인': 'CONDITIONAL', '승인→성공': 'ALLOWED', '정상': 'ALLOWED' };
|
|
const key = map[s] ?? s;
|
|
const meta = AGENT_EXEC_RESULTS[key as AgentExecResult];
|
|
if (!meta) return s;
|
|
return t(meta.i18nKey, { defaultValue: meta.fallback[lang] });
|
|
}
|