import type { Requirement } from './requirement'; export interface RequirementOption { id: string; code: string; title: string; productOwner?: string; status: Requirement['status']; isHistorical?: boolean; } export function toRequirementOption(requirement: Requirement, isHistorical = false): RequirementOption { return { id: requirement.id, code: requirement.code, title: requirement.title, productOwner: requirement.productOwner, status: requirement.status, isHistorical, }; } export function getProjectAdoptedRequirementCandidates(requirements: Requirement[], projectId: string): Requirement[] { return requirements .filter((r) => r.projectId === projectId && r.status === 'adopted') .sort((a, b) => a.code.localeCompare(b.code, 'zh-CN')); } export function getVersionLinkedRequirementCandidates(requirements: Requirement[], requirementIds: string[]): Requirement[] { const linkedOrder = new Map(); requirementIds.forEach((id, index) => { if (!linkedOrder.has(id)) linkedOrder.set(id, index); }); return requirements .filter((r) => linkedOrder.has(r.id)) .sort((a, b) => { const orderA = linkedOrder.get(a.id) ?? Number.MAX_SAFE_INTEGER; const orderB = linkedOrder.get(b.id) ?? Number.MAX_SAFE_INTEGER; if (orderA !== orderB) return orderA - orderB; return a.code.localeCompare(b.code, 'zh-CN'); }); } export function mergeSelectedRequirementOptions( candidates: Requirement[], allRequirements: Requirement[], selectedIds: string[] = [], ): RequirementOption[] { const candidateOptions = candidates.map((r) => toRequirementOption(r)); const candidateIds = new Set(candidateOptions.map((r) => r.id)); const historical = selectedIds .filter((id) => !candidateIds.has(id)) .map((id) => allRequirements.find((r) => r.id === id)) .filter((r): r is Requirement => Boolean(r)) .map((r) => toRequirementOption(r, true)); return [...candidateOptions, ...historical]; }