fix(requirement): 修复需求池录入人员显示

This commit is contained in:
2026-07-06 11:14:49 +08:00
parent b4a3c990b4
commit 84344e81f6
7 changed files with 47 additions and 13 deletions

View File

@@ -49,7 +49,7 @@ function buildAppData(): Record<string, any> {
typeId: 'type-feature',
status: 'adopted',
priority: 'P1',
creator: 'member-pm',
creator: 'Product manager',
createdAt: '2026-01-02T08:00:00.000Z',
updatedAt: '2026-01-02T09:00:00.000Z',
},

View File

@@ -371,6 +371,7 @@ export function mapAppDataToV22Rows(appData: Record<string, unknown>): V22Mapped
updatedAt: stringField(member, 'updatedAt') ?? stringField(member, 'createdAt'),
});
}
const userIdByReference = buildUserIdByReference(users);
const defaultProductId = products[0]?.id;
const requirementCode = scopedCodeFactory('REQ');
@@ -400,7 +401,7 @@ export function mapAppDataToV22Rows(appData: Record<string, unknown>): V22Mapped
sourceType: stringField(requirement, 'sourceType'),
sourceTarget: stringField(requirement, 'sourceTarget'),
platform: platforms.join(',') || stringField(requirement, 'platform'),
creatorId: stringField(requirement, 'creatorId') ?? stringField(requirement, 'creator'),
creatorId: resolveUserId(stringField(requirement, 'creatorId') ?? stringField(requirement, 'creator'), userIdByReference),
createdAt: stringField(requirement, 'createdAt'),
updatedAt: stringField(requirement, 'updatedAt') ?? stringField(requirement, 'createdAt'),
};
@@ -437,7 +438,7 @@ export function mapAppDataToV22Rows(appData: Record<string, unknown>): V22Mapped
type: stringField(plan, 'type') ?? 'product',
title: stringField(plan, 'title') ?? id,
status: stringField(plan, 'status') ?? 'pending',
ownerId: stringField(plan, 'ownerId') ?? stringField(plan, 'owner'),
ownerId: resolveUserId(stringField(plan, 'ownerId') ?? stringField(plan, 'owner'), userIdByReference),
expectedStartAt: stringField(plan, 'expectedStartAt') ?? stringField(plan, 'startTime'),
expectedEndAt: stringField(plan, 'expectedEndAt') ?? stringField(plan, 'endTime'),
actualStartAt: stringField(plan, 'actualStartAt'),
@@ -475,8 +476,8 @@ export function mapAppDataToV22Rows(appData: Record<string, unknown>): V22Mapped
description: stringField(task, 'description') ?? '',
status: stringField(task, 'status') ?? 'todo',
priority: priorityRank(task.priority),
assigneeId: stringField(task, 'assigneeId'),
creatorId: stringField(task, 'creatorId') ?? stringField(task, 'createdBy'),
assigneeId: resolveUserId(stringField(task, 'assigneeId'), userIdByReference),
creatorId: resolveUserId(stringField(task, 'creatorId') ?? stringField(task, 'createdBy'), userIdByReference),
isBlocked: booleanField(task, 'isBlocked') ?? false,
blockReason: stringField(task, 'blockReason'),
expectedStartAt: stringField(task, 'expectedStartAt'),
@@ -519,8 +520,8 @@ export function mapAppDataToV22Rows(appData: Record<string, unknown>): V22Mapped
status: stringField(testCase, 'status') ?? 'pending',
roundNo: integerField(testCase, 'roundNo') ?? 1,
priority: priorityRank(testCase.priority),
assigneeId: stringField(testCase, 'assigneeId'),
creatorId: stringField(testCase, 'creatorId') ?? stringField(testCase, 'createdBy'),
assigneeId: resolveUserId(stringField(testCase, 'assigneeId'), userIdByReference),
creatorId: resolveUserId(stringField(testCase, 'creatorId') ?? stringField(testCase, 'createdBy'), userIdByReference),
plannedTestAt: stringField(testCase, 'plannedTestAt'),
plannedEndAt: stringField(testCase, 'plannedEndAt'),
startedAt: stringField(testCase, 'startedAt'),
@@ -564,8 +565,8 @@ export function mapAppDataToV22Rows(appData: Record<string, unknown>): V22Mapped
status: stringField(bug, 'status') ?? 'open',
severity: stringField(bug, 'severity') ?? 'minor',
priority: priorityRank(bug.priority),
assigneeId: stringField(bug, 'assigneeId'),
reporterId: stringField(bug, 'reporterId') ?? stringField(bug, 'reportedBy'),
assigneeId: resolveUserId(stringField(bug, 'assigneeId'), userIdByReference),
reporterId: resolveUserId(stringField(bug, 'reporterId') ?? stringField(bug, 'reportedBy'), userIdByReference),
plannedFixAt: stringField(bug, 'plannedFixAt'),
resolvedAt: stringField(bug, 'resolvedAt'),
closedAt: stringField(bug, 'closedAt'),
@@ -858,6 +859,20 @@ function uniqueEmailFactory() {
};
}
function buildUserIdByReference(users: UserRow[]): Map<string, string> {
const refs = new Map<string, string>();
for (const user of users) {
refs.set(user.id, user.id);
refs.set(user.name, user.id);
}
return refs;
}
function resolveUserId(ref: string | undefined, userIdByReference: Map<string, string>): string | undefined {
if (!ref) return undefined;
return userIdByReference.get(ref);
}
function normalizeMemberEmail(email: string | undefined, username: string, id: string): string {
if (email?.includes('@')) return email;
const base = email || username || id;

View File

@@ -44,6 +44,7 @@ describe('V22QueryService', () => {
expect(result.devTasks).toEqual([{ id: 'dev-1' }]);
expect(prisma.requirement.findMany).toHaveBeenCalledWith({
where: { versionId: 'version-1' },
include: { creator: { select: { id: true, name: true } } },
orderBy: { createdAt: 'desc' },
});
expect(prisma.devTask.findMany).toHaveBeenCalledWith({
@@ -88,6 +89,7 @@ describe('V22QueryService', () => {
{ title: { contains: 'login', mode: 'insensitive' } },
],
},
include: { creator: { select: { id: true, name: true } } },
orderBy: { createdAt: 'asc' },
take: 2,
cursor: { id_productId: { id: 'req-3', productId: 'product-1' } },

View File

@@ -19,6 +19,10 @@ interface XiaobaoWarningQuery {
manager?: string;
}
const REQUIREMENT_CREATOR_INCLUDE = {
creator: { select: { id: true, name: true } },
} as const;
@Injectable()
export class V22QueryService {
constructor(private readonly prisma: PrismaService) {}
@@ -30,6 +34,7 @@ export class V22QueryService {
const [requirements, versionPlans, devTasks, testCases, bugs] = await Promise.all([
this.prisma.requirement.findMany({
where: { versionId },
include: REQUIREMENT_CREATOR_INCLUDE,
orderBy: { createdAt: 'desc' },
}),
this.prisma.versionPlan.findMany({
@@ -80,6 +85,7 @@ export class V22QueryService {
}
: {}),
},
include: REQUIREMENT_CREATOR_INCLUDE,
orderBy: { createdAt: sortDirection },
take: limit + 1,
...(query.cursor