feat(professionals): send FCM push notifications on status changes
Same events that trigger email (approve, deny, deactivate, setPending, upsert) now also call tryPush() to send a silent FCM push to the professional's device. NotificationsModule added to ProfessionalsModule imports. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
1f3efb50da
commit
749a1e860d
@@ -2,9 +2,10 @@ import { Module } from '@nestjs/common';
|
|||||||
import { ProfessionalsService } from './professionals.service';
|
import { ProfessionalsService } from './professionals.service';
|
||||||
import { ProfessionalsController } from './professionals.controller';
|
import { ProfessionalsController } from './professionals.controller';
|
||||||
import { AuthModule } from '../auth/auth.module';
|
import { AuthModule } from '../auth/auth.module';
|
||||||
|
import { NotificationsModule } from '../notifications/notifications.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [AuthModule],
|
imports: [AuthModule, NotificationsModule],
|
||||||
providers: [ProfessionalsService],
|
providers: [ProfessionalsService],
|
||||||
controllers: [ProfessionalsController],
|
controllers: [ProfessionalsController],
|
||||||
exports: [ProfessionalsService],
|
exports: [ProfessionalsService],
|
||||||
|
|||||||
@@ -1,10 +1,24 @@
|
|||||||
import { Injectable, NotFoundException, BadRequestException, ForbiddenException } from '@nestjs/common';
|
import { Injectable, NotFoundException, BadRequestException, ForbiddenException } from '@nestjs/common';
|
||||||
import { PrismaService } from '../prisma/prisma.service';
|
import { PrismaService } from '../prisma/prisma.service';
|
||||||
import { MailService } from '../mail/mail.service';
|
import { MailService } from '../mail/mail.service';
|
||||||
|
import { NotificationsService } from '../notifications/notifications.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ProfessionalsService {
|
export class ProfessionalsService {
|
||||||
constructor(private prisma: PrismaService, private mail: MailService) {}
|
constructor(
|
||||||
|
private prisma: PrismaService,
|
||||||
|
private mail: MailService,
|
||||||
|
private notifications: NotificationsService,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
private async tryPush(userId: string, title: string, body: string) {
|
||||||
|
try {
|
||||||
|
const u = await this.prisma.users.findUnique({
|
||||||
|
where: { id: userId }, select: { fcm_token: true },
|
||||||
|
});
|
||||||
|
if (u?.fcm_token) await this.notifications.send(u.fcm_token, title, body);
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
|
||||||
async findAllActive(page = 1, limit = 20, city?: string) {
|
async findAllActive(page = 1, limit = 20, city?: string) {
|
||||||
const skip = (page - 1) * limit;
|
const skip = (page - 1) * limit;
|
||||||
@@ -76,6 +90,7 @@ export class ProfessionalsService {
|
|||||||
const prof = await this.prisma.professionals.create({ data: { user_id: userId, is_active: false, ...data } });
|
const prof = await this.prisma.professionals.create({ data: { user_id: userId, is_active: false, ...data } });
|
||||||
const u = await this.prisma.users.findUnique({ where: { id: userId }, select: { name: true, email: true } });
|
const u = await this.prisma.users.findUnique({ where: { id: userId }, select: { name: true, email: true } });
|
||||||
if (u?.email) this.mail.sendProfessionalSubmitted(u.name || 'Usuario', u.email, data.profession || '').catch(() => {});
|
if (u?.email) this.mail.sendProfessionalSubmitted(u.name || 'Usuario', u.email, data.profession || '').catch(() => {});
|
||||||
|
this.tryPush(userId, 'Solicitud recibida', 'Hemos recibido tu solicitud profesional. Te avisaremos cuando sea revisada.');
|
||||||
return prof;
|
return prof;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,6 +102,7 @@ export class ProfessionalsService {
|
|||||||
this.prisma.users.update({ where: { id: userId }, data: { pro_state: 1 } }),
|
this.prisma.users.update({ where: { id: userId }, data: { pro_state: 1 } }),
|
||||||
]);
|
]);
|
||||||
if (user.email) this.mail.sendProfessionalSubmitted(user.name || 'Usuario', user.email, data.profession || '').catch(() => {});
|
if (user.email) this.mail.sendProfessionalSubmitted(user.name || 'Usuario', user.email, data.profession || '').catch(() => {});
|
||||||
|
this.tryPush(userId, 'Solicitud recibida', 'Hemos recibido tu solicitud profesional. Te avisaremos cuando sea revisada.');
|
||||||
return this.prisma.professionals.findUnique({ where: { user_id: userId } });
|
return this.prisma.professionals.findUnique({ where: { user_id: userId } });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,6 +181,7 @@ export class ProfessionalsService {
|
|||||||
]);
|
]);
|
||||||
const u = await this.prisma.users.findUnique({ where: { id: prof.user_id }, select: { name: true, email: true } });
|
const u = await this.prisma.users.findUnique({ where: { id: prof.user_id }, select: { name: true, email: true } });
|
||||||
if (u?.email) this.mail.sendStatusChanged(u.name || 'Profesional', u.email, 'approved').catch(() => {});
|
if (u?.email) this.mail.sendStatusChanged(u.name || 'Profesional', u.email, 'approved').catch(() => {});
|
||||||
|
this.tryPush(prof.user_id, '¡Solicitud aprobada! 🎉', 'Tu perfil profesional ha sido aprobado en ProsApp.');
|
||||||
return { message: 'Profesional aprobado' };
|
return { message: 'Profesional aprobado' };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,6 +195,7 @@ export class ProfessionalsService {
|
|||||||
]);
|
]);
|
||||||
const u = await this.prisma.users.findUnique({ where: { id: prof.user_id }, select: { name: true, email: true } });
|
const u = await this.prisma.users.findUnique({ where: { id: prof.user_id }, select: { name: true, email: true } });
|
||||||
if (u?.email) this.mail.sendStatusChanged(u.name || 'Profesional', u.email, 'rejected').catch(() => {});
|
if (u?.email) this.mail.sendStatusChanged(u.name || 'Profesional', u.email, 'rejected').catch(() => {});
|
||||||
|
this.tryPush(prof.user_id, 'Actualización de tu solicitud', 'Tu solicitud profesional fue rechazada. Puedes volver a intentarlo.');
|
||||||
return { message: 'Solicitud rechazada' };
|
return { message: 'Solicitud rechazada' };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,6 +214,7 @@ export class ProfessionalsService {
|
|||||||
]);
|
]);
|
||||||
const u = await this.prisma.users.findUnique({ where: { id: prof.user_id }, select: { name: true, email: true } });
|
const u = await this.prisma.users.findUnique({ where: { id: prof.user_id }, select: { name: true, email: true } });
|
||||||
if (u?.email) this.mail.sendStatusChanged(u.name || 'Profesional', u.email, 'deactivated').catch(() => {});
|
if (u?.email) this.mail.sendStatusChanged(u.name || 'Profesional', u.email, 'deactivated').catch(() => {});
|
||||||
|
this.tryPush(prof.user_id, 'Cuenta desactivada', 'Tu cuenta profesional ha sido desactivada.');
|
||||||
return { message: 'Profesional desactivado' };
|
return { message: 'Profesional desactivado' };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,6 +227,7 @@ export class ProfessionalsService {
|
|||||||
]);
|
]);
|
||||||
const u = await this.prisma.users.findUnique({ where: { id: prof.user_id }, select: { name: true, email: true } });
|
const u = await this.prisma.users.findUnique({ where: { id: prof.user_id }, select: { name: true, email: true } });
|
||||||
if (u?.email) this.mail.sendStatusChanged(u.name || 'Profesional', u.email, 'pending').catch(() => {});
|
if (u?.email) this.mail.sendStatusChanged(u.name || 'Profesional', u.email, 'pending').catch(() => {});
|
||||||
|
this.tryPush(prof.user_id, 'Solicitud en revisión', 'Tu solicitud está siendo revisada por el equipo de ProsApp.');
|
||||||
return { message: 'Profesional puesto en revisión' };
|
return { message: 'Profesional puesto en revisión' };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user