mirror of
https://github.com/HamzaSha1/zod-backend.git
synced 2025-08-26 06:09:41 +00:00
feat: add loggers to all services
This commit is contained in:
@ -1,19 +1,23 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { Inject, Injectable, Logger } from '@nestjs/common';
|
||||
import { Cacheable } from 'cacheable';
|
||||
|
||||
@Injectable()
|
||||
export class CacheService {
|
||||
private readonly logger = new Logger(CacheService.name);
|
||||
constructor(@Inject('CACHE_INSTANCE') private readonly cache: Cacheable) {}
|
||||
|
||||
get<T>(key: string): Promise<T | undefined> {
|
||||
this.logger.log(`Getting value for key ${key}`);
|
||||
return this.cache.get(key);
|
||||
}
|
||||
|
||||
async set<T>(key: string, value: T, ttl?: number | string): Promise<void> {
|
||||
this.logger.log(`Setting value for key ${key}`);
|
||||
await this.cache.set(key, value, ttl);
|
||||
}
|
||||
|
||||
async delete(key: string): Promise<void> {
|
||||
this.logger.log(`Deleting value for key ${key}`);
|
||||
await this.cache.delete(key);
|
||||
}
|
||||
}
|
||||
|
@ -1,23 +1,27 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { DocumentType } from '~/document/enums';
|
||||
import { DocumentService, OciService } from '~/document/services';
|
||||
|
||||
@Injectable()
|
||||
export class LookupService {
|
||||
private readonly logger = new Logger(LookupService.name);
|
||||
constructor(private readonly documentService: DocumentService, private readonly ociService: OciService) {}
|
||||
async findDefaultAvatar() {
|
||||
this.logger.log(`Finding default avatar`);
|
||||
const documents = await this.documentService.findDocuments({ documentType: DocumentType.DEFAULT_AVATAR });
|
||||
|
||||
await Promise.all(
|
||||
documents.map(async (document) => {
|
||||
document.url = await this.ociService.generatePreSignedUrl(document);
|
||||
}),
|
||||
);
|
||||
|
||||
this.logger.log(`Default avatar returned successfully`);
|
||||
|
||||
return documents;
|
||||
}
|
||||
|
||||
async findDefaultTasksLogo() {
|
||||
this.logger.log(`Finding default tasks logos`);
|
||||
const documents = await this.documentService.findDocuments({ documentType: DocumentType.DEFAULT_TASKS_LOGO });
|
||||
|
||||
await Promise.all(
|
||||
@ -26,6 +30,7 @@ export class LookupService {
|
||||
}),
|
||||
);
|
||||
|
||||
this.logger.log(`Default tasks logos returned successfully`);
|
||||
return documents;
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import * as admin from 'firebase-admin';
|
||||
@Injectable()
|
||||
export class FirebaseService {
|
||||
private readonly logger = new Logger(FirebaseService.name);
|
||||
constructor(private readonly configService: ConfigService) {
|
||||
admin.initializeApp({
|
||||
credential: admin.credential.cert({
|
||||
@ -14,6 +15,7 @@ export class FirebaseService {
|
||||
}
|
||||
|
||||
sendNotification(tokens: string | string[], title: string, body: string) {
|
||||
this.logger.log(`Sending push notification to ${tokens}`);
|
||||
const message = {
|
||||
notification: {
|
||||
title,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { EventEmitter2, OnEvent } from '@nestjs/event-emitter';
|
||||
import { PageOptionsRequestDto } from '~/core/dtos';
|
||||
import { DeviceService } from '~/user/services';
|
||||
@ -13,6 +13,7 @@ import { TwilioService } from './twilio.service';
|
||||
|
||||
@Injectable()
|
||||
export class NotificationsService {
|
||||
private readonly logger = new Logger(NotificationsService.name);
|
||||
constructor(
|
||||
private readonly firebaseService: FirebaseService,
|
||||
private readonly notificationRepository: NotificationsRepository,
|
||||
@ -22,11 +23,13 @@ export class NotificationsService {
|
||||
) {}
|
||||
|
||||
async sendPushNotification(userId: string, title: string, body: string) {
|
||||
this.logger.log(`Sending push notification to user ${userId}`);
|
||||
// Get the device tokens for the user
|
||||
|
||||
const tokens = await this.deviceService.getTokens(userId);
|
||||
|
||||
if (!tokens.length) {
|
||||
this.logger.log(`No device tokens found for user ${userId} but notification created in the database`);
|
||||
return;
|
||||
}
|
||||
// Send the notification
|
||||
@ -34,27 +37,34 @@ export class NotificationsService {
|
||||
}
|
||||
|
||||
async sendSMS(to: string, body: string) {
|
||||
this.logger.log(`Sending SMS to ${to}`);
|
||||
await this.twilioService.sendSMS(to, body);
|
||||
}
|
||||
|
||||
async getNotifications(userId: string, pageOptionsDto: PageOptionsRequestDto) {
|
||||
this.logger.log(`Getting notifications for user ${userId}`);
|
||||
const [[notifications, count], unreadCount] = await Promise.all([
|
||||
this.notificationRepository.getNotifications(userId, pageOptionsDto),
|
||||
this.notificationRepository.getUnreadNotificationsCount(userId),
|
||||
]);
|
||||
|
||||
this.logger.log(`Returning notifications for user ${userId}`);
|
||||
|
||||
return { notifications, count, unreadCount };
|
||||
}
|
||||
|
||||
createNotification(notification: Partial<Notification>) {
|
||||
this.logger.log(`Creating notification for user ${notification.userId}`);
|
||||
return this.notificationRepository.createNotification(notification);
|
||||
}
|
||||
|
||||
markAsRead(userId: string) {
|
||||
this.logger.log(`Marking notifications as read for user ${userId}`);
|
||||
return this.notificationRepository.markAsRead(userId);
|
||||
}
|
||||
|
||||
async sendOtpNotification(sendOtpRequest: ISendOtp, otp: string) {
|
||||
this.logger.log(`Sending OTP to ${sendOtpRequest.recipient}`);
|
||||
const notification = await this.createNotification({
|
||||
recipient: sendOtpRequest.recipient,
|
||||
title: OTP_TITLE,
|
||||
@ -63,11 +73,16 @@ export class NotificationsService {
|
||||
channel: sendOtpRequest.otpType === OtpType.EMAIL ? NotificationChannel.EMAIL : NotificationChannel.SMS,
|
||||
});
|
||||
|
||||
this.logger.log(`emitting ${EventType.NOTIFICATION_CREATED} event`);
|
||||
|
||||
return this.eventEmitter.emit(EventType.NOTIFICATION_CREATED, notification);
|
||||
}
|
||||
|
||||
@OnEvent(EventType.NOTIFICATION_CREATED)
|
||||
handleNotificationCreatedEvent(notification: Notification) {
|
||||
this.logger.log(
|
||||
`Handling ${EventType.NOTIFICATION_CREATED} event for notification ${notification.id} and type ${notification.channel}`,
|
||||
);
|
||||
switch (notification.channel) {
|
||||
case NotificationChannel.SMS:
|
||||
return this.sendSMS(notification.recipient!, notification.message);
|
||||
|
@ -8,6 +8,7 @@ export class TwilioService {
|
||||
constructor(private readonly twilioService: TwilioApiService, private readonly configService: ConfigService) {}
|
||||
private from = this.configService.getOrThrow('TWILIO_PHONE_NUMBER');
|
||||
sendSMS(to: string, body: string) {
|
||||
this.logger.log(`Sending SMS to ${to}`);
|
||||
if (this.configService.get('NODE_ENV') === Environment.DEV) {
|
||||
this.logger.log(`Skipping SMS sending in DEV environment. Message: ${body} to: ${to}`);
|
||||
return;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { NotificationsService } from '../../notification/services/notifications.service';
|
||||
import { DEFAULT_OTP_DIGIT, DEFAULT_OTP_LENGTH } from '../constants';
|
||||
@ -9,27 +9,37 @@ import { generateRandomOtp } from '../utils';
|
||||
|
||||
@Injectable()
|
||||
export class OtpService {
|
||||
private readonly logger = new Logger(OtpService.name);
|
||||
constructor(
|
||||
private readonly configService: ConfigService,
|
||||
private readonly otpRepository: OtpRepository,
|
||||
private readonly notificationService: NotificationsService,
|
||||
) {}
|
||||
private useMock = this.configService.get<boolean>('USE_MOCK', false);
|
||||
async generateAndSendOtp(sendotpRequest: ISendOtp): Promise<string> {
|
||||
async generateAndSendOtp(sendOtpRequest: ISendOtp): Promise<string> {
|
||||
this.logger.log(`Generating OTP for ${sendOtpRequest.recipient}`);
|
||||
const otp = this.useMock ? DEFAULT_OTP_DIGIT.repeat(DEFAULT_OTP_LENGTH) : generateRandomOtp(DEFAULT_OTP_LENGTH);
|
||||
|
||||
await this.otpRepository.createOtp({ ...sendotpRequest, value: otp });
|
||||
await this.otpRepository.createOtp({ ...sendOtpRequest, value: otp });
|
||||
|
||||
this.sendOtp(sendotpRequest, otp);
|
||||
|
||||
return sendotpRequest.otpType == OtpType.EMAIL
|
||||
? sendotpRequest.recipient
|
||||
: sendotpRequest.recipient?.replace(/.(?=.{4})/g, '*');
|
||||
await this.sendOtp(sendOtpRequest, otp);
|
||||
this.logger.log(`OTP generated and sent successfully to ${sendOtpRequest.recipient}`);
|
||||
return sendOtpRequest.otpType == OtpType.EMAIL
|
||||
? sendOtpRequest.recipient
|
||||
: sendOtpRequest.recipient?.replace(/.(?=.{4})/g, '*');
|
||||
}
|
||||
|
||||
async verifyOtp(verifyOtpRequest: IVerifyOtp) {
|
||||
this.logger.log(`Verifying OTP for ${verifyOtpRequest.userId}`);
|
||||
const otp = await this.otpRepository.findOtp(verifyOtpRequest);
|
||||
|
||||
if (!otp) {
|
||||
this.logger.error(
|
||||
`OTP value ${verifyOtpRequest.value} not found for ${verifyOtpRequest.userId} and ${verifyOtpRequest.otpType}`,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
return !!otp;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user