Files
Agent-System/web/src/lib/projectAdapter.ts
T
weichenandCursor 855363fd60 fix(web): gate demo seeds and reclaim mock deliverables
Stop shipping hard-coded demo docs/projects into production builds,
drop local mock items on authoritative empty server lists, and purge
stale demo seed residue from localStorage on boot.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 02:50:34 +00:00

74 lines
2.2 KiB
TypeScript

import { Project } from '../types/projectWorkflow';
import { ProjectInfo, ProjectMember } from '../types/workbench';
import { isDemoSeedProjectId } from '../data/demoSeedIds';
type UserCatalogEntry = { id: number; name: string };
export function resolveUserDisplayName(
userId: number,
catalog: UserCatalogEntry[],
fallback = '未知用户'
): string {
return catalog.find((u) => u.id === userId)?.name ?? fallback;
}
export function mapServerProjectToProjectInfo(
project: Project,
catalog: UserCatalogEntry[],
existing?: ProjectInfo
): ProjectInfo {
const creatorName = resolveUserDisplayName(project.creator_user_id, catalog);
const defaultMember: ProjectMember = {
userId: project.creator_user_id,
userName: creatorName,
role: 'creator',
status: 'active',
joinedAt: project.created_at,
};
return {
id: project.id,
title: project.name,
deviceType: project.device_type || existing?.deviceType || '',
description: project.intended_use || existing?.description || '',
creatorId: project.creator_user_id,
creatorName,
createdAt: project.created_at,
members: existing?.members?.length ? existing.members : [defaultMember],
};
}
/**
* 服务端项目覆盖同 id 本地项。
* 默认丢弃 local-only 的 demo seed 项目,避免侧边栏幻影演示项。
*/
export function mergeProjectLists(
local: ProjectInfo[],
fromServer: ProjectInfo[],
opts?: { dropLocalOnlyDemoSeeds?: boolean },
): ProjectInfo[] {
const dropLocalOnlyDemo = opts?.dropLocalOnlyDemoSeeds !== false;
const byId = new Map<number, ProjectInfo>();
const serverIds = new Set(fromServer.map((p) => p.id));
for (const project of local) {
if (dropLocalOnlyDemo && isDemoSeedProjectId(project.id) && !serverIds.has(project.id)) {
continue;
}
byId.set(project.id, project);
}
for (const project of fromServer) {
const previous = byId.get(project.id);
if (!previous) {
byId.set(project.id, project);
continue;
}
byId.set(project.id, {
...previous,
...project,
members: previous.members.length > 0 ? previous.members : project.members,
});
}
return [...byId.values()];
}