import type { Bug } from './bug'; import type { DevTask } from './dev-task'; import type { OvertimeRecord } from './overtime'; import type { Requirement } from './requirement'; import type { TestCase } from './test-case'; import type { VersionPlan } from './version-plan'; export interface VersionDataScope { requirements: Requirement[]; requirementIds: string[]; requirementIdSet: Set; plans: VersionPlan[]; plansByType: Record; devTasks: DevTask[]; testCases: TestCase[]; bugs: Bug[]; overtimeRecords: OvertimeRecord[]; } interface VersionDataScopeInput { versionId: string; requirements: Requirement[]; plans: VersionPlan[]; devTasks: DevTask[]; testCases: TestCase[]; bugs: Bug[]; overtimeRecords?: OvertimeRecord[]; } interface VersionDataScopeMapInput extends Omit { versionIds: string[]; } export function buildVersionDataScope(input: VersionDataScopeInput): VersionDataScope { const { versionId, requirements, plans, devTasks, testCases, bugs, overtimeRecords = [], } = input; const scopedRequirements: Requirement[] = []; const requirementIds: string[] = []; const requirementIdSet = new Set(); for (const requirement of requirements) { if (requirement.versionId !== versionId) continue; scopedRequirements.push(requirement); requirementIds.push(requirement.id); requirementIdSet.add(requirement.id); } const scopedPlans: VersionPlan[] = []; const plansByType: Record = { research: [], product: [], ui: [], }; for (const plan of plans) { if (plan.versionId !== versionId) continue; scopedPlans.push(plan); plansByType[plan.type].push(plan); } return { requirements: scopedRequirements, requirementIds, requirementIdSet, plans: scopedPlans, plansByType, devTasks: devTasks.filter((task) => task.versionId === versionId || (!task.versionId && requirementIdSet.has(task.requirementId))), testCases: testCases.filter((testCase) => testCase.versionId === versionId), bugs: bugs.filter((bug) => bug.versionId === versionId), overtimeRecords: overtimeRecords.filter((record) => record.versionId === versionId), }; } export function buildVersionDataScopeMap(input: VersionDataScopeMapInput): Record { const scopes: Record = {}; const targetVersionIds = new Set(input.versionIds); for (const versionId of input.versionIds) { scopes[versionId] = createEmptyScope(); } const requirementVersionMap = new Map(); for (const requirement of input.requirements) { const versionId = requirement.versionId; if (!versionId) continue; requirementVersionMap.set(requirement.id, versionId); const scope = scopes[versionId]; if (!scope) continue; scope.requirements.push(requirement); scope.requirementIds.push(requirement.id); scope.requirementIdSet.add(requirement.id); } for (const plan of input.plans) { const scope = scopes[plan.versionId]; if (!scope) continue; scope.plans.push(plan); scope.plansByType[plan.type].push(plan); } for (const task of input.devTasks) { const versionId = task.versionId || requirementVersionMap.get(task.requirementId); if (!versionId || !targetVersionIds.has(versionId)) continue; scopes[versionId]?.devTasks.push(task); } for (const testCase of input.testCases) { scopes[testCase.versionId]?.testCases.push(testCase); } for (const bug of input.bugs) { scopes[bug.versionId]?.bugs.push(bug); } for (const record of input.overtimeRecords ?? []) { if (!record.versionId) continue; scopes[record.versionId]?.overtimeRecords.push(record); } return scopes; } function createEmptyScope(): VersionDataScope { return { requirements: [], requirementIds: [], requirementIdSet: new Set(), plans: [], plansByType: { research: [], product: [], ui: [], }, devTasks: [], testCases: [], bugs: [], overtimeRecords: [], }; }