import type { Priority } from './derive'; export type BugStatus = 'open' | 'fixing' | 'fixed' | 'verifying' | 'closed' | 'rejected'; export type BugSeverity = 'critical' | 'major' | 'minor' | 'trivial'; export interface BugLog { id: string; action: 'create' | 'status_change' | 'transfer' | 'resolve'; fromValue?: string; toValue?: string; operator: string; remark?: string; createdAt: string; } export interface Bug { id: string; bugNo: string; versionId: string; testCaseId: string; requirementId?: string; title: string; description: string; severity: BugSeverity; priority: Priority; reportedBy: string; assigneeId: string; status: BugStatus; images?: string[]; logs?: BugLog[]; resolvedAt?: string; closedAt?: string; resolution?: string; createdAt: string; updatedAt: string; } export const BUG_STATUS_LABEL: Record = { open: '待修复', fixing: '修复中', fixed: '已修复', verifying: '验证中', closed: '已关闭', rejected: '已拒绝', }; export const BUG_STATUS_COLOR: Record = { open: 'bg-red-50 text-red-600', fixing: 'bg-blue-50 text-blue-600', fixed: 'bg-indigo-50 text-indigo-600', verifying: 'bg-purple-50 text-purple-600', closed: 'bg-emerald-50 text-emerald-600', rejected: 'bg-zinc-100 text-zinc-500', }; export const BUG_SEVERITY_LABEL: Record = { critical: '致命', major: '严重', minor: '一般', trivial: '轻微', }; export const BUG_SEVERITY_COLOR: Record = { critical: 'bg-red-100 text-red-700', major: 'bg-orange-50 text-orange-700', minor: 'bg-yellow-50 text-yellow-700', trivial: 'bg-zinc-100 text-zinc-600', }; export const BUG_ALLOWED_TRANSITIONS: Record = { open: ['fixing', 'rejected'], fixing: ['fixed'], fixed: ['verifying'], verifying: ['closed', 'open'], closed: [], rejected: [], }; export function canBugTransition(from: BugStatus, to: BugStatus): boolean { return BUG_ALLOWED_TRANSITIONS[from].includes(to); } export function generateBugNo(existingBugs: Bug[]): string { const maxNum = existingBugs.reduce((max, b) => { const num = parseInt(b.bugNo.replace('BUG-', ''), 10); return isNaN(num) ? max : Math.max(max, num); }, 0); return `BUG-${String(maxNum + 1).padStart(3, '0')}`; }