refactor(data): 收口关系表运行时数据源
Some checks failed
Deploy Production / Build, push, deploy, verify (push) Has been cancelled

- 移除已迁移业务 AppData 运行时 fallback,改走领域 API 和关系表快读
- 补齐需求产品负责人、版本计划任务 JSON 和成员 username 回填迁移
- 统一治理字典入口,并补充 AI provider、数据源契约和领域服务测试

Co-Authored-By: Codex GPT-5 <codex@openai.com>
This commit is contained in:
2026-07-09 14:59:49 +08:00
parent 1e6fb0c7aa
commit 2e595c7e72
98 changed files with 2938 additions and 1441 deletions

View File

@@ -89,17 +89,27 @@ export function hasVersionDataScopeRows(scope: VersionDataScope | null | undefin
}
export function selectVersionDataScope(input: {
appDataScope: VersionDataScope | null;
storeScope: VersionDataScope | null;
v22Scope?: VersionDataScope | null;
}): VersionDataScope | null {
const { appDataScope, v22Scope } = input;
const { storeScope, v22Scope } = input;
if (hasVersionDataScopeRows(v22Scope)) {
const requirements = overlayRowsById(v22Scope.requirements, storeScope?.requirements ?? []);
const plans = overlayRowsById(v22Scope.plans, storeScope?.plans ?? []);
return {
...v22Scope,
overtimeRecords: appDataScope?.overtimeRecords ?? v22Scope.overtimeRecords,
requirements,
requirementIds: requirements.map((item) => item.id),
requirementIdSet: new Set(requirements.map((item) => item.id)),
plans,
plansByType: groupPlansByType(plans),
devTasks: overlayRowsById(v22Scope.devTasks, storeScope?.devTasks ?? []),
testCases: overlayRowsById(v22Scope.testCases, storeScope?.testCases ?? []),
bugs: overlayRowsById(v22Scope.bugs, storeScope?.bugs ?? []),
overtimeRecords: storeScope?.overtimeRecords ?? v22Scope.overtimeRecords,
};
}
return appDataScope;
return storeScope;
}
export function buildVersionDataScopeMap(input: VersionDataScopeMapInput): Record<string, VersionDataScope> {
@@ -167,3 +177,25 @@ function createEmptyScope(): VersionDataScope {
overtimeRecords: [],
};
}
function overlayRowsById<T extends { id: string }>(baseRows: T[], overlayRows: T[]): T[] {
if (baseRows.length === 0) return baseRows;
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;
}
function groupPlansByType(plans: VersionPlan[]): Record<VersionPlan['type'], VersionPlan[]> {
return {
research: plans.filter((plan) => plan.type === 'research'),
product: plans.filter((plan) => plan.type === 'product'),
ui: plans.filter((plan) => plan.type === 'ui'),
};
}