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

@@ -4,7 +4,7 @@ import {
Injectable,
NotFoundException,
} from '@nestjs/common';
import { CatalogEntityKind, LabCaseActivityType, LabTaskStatus, Prisma } from '@prisma/client';
import { CatalogEntityKind, LabCaseActivityType, LabTaskStatus, Prisma, UserNotificationType } from '@prisma/client';
import { PrismaService } from '../../../prisma/prisma.service';
import { normalizeMobile } from '../../common/phone';
import {
@@ -16,6 +16,7 @@ import { isLabCaseOverdue, startOfUtcDay } from '../../common/lab-case-due-date'
import { ListLabTasksDto, LocateTaskPageDto, UpdateLabTaskDto } from './dto/tasks.dto';
import { hasEffectivePermission } from '../../common/membership-permissions';
import { LabCaseActivityService } from '../notifications/lab-case-activity.service';
import { UserNotificationService } from '../notifications/user-notification.service';
const taskListInclude = {
lastStatusChangedBy: { select: { id: true, name: true } },
@@ -42,6 +43,7 @@ export class TasksService {
private readonly prisma: PrismaService,
private readonly catalogLabels: CatalogLabelService,
private readonly labCaseActivity: LabCaseActivityService,
private readonly userNotifications: UserNotificationService,
) {}
getOrganizationIdFromUser(user: { organizationId?: string }) {
@@ -323,6 +325,30 @@ export class TasksService {
return result;
});
if (dto.status === LabTaskStatus.COMPLETED && task.status !== LabTaskStatus.COMPLETED) {
void this.userNotifications.notify({
organizationId: labOrganizationId,
type: UserNotificationType.TASK_COMPLETED,
href: `/tasks?taskId=${encodeURIComponent(taskId)}&labCaseId=${encodeURIComponent(task.labCaseId)}`,
actorUserId,
payload: { labCaseId: task.labCaseId, taskId },
requiredPermission: 'TAB_TASKS_READ',
});
const clinicOrgId = task.labCase?.treatment?.organization?.id;
if (clinicOrgId) {
void this.userNotifications.notify({
organizationId: clinicOrgId,
type: UserNotificationType.TASK_COMPLETED,
href: `/treatment?labCaseId=${encodeURIComponent(task.labCaseId)}`,
actorUserId,
payload: { labCaseId: task.labCaseId, taskId },
requiredPermission: 'TAB_TREATMENT_READ',
labCaseIdForProviderScope: task.labCaseId,
});
}
}
const locale = normalizeCatalogLocale(localeInput);
const prosthesisLabels = await this.catalogLabels.resolveLabels(
CatalogEntityKind.PROSTHESIS_TYPE,