Files
ftb-project-management/apps/web/lib/workspace-v22-source.ts
2e595c7e72
Some checks failed
Deploy Production / Build, push, deploy, verify (push) Has been cancelled
refactor(data): 收口关系表运行时数据源
- 移除已迁移业务 AppData 运行时 fallback,改走领域 API 和关系表快读
- 补齐需求产品负责人、版本计划任务 JSON 和成员 username 回填迁移
- 统一治理字典入口,并补充 AI provider、数据源契约和领域服务测试

Co-Authored-By: Codex GPT-5 <codex@openai.com>
2026-07-09 14:59:49 +08:00

73 lines
2.0 KiB
TypeScript

import type { Bug } from './bug';
import type { DevTask } from './dev-task';
import type { TestCase } from './test-case';
import type { V22WorkspaceData } from './v22-api';
import type { VersionPlan } from './version-plan';
export interface WorkspaceCollections {
versionPlans: VersionPlan[];
devTasks: DevTask[];
testCases: TestCase[];
bugs: Bug[];
}
export interface SelectWorkspaceCollectionsInput {
v22Loaded: boolean;
v22Failed: boolean;
v22Data: V22WorkspaceData | null;
storeData: {
plans: VersionPlan[];
devTasks: DevTask[];
testCases: TestCase[];
bugs: Bug[];
};
}
export function selectWorkspaceCollections({
v22Loaded,
v22Failed,
v22Data,
storeData,
}: SelectWorkspaceCollectionsInput): WorkspaceCollections {
if (v22Loaded && !v22Failed && v22Data) {
const hasV22Rows = v22Data.versionPlans.length > 0
|| v22Data.devTasks.length > 0
|| v22Data.testCases.length > 0
|| v22Data.bugs.length > 0;
if (!hasV22Rows) {
return {
versionPlans: v22Data.versionPlans,
devTasks: v22Data.devTasks,
testCases: v22Data.testCases,
bugs: v22Data.bugs,
};
}
return {
versionPlans: overlayRowsById(v22Data.versionPlans, storeData.plans),
devTasks: overlayRowsById(v22Data.devTasks, storeData.devTasks),
testCases: overlayRowsById(v22Data.testCases, storeData.testCases),
bugs: overlayRowsById(v22Data.bugs, storeData.bugs),
};
}
return {
versionPlans: storeData.plans,
devTasks: storeData.devTasks,
testCases: storeData.testCases,
bugs: storeData.bugs,
};
}
function overlayRowsById<T extends { id: string }>(baseRows: T[], overlayRows: T[]): T[] {
const overlayById = new Map(overlayRows.map((item) => [item.id, item]));
const seen = new Set<string>();
const merged = baseRows.map((item) => {
seen.add(item.id);
return overlayById.get(item.id) ?? item;
});
for (const item of overlayRows) {
if (!seen.has(item.id)) merged.push(item);
}
return merged;
}