fix(产品): 防止空概览覆盖版本树
This commit is contained in:
@@ -7,6 +7,35 @@ test('does not persist an empty remote overview', () => {
|
|||||||
assert.equal(shouldPersistRemoteOverview([]), false);
|
assert.equal(shouldPersistRemoteOverview([]), false);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('persists a non-empty remote overview', () => {
|
test('does not persist product-only remote overview', () => {
|
||||||
assert.equal(shouldPersistRemoteOverview([{ id: 'product-1' }]), true);
|
assert.equal(shouldPersistRemoteOverview([{ id: 'product-1' }]), false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('does not persist relational products without frontend project or version data', () => {
|
||||||
|
assert.equal(
|
||||||
|
shouldPersistRemoteOverview([
|
||||||
|
{
|
||||||
|
id: 'cmqs07s3900001450gwu9lesi',
|
||||||
|
name: '测试AI任务拆解',
|
||||||
|
projects: [],
|
||||||
|
versions: [],
|
||||||
|
_count: { requirements: 0, projects: 0, versions: 0 },
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('persists overview with frontend project and version ids', () => {
|
||||||
|
assert.equal(
|
||||||
|
shouldPersistRemoteOverview([
|
||||||
|
{
|
||||||
|
id: 'local-1782301366735',
|
||||||
|
name: '测试AI任务拆解',
|
||||||
|
projects: [{ id: 'proj-1782301375710', name: '任务拆解' }],
|
||||||
|
versions: [{ id: 'ver-1782301431670', name: '任务拆解V1.0', status: 'developing' }],
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
true,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,3 +1,35 @@
|
|||||||
export function shouldPersistRemoteOverview(overview: unknown): boolean {
|
export function shouldPersistRemoteOverview(overview: unknown): boolean {
|
||||||
return Array.isArray(overview) && overview.length > 0;
|
if (!Array.isArray(overview) || overview.length === 0) return false;
|
||||||
|
return overview.some(hasFrontendTreeSignal);
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasFrontendTreeSignal(product: unknown): boolean {
|
||||||
|
if (!isRecord(product)) return false;
|
||||||
|
const projects = Array.isArray(product.projects) ? product.projects : [];
|
||||||
|
const versions = Array.isArray(product.versions) ? product.versions : [];
|
||||||
|
return projects.some(isFrontendProject) || versions.some(isFrontendVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isFrontendProject(project: unknown): boolean {
|
||||||
|
return (
|
||||||
|
isRecord(project) &&
|
||||||
|
typeof project.id === 'string' &&
|
||||||
|
project.id.startsWith('proj-') &&
|
||||||
|
typeof project.name === 'string'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isFrontendVersion(version: unknown): boolean {
|
||||||
|
if (!isRecord(version) || typeof version.id !== 'string' || typeof version.name !== 'string') return false;
|
||||||
|
return (
|
||||||
|
version.id.startsWith('ver-') ||
|
||||||
|
typeof version.status === 'string' ||
|
||||||
|
typeof version.expectedReleaseDate === 'string' ||
|
||||||
|
Array.isArray(version.members) ||
|
||||||
|
typeof version.priority === 'string'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isRecord(value: unknown): value is Record<string, unknown> {
|
||||||
|
return typeof value === 'object' && value !== null;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user