/opt/mawid/apps/api/src/whatsapp
NameSizeModeActions
owner-notifier.service.ts17450644editdlrm
wa-core.module.ts13520644editdlrm
wa-http.client.ts17360644editdlrm
wa-inbound.service.spec.ts50660644editdlrm
wa-inbound.service.ts54310644editdlrm
wa-outbound.worker.ts27230644editdlrm
wa-queue.ts4470644editdlrm
wa-sender.service.ts49590644editdlrm
wa-signature.spec.ts12640644editdlrm
wa-signature.ts6620644editdlrm
wa-types.ts16830644editdlrm
wa-webhook.controller.spec.ts26840644editdlrm
wa-webhook.controller.ts23080644editdlrm
wa-window.spec.ts8600644editdlrm
wa-window.ts5090644editdlrm
whatsapp.module.ts5790644editdlrm
Edit: /opt/mawid/apps/api/src/whatsapp/owner-notifier.service.ts (1745B)
import { Inject, Injectable, Logger } from '@nestjs/common'; import { PrismaService } from '../prisma/prisma.service'; import { WA_HTTP_CLIENT, type WaHttpClient } from './wa-http.client'; /** * Sends WhatsApp texts to the clinic OWNER (not a patient) — used for slot * refill notices (Phase 5) and the weekly summary (Phase 6). Owner number * comes from clinic.settings.ownerWaPhone; if unset, notifications are skipped. * * Sends directly through the HTTP client (no Message/Conversation rows — those * model patient conversations). Delivery is fire-and-forget; failures log. */ @Injectable() export class OwnerNotifierService { private readonly logger = new Logger(OwnerNotifierService.name); constructor( private readonly prisma: PrismaService, @Inject(WA_HTTP_CLIENT) private readonly http: WaHttpClient, ) {} async sendText(clinicId: string, text: string): Promise { const clinic = await this.prisma.clinic.findUnique({ where: { id: clinicId } }); if (!clinic) return; const ownerPhone = ((clinic.settings ?? {}) as { ownerWaPhone?: string }).ownerWaPhone; if (!ownerPhone || !clinic.waPhoneNumberId) { this.logger.log(`owner notification skipped for clinic ${clinicId} (no ownerWaPhone)`); return; } try { await this.http.send(clinic.waPhoneNumberId, { messaging_product: 'whatsapp', to: ownerPhone.replace(/^\+/, ''), type: 'text', text: { body: text }, }); await this.prisma.auditLog.create({ data: { clinicId, actor: 'system', action: 'owner:notified', meta: { text } }, }); } catch (err) { this.logger.warn(`owner notification failed for clinic ${clinicId}: ${String(err)}`); } } }