From dbdb568d3f7dbbc39b60980c3660b1e9f37df1cf Mon Sep 17 00:00:00 2001 From: Naufil Asar Date: Sun, 28 Jul 2024 16:08:39 +0530 Subject: [PATCH] refactor(api): optimize user cache implementation and improve code structure --- apps/api/src/app/app.module.ts | 4 ++- apps/api/src/auth/auth.module.ts | 4 +-- .../auth/controller/auth.controller.spec.ts | 4 ++- apps/api/src/auth/guard/auth/auth.guard.ts | 1 - .../api/src/auth/service/auth.service.spec.ts | 4 ++- apps/api/src/auth/service/auth.service.ts | 6 +++-- apps/api/src/cache/cache.service.ts | 26 ++++++++++++------- 7 files changed, 31 insertions(+), 18 deletions(-) diff --git a/apps/api/src/app/app.module.ts b/apps/api/src/app/app.module.ts index 2f492558..0bc84ee0 100644 --- a/apps/api/src/app/app.module.ts +++ b/apps/api/src/app/app.module.ts @@ -23,6 +23,7 @@ import { ScheduleModule } from '@nestjs/schedule' import { EnvSchema } from '../common/env/env.schema' import { IntegrationModule } from '../integration/integration.module' import { FeedbackModule } from '../feedback/feedback.module' +import { CacheModule } from '../cache/cache.module' @Module({ controllers: [AppController], @@ -53,7 +54,8 @@ import { FeedbackModule } from '../feedback/feedback.module' SocketModule, ProviderModule, IntegrationModule, - FeedbackModule + FeedbackModule, + CacheModule ], providers: [ { diff --git a/apps/api/src/auth/auth.module.ts b/apps/api/src/auth/auth.module.ts index c2f07fac..00197f1c 100644 --- a/apps/api/src/auth/auth.module.ts +++ b/apps/api/src/auth/auth.module.ts @@ -9,7 +9,6 @@ import { GoogleOAuthStrategyFactory } from '../config/factory/google/google-stra import { GoogleStrategy } from '../config/oauth-strategy/google/google.strategy' import { GitlabOAuthStrategyFactory } from '../config/factory/gitlab/gitlab-strategy.factory' import { GitlabStrategy } from '../config/oauth-strategy/gitlab/gitlab.strategy' -import { CacheModule } from '../cache/cache.module' @Module({ imports: [ @@ -22,8 +21,7 @@ import { CacheModule } from '../cache/cache.module' algorithm: 'HS256' } }), - UserModule, - CacheModule + UserModule ], providers: [ AuthService, diff --git a/apps/api/src/auth/controller/auth.controller.spec.ts b/apps/api/src/auth/controller/auth.controller.spec.ts index d51abbd4..b177f376 100644 --- a/apps/api/src/auth/controller/auth.controller.spec.ts +++ b/apps/api/src/auth/controller/auth.controller.spec.ts @@ -10,6 +10,7 @@ import { ConfigService } from '@nestjs/config' import { GithubOAuthStrategyFactory } from '../../config/factory/github/github-strategy.factory' import { GoogleOAuthStrategyFactory } from '../../config/factory/google/google-strategy.factory' import { GitlabOAuthStrategyFactory } from '../../config/factory/gitlab/gitlab-strategy.factory' +import { CacheService } from '../../cache/cache.service' describe('AuthController', () => { let controller: AuthController @@ -25,7 +26,8 @@ describe('AuthController', () => { ConfigService, { provide: MAIL_SERVICE, useClass: MockMailService }, JwtService, - PrismaService + PrismaService, + CacheService ] }) .overrideProvider(PrismaService) diff --git a/apps/api/src/auth/guard/auth/auth.guard.ts b/apps/api/src/auth/guard/auth/auth.guard.ts index 919adffd..c0248c55 100644 --- a/apps/api/src/auth/guard/auth/auth.guard.ts +++ b/apps/api/src/auth/guard/auth/auth.guard.ts @@ -144,7 +144,6 @@ export class AuthGuard implements CanActivate { throw new UnauthorizedException('Onboarding not finished') } - if (user) this.cache.setUser(user) // We attach the user to the request object. request['user'] = user return true diff --git a/apps/api/src/auth/service/auth.service.spec.ts b/apps/api/src/auth/service/auth.service.spec.ts index 57c89764..6e12d18e 100644 --- a/apps/api/src/auth/service/auth.service.spec.ts +++ b/apps/api/src/auth/service/auth.service.spec.ts @@ -5,6 +5,7 @@ import { MAIL_SERVICE } from '../../mail/services/interface.service' import { JwtService } from '@nestjs/jwt' import { PrismaService } from '../../prisma/prisma.service' import { mockDeep } from 'jest-mock-extended' +import { CacheService } from '../../cache/cache.service' describe('AuthService', () => { let service: AuthService @@ -15,7 +16,8 @@ describe('AuthService', () => { AuthService, { provide: MAIL_SERVICE, useClass: MockMailService }, JwtService, - PrismaService + PrismaService, + CacheService ] }) .overrideProvider(PrismaService) diff --git a/apps/api/src/auth/service/auth.service.ts b/apps/api/src/auth/service/auth.service.ts index 5dac0e89..1c82a738 100644 --- a/apps/api/src/auth/service/auth.service.ts +++ b/apps/api/src/auth/service/auth.service.ts @@ -18,6 +18,7 @@ import { PrismaService } from '../../prisma/prisma.service' import createUser from '../../common/create-user' import { AuthProvider } from '@prisma/client' import generateOtp from '../../common/generate-otp' +import { CacheService } from '../../cache/cache.service' @Injectable() export class AuthService { @@ -26,7 +27,8 @@ export class AuthService { constructor( @Inject(MAIL_SERVICE) private mailService: IMailService, private readonly prisma: PrismaService, - private jwt: JwtService + private jwt: JwtService, + private cache: CacheService ) { this.logger = new Logger(AuthService.name) } @@ -82,7 +84,7 @@ export class AuthService { } } }) - + this.cache.setUser(user) // Save user to cache this.logger.log(`User logged in: ${email}`) const token = await this.generateToken(user.id) diff --git a/apps/api/src/cache/cache.service.ts b/apps/api/src/cache/cache.service.ts index fccf7e77..11456d56 100644 --- a/apps/api/src/cache/cache.service.ts +++ b/apps/api/src/cache/cache.service.ts @@ -1,22 +1,30 @@ -import { Injectable, OnModuleDestroy } from '@nestjs/common' +import { Injectable, Logger, OnModuleDestroy } from '@nestjs/common' import { createClient, RedisClientType } from 'redis' import { User } from '@prisma/client' @Injectable() export class CacheService implements OnModuleDestroy { private readonly redisClient: RedisClientType - private readonly userPrefix = 'user-' + private static readonly USER_PREFIX = 'user-' + private readonly logger = new Logger(CacheService.name) constructor() { - this.redisClient = createClient({ - url: 'redis://localhost:6379' // Replace with your Redis URL - // Add other Redis configuration options as needed - }) - this.redisClient.connect() + if (process.env.REDIS_URL) { + this.redisClient = createClient({ + url: process.env.REDIS_URL + }) + this.redisClient.connect().catch((error) => { + this.logger.error('Failed to connect to Redis', error) + }) + } else { + this.logger.warn( + 'REDIS_URL is not set. CacheService will not be functional.' + ) + } } private getUserKey(userId: string): string { - return `${this.userPrefix}${userId}` + return `${CacheService.USER_PREFIX}${userId}` } async setUser(user: User, expirationInSeconds?: number): Promise { @@ -44,7 +52,7 @@ export class CacheService implements OnModuleDestroy { } async clearAllUserCache(): Promise { - const keys = await this.redisClient.keys(`${this.userPrefix}*`) + const keys = await this.redisClient.keys(`${CacheService.USER_PREFIX}*`) if (keys.length > 0) { await this.redisClient.del(keys) }