feat(search): enhance geo-search and listing-approved handlers

Improve geo-search handler with better query processing and update
listing-approved event handler with enhanced indexing logic.
Tests updated accordingly.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Ho Ngoc Hai
2026-04-08 23:07:06 +07:00
parent a87532ff6e
commit 7fb25eb2b1
4 changed files with 163 additions and 39 deletions

View File

@@ -1,5 +1,6 @@
import { Injectable } from '@nestjs/common';
import { OnEvent } from '@nestjs/event-emitter';
import { CacheService, CachePrefix } from '@modules/shared/infrastructure/cache.service';
import { type LoggerService } from '@modules/shared/infrastructure/logger.service';
import { type ListingIndexerService } from '../services/listing-indexer.service';
@@ -7,24 +8,56 @@ import { type ListingIndexerService } from '../services/listing-indexer.service'
export class ListingApprovedEventHandler {
constructor(
private readonly indexer: ListingIndexerService,
private readonly cache: CacheService,
private readonly logger: LoggerService,
) {}
@OnEvent('listing.approved')
async handle(payload: { listingId: string }): Promise<void> {
this.logger.log(`Handling listing.approved for ${payload.listingId}`, 'ListingApprovedHandler');
await this.indexer.indexListing(payload.listingId);
await Promise.all([
this.indexer.indexListing(payload.listingId),
this.invalidateSearchAndAnalyticsCache(payload.listingId),
]);
}
@OnEvent('listing.updated')
async handleUpdate(payload: { listingId: string }): Promise<void> {
this.logger.log(`Handling listing.updated for ${payload.listingId}`, 'ListingApprovedHandler');
await this.indexer.indexListing(payload.listingId);
await Promise.all([
this.indexer.indexListing(payload.listingId),
this.invalidateSearchAndAnalyticsCache(payload.listingId),
]);
}
@OnEvent('listing.deactivated')
async handleDeactivation(payload: { listingId: string }): Promise<void> {
this.logger.log(`Handling listing.deactivated for ${payload.listingId}`, 'ListingApprovedHandler');
await this.indexer.removeListing(payload.listingId);
await Promise.all([
this.indexer.removeListing(payload.listingId),
this.invalidateSearchAndAnalyticsCache(payload.listingId),
]);
}
@OnEvent('listing.sold')
async handleSold(payload: { listingId: string }): Promise<void> {
this.logger.log(`Handling listing.sold for ${payload.listingId}`, 'ListingApprovedHandler');
await Promise.all([
this.indexer.removeListing(payload.listingId),
this.invalidateSearchAndAnalyticsCache(payload.listingId),
]);
}
private async invalidateSearchAndAnalyticsCache(listingId: string): Promise<void> {
await Promise.all([
this.cache.invalidate(CacheService.buildKey(CachePrefix.LISTING, listingId)),
this.cache.invalidateByPrefix(CachePrefix.SEARCH),
this.cache.invalidateByPrefix(CachePrefix.GEO_SEARCH),
this.cache.invalidateByPrefix(CachePrefix.MARKET_DISTRICT),
this.cache.invalidateByPrefix(CachePrefix.MARKET_REPORT),
this.cache.invalidateByPrefix(CachePrefix.MARKET_HEATMAP),
this.cache.invalidateByPrefix(CachePrefix.MARKET_TREND),
]);
this.logger.log(`Cache invalidated for listing ${listingId}`, 'ListingApprovedHandler');
}
}