feature: Tasks tab added for lab organizations. tasks now can be assigned and their status can be updated by the assignee.
This commit is contained in:
@@ -200,14 +200,19 @@ export class CasesService {
|
||||
}
|
||||
|
||||
if (dto.assigneeUserId !== undefined && dto.assigneeUserId !== null) {
|
||||
await this.ensureLabMember(dto.assigneeUserId, labOrganizationId);
|
||||
await this.ensureAssignableMember(dto.assigneeUserId, labOrganizationId);
|
||||
}
|
||||
|
||||
const updated = await this.prisma.labCaseTask.update({
|
||||
where: { id: taskId },
|
||||
data: {
|
||||
...(dto.assigneeUserId !== undefined ? { assigneeUserId: dto.assigneeUserId } : {}),
|
||||
...(dto.status !== undefined ? { status: dto.status } : {}),
|
||||
...(dto.assigneeUserId !== undefined
|
||||
? {
|
||||
assigneeUserId: dto.assigneeUserId,
|
||||
assignedAt: dto.assigneeUserId === null ? null : new Date(),
|
||||
}
|
||||
: {}),
|
||||
...(dto.priority !== undefined ? { priority: dto.priority } : {}),
|
||||
},
|
||||
include: {
|
||||
assignee: { select: { id: true, name: true, email: true } },
|
||||
@@ -222,18 +227,27 @@ export class CasesService {
|
||||
|
||||
const memberships = await this.prisma.membership.findMany({
|
||||
where: { organizationId: labOrganizationId, isActive: true },
|
||||
include: { user: { select: { id: true, name: true, email: true } } },
|
||||
include: {
|
||||
user: { select: { id: true, name: true, email: true } },
|
||||
permissions: { include: { permission: true } },
|
||||
},
|
||||
orderBy: [{ isOwner: 'desc' }, { createdAt: 'asc' }],
|
||||
});
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: memberships.map((m) => ({
|
||||
userId: m.user.id,
|
||||
name: m.user.name,
|
||||
email: m.user.email,
|
||||
isOwner: m.isOwner,
|
||||
})),
|
||||
data: memberships
|
||||
.filter((m) => {
|
||||
if (m.isOwner) return true;
|
||||
const names = m.permissions.map((p) => p.permission.name);
|
||||
return names.includes('TAB_TASKS_READ') || names.includes('TAB_TASKS_EDIT');
|
||||
})
|
||||
.map((m) => ({
|
||||
userId: m.user.id,
|
||||
name: m.user.name,
|
||||
email: m.user.email,
|
||||
isOwner: m.isOwner,
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -377,7 +391,10 @@ export class CasesService {
|
||||
stepOrder: number;
|
||||
stepLabel: string;
|
||||
status: LabTaskStatus;
|
||||
priority: number;
|
||||
assigneeUserId: string | null;
|
||||
assignedAt: Date | null;
|
||||
createdAt: Date;
|
||||
assignee: { id: string; name: string; email: string } | null;
|
||||
}>,
|
||||
) {
|
||||
@@ -411,7 +428,10 @@ export class CasesService {
|
||||
stepOrder: number;
|
||||
stepLabel: string;
|
||||
status: LabTaskStatus;
|
||||
priority: number;
|
||||
assigneeUserId: string | null;
|
||||
assignedAt: Date | null;
|
||||
createdAt: Date;
|
||||
assignee: { id: string; name: string; email: string } | null;
|
||||
}) {
|
||||
return {
|
||||
@@ -421,6 +441,9 @@ export class CasesService {
|
||||
stepOrder: task.stepOrder,
|
||||
stepLabel: task.stepLabel,
|
||||
status: task.status,
|
||||
priority: task.priority,
|
||||
assignedAt: task.assignedAt?.toISOString() ?? null,
|
||||
createdAt: task.createdAt.toISOString(),
|
||||
assigneeUserId: task.assigneeUserId,
|
||||
assignee: task.assignee
|
||||
? { id: task.assignee.id, name: task.assignee.name, email: task.assignee.email }
|
||||
@@ -428,14 +451,20 @@ export class CasesService {
|
||||
};
|
||||
}
|
||||
|
||||
private async ensureLabMember(userId: string, labOrganizationId: string) {
|
||||
private async ensureAssignableMember(userId: string, labOrganizationId: string) {
|
||||
const membership = await this.prisma.membership.findFirst({
|
||||
where: { userId, organizationId: labOrganizationId, isActive: true },
|
||||
select: { id: true },
|
||||
include: { permissions: { include: { permission: true } } },
|
||||
});
|
||||
if (!membership) {
|
||||
throw new BadRequestException('Assignee must be an active member of this lab');
|
||||
}
|
||||
if (membership.isOwner) return;
|
||||
const names = membership.permissions.map((p) => p.permission.name);
|
||||
if (names.includes('TAB_TASKS_READ') || names.includes('TAB_TASKS_EDIT')) {
|
||||
return;
|
||||
}
|
||||
throw new BadRequestException('Assignee must have access to the Tasks tab');
|
||||
}
|
||||
|
||||
private async assertCanReadCases(userId: string, organizationId: string) {
|
||||
|
||||
Reference in New Issue
Block a user