import { Injectable } from '@nestjs/common'; import { ClsService } from 'nestjs-cls'; import type { SubscribePayload, PendingCountResponse } from '@sar/api-interface'; import type { WorkspaceClsStore } from '../workspace/workspace.types'; import { PushService, type PushPayload } from './push.service'; // Situa: 1=Pendente Aprovação const SITUA_PENDENTE = 1; @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'); const idEmpresa = this.cls.get('idEmpresa'); const codVendedor = userId ? parseInt(userId, 10) : null; await prisma.pushSubscription.upsert({ where: { endpoint: dto.endpoint }, update: { codVendedor, idEmpresa, role, p256dh: dto.keys.p256dh, auth: dto.keys.auth, }, create: { codVendedor, idEmpresa, role, endpoint: dto.endpoint, p256dh: dto.keys.p256dh, auth: dto.keys.auth, }, }); } // Escopado ao dono: só remove subscription do próprio usuário — quem souber o // endpoint de terceiro não consegue desregistrá-lo. async unsubscribe(userId: string, endpoint: string): Promise { const prisma = this.cls.get('prisma'); if (!prisma) throw new Error('prisma não disponível no CLS'); const idEmpresa = this.cls.get('idEmpresa'); const codVendedor = userId ? parseInt(userId, 10) : null; await prisma.pushSubscription.deleteMany({ where: { endpoint, idEmpresa, codVendedor } }); } 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'); const idEmpresa = this.cls.get('idEmpresa'); if (role === 'supervisor' || role === 'manager' || role === 'admin') { const count = await prisma.pedido.count({ where: { situa: SITUA_PENDENTE, idEmpresa }, }); return { count }; } return { count: 0 }; } // Envia push para todos os supervisores/managers/admin da empresa. async notifySupervisors(payload: PushPayload): Promise { const prisma = this.cls.get('prisma'); if (!prisma) return; const idEmpresa = this.cls.get('idEmpresa'); const subs = await prisma.pushSubscription.findMany({ where: { idEmpresa, role: { in: ['supervisor', 'manager', 'admin'] }, }, }); await Promise.allSettled(subs.map((s) => this.push.send(s, payload))); } // Envia push para um codVendedor específico (todos os dispositivos registrados). async notifyUser(userId: string, payload: PushPayload): Promise { const prisma = this.cls.get('prisma'); if (!prisma) return; const idEmpresa = this.cls.get('idEmpresa'); const codVendedor = parseInt(userId, 10); const subs = await prisma.pushSubscription.findMany({ where: { idEmpresa, codVendedor }, }); await Promise.allSettled(subs.map((s) => this.push.send(s, payload))); } }