import { Injectable } from '@nestjs/common'; import { ClsService } from 'nestjs-cls'; import { OrderStatus } from '@prisma/client'; import type { SubscribePayload, PendingCountResponse } from '@sar/api-interface'; import type { WorkspaceClsStore } from '../workspace/workspace.types'; import { PushService, type PushPayload } from './push.service'; @Injectable() export class NotificationsService { constructor( private readonly cls: ClsService, private readonly push: PushService, ) {} async subscribe(userId: string, role: string, dto: SubscribePayload): Promise { const prisma = this.cls.get('prisma'); if (!prisma) throw new Error('prisma não disponível no CLS'); await prisma.pushSubscription.upsert({ where: { endpoint: dto.endpoint }, update: { userId, role, p256dh: dto.keys.p256dh, auth: dto.keys.auth }, create: { userId, role, endpoint: dto.endpoint, p256dh: dto.keys.p256dh, auth: dto.keys.auth, }, }); } async unsubscribe(endpoint: string): Promise { const prisma = this.cls.get('prisma'); if (!prisma) throw new Error('prisma não disponível no CLS'); await prisma.pushSubscription.deleteMany({ where: { endpoint } }); } async pendingCount(userId: string, role: string): Promise { const prisma = this.cls.get('prisma'); if (!prisma) throw new Error('prisma não disponível no CLS'); if (role === 'supervisor' || role === 'manager' || role === 'admin') { const count = await prisma.order.count({ where: { status: OrderStatus.pending_approval, deletedAt: null }, }); return { count }; } return { count: 0 }; } // Envia push para todos os supervisores/managers/admin do workspace. async notifySupervisors(payload: PushPayload): Promise { const prisma = this.cls.get('prisma'); if (!prisma) return; const subs = await prisma.pushSubscription.findMany({ where: { role: { in: ['supervisor', 'manager', 'admin'] } }, }); await Promise.allSettled(subs.map((s) => this.push.send(s, payload))); } // Envia push para um userId específico (todos os dispositivos registrados). async notifyUser(userId: string, payload: PushPayload): Promise { const prisma = this.cls.get('prisma'); if (!prisma) return; const subs = await prisma.pushSubscription.findMany({ where: { userId } }); await Promise.allSettled(subs.map((s) => this.push.send(s, payload))); } }