import type { AcquisitionMode } from "./mode"; /** 默认:用户明确立即处理 > 追更补缺 > 新作品 > 已有版本升级(REQ §6.8) */ export type PriorityClass = "immediate" | "catch_up" | "new_title" | "upgrade"; export const DEFAULT_PRIORITY_ORDER: readonly PriorityClass[] = ["immediate", "catch_up", "new_title", "upgrade"]; export interface QueueItem { id: string; priorityClass: PriorityClass; /** 入队时间 ISO;同优先级先进先出,避免饥饿 */ enqueuedAt: string; } export function priorityOf(mode: AcquisitionMode, immediate = false): PriorityClass { return immediate ? "immediate" : mode; } export function validatePriorityOrder(order: readonly PriorityClass[]): void { const all = new Set(DEFAULT_PRIORITY_ORDER); if (order.length !== all.size || new Set(order).size !== all.size || !order.every((o) => all.has(o))) throw new Error(`优先级配置必须恰好包含 ${[...all].join("/")} 各一次`); } /** 按优先级排序(稳定、纯函数)。优先级只影响资源分配,不越过阈值/HR/权限 */ export function sortByPriority( items: readonly T[], order: readonly PriorityClass[] = DEFAULT_PRIORITY_ORDER, ): T[] { validatePriorityOrder(order); const rank = new Map(order.map((c, i) => [c, i])); return [...items].sort( (a, b) => rank.get(a.priorityClass)! - rank.get(b.priorityClass)! || a.enqueuedAt.localeCompare(b.enqueuedAt) || a.id.localeCompare(b.id), ); }