feature: version one notification feature implemented.

This commit is contained in:
2026-07-18 01:09:54 +03:30
parent 0740493384
commit 9f6ec193d2
40 changed files with 1679 additions and 224 deletions

View File

@@ -3,12 +3,13 @@ import {
Injectable,
NotFoundException,
} from '@nestjs/common';
import { LabCaseCommentSide, LabCaseActivityType, Prisma } from '@prisma/client';
import { LabCaseCommentSide, LabCaseActivityType, Prisma, UserNotificationType } from '@prisma/client';
import { PrismaService } from '../../../prisma/prisma.service';
import { CreateLabCaseCommentDto } from './dto/lab-case-comment.dto';
import { hasEffectivePermission } from '../../common/membership-permissions';
import { treatmentProviderScopeWhere } from '../../common/treatment-provider-scope';
import { LabCaseActivityService } from '../notifications/lab-case-activity.service';
import { UserNotificationService } from '../notifications/user-notification.service';
const commentInclude = {
authorUser: { select: { id: true, name: true } },
@@ -24,6 +25,7 @@ export class LabCaseCommentsService {
constructor(
private readonly prisma: PrismaService,
private readonly labCaseActivity: LabCaseActivityService,
private readonly userNotifications: UserNotificationService,
) {}
// ---------- Lab side (TAB_TASKS_EDIT) ----------
@@ -67,6 +69,31 @@ export class LabCaseCommentsService {
visibleToClinic: created.visibleToClinic,
},
});
void this.userNotifications.notify({
organizationId: labOrganizationId,
type: UserNotificationType.LAB_COMMENT,
href: `/cases?caseId=${encodeURIComponent(caseId)}`,
actorUserId,
payload: { labCaseId: caseId, commentId: created.id },
requiredPermission: 'TAB_TASKS_READ',
});
if (created.visibleToClinic) {
const clinicOrgId = await this.clinicOrgIdForCase(caseId);
if (clinicOrgId) {
void this.userNotifications.notify({
organizationId: clinicOrgId,
type: UserNotificationType.LAB_COMMENT_CLINIC,
href: `/treatment?labCaseId=${encodeURIComponent(caseId)}`,
actorUserId,
payload: { labCaseId: caseId, commentId: created.id },
requiredPermission: 'TAB_TREATMENT_READ',
labCaseIdForProviderScope: caseId,
});
}
}
return { success: true, data: this.mapComment(created, LabCaseCommentSide.LAB) };
}
@@ -130,6 +157,17 @@ export class LabCaseCommentsService {
actorUserId,
payload: { commentId: created.id },
});
const labOrgId = await this.labOrgIdForCase(caseId);
if (labOrgId) {
void this.userNotifications.notify({
organizationId: labOrgId,
type: UserNotificationType.CLINIC_COMMENT,
href: `/cases?caseId=${encodeURIComponent(caseId)}`,
actorUserId,
payload: { labCaseId: caseId, commentId: created.id },
requiredPermission: 'TAB_CASES_READ',
});
}
return { success: true, data: this.mapComment(created, LabCaseCommentSide.CLINIC) };
}
@@ -172,6 +210,17 @@ export class LabCaseCommentsService {
actorUserId,
payload: { commentId: created.id },
});
const labOrgId = await this.labOrgIdForCase(caseId);
if (labOrgId) {
void this.userNotifications.notify({
organizationId: labOrgId,
type: UserNotificationType.CLINIC_COMMENT,
href: `/cases?caseId=${encodeURIComponent(caseId)}`,
actorUserId,
payload: { labCaseId: caseId, commentId: created.id },
requiredPermission: 'TAB_CASES_READ',
});
}
return { success: true, data: this.mapComment(created, LabCaseCommentSide.CLINIC) };
}
@@ -336,4 +385,21 @@ export class LabCaseCommentsService {
}
throw new ForbiddenException('You do not have access to treatment cases');
}
private async labOrgIdForCase(caseId: string): Promise<string | null> {
const send = await this.prisma.labCaseSend.findFirst({
where: { labCaseId: caseId },
orderBy: { sentAt: 'asc' },
select: { organizationId: true },
});
return send?.organizationId ?? null;
}
private async clinicOrgIdForCase(caseId: string): Promise<string | null> {
const labCase = await this.prisma.labCase.findUnique({
where: { id: caseId },
select: { treatment: { select: { organizationId: true } } },
});
return labCase?.treatment.organizationId ?? null;
}
}