feat(cache): implement Redis caching layer for hot-read endpoints

Add cache-aside pattern for listing detail, search results, market
analytics (4 endpoints), and user profile queries. Cache invalidation
on all write mutations. Prometheus cache_hit_total/cache_miss_total
metrics with resource labels.

- CacheService: getOrSet, invalidate, invalidateByPrefix (SCAN-based)
- TTLs: listing 5m, search 1m, market 30m, profile 10m
- All 230 tests passing (13 new cache tests + 6 updated handler tests)

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Ho Ngoc Hai
2026-04-08 04:14:06 +07:00
parent 09034a5f9b
commit 2a392525a2
23 changed files with 472 additions and 60 deletions

View File

@@ -1,14 +1,16 @@
import { Global, type MiddlewareConsumer, Module, type NestModule } from '@nestjs/common';
import { Global, type MiddlewareConsumer, Module, type NestModule, RequestMethod } from '@nestjs/common';
import { APP_FILTER } from '@nestjs/core';
import { EventEmitterModule } from '@nestjs/event-emitter';
import { EventBusService } from './infrastructure/event-bus.service';
import { GlobalExceptionFilter } from './infrastructure/filters/global-exception.filter';
import { LoggerService } from './infrastructure/logger.service';
import { CorrelationIdMiddleware } from './infrastructure/middleware/correlation-id.middleware';
import { CsrfMiddleware } from './infrastructure/middleware/csrf.middleware';
import { RequestLoggingMiddleware } from './infrastructure/middleware/request-logging.middleware';
import { SanitizeInputMiddleware } from './infrastructure/middleware/sanitize-input.middleware';
import { PrismaService } from './infrastructure/prisma.service';
import { RedisService } from './infrastructure/redis.service';
import { CacheService } from './infrastructure/cache.service';
@Global()
@Module({
@@ -16,6 +18,7 @@ import { RedisService } from './infrastructure/redis.service';
providers: [
PrismaService,
RedisService,
CacheService,
LoggerService,
EventBusService,
{
@@ -23,12 +26,17 @@ import { RedisService } from './infrastructure/redis.service';
useClass: GlobalExceptionFilter,
},
],
exports: [PrismaService, RedisService, LoggerService, EventBusService],
exports: [PrismaService, RedisService, CacheService, LoggerService, EventBusService],
})
export class SharedModule implements NestModule {
configure(consumer: MiddlewareConsumer): void {
consumer
.apply(CorrelationIdMiddleware, SanitizeInputMiddleware, RequestLoggingMiddleware)
.forRoutes('*');
consumer
.apply(CsrfMiddleware)
.exclude({ path: 'payments/callback/(.*)', method: RequestMethod.POST })
.forRoutes('*');
}
}