feat(analytics): integrate AI/ML services — AVM endpoint, moderation pipeline, market index cron
- Add AiServiceClient HTTP client for Python FastAPI AI service with timeout and fallback - Add HttpAVMService that calls Python AVM endpoint, falls back to PrismaAVMService on failure - Add ListingCreatedModerationHandler: auto-flags suspicious listings via AI moderation on create - Add MarketIndexCronService: daily cron job aggregating market stats per district/city/type - Wire ScheduleModule and new providers into AnalyticsModule and AppModule - Add unit tests for AiServiceClient, HttpAVMService, and moderation handler (all passing) Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
@@ -3,6 +3,7 @@ import { CqrsModule } from '@nestjs/cqrs';
|
||||
import { GenerateReportHandler } from './application/commands/generate-report/generate-report.handler';
|
||||
import { TrackEventHandler } from './application/commands/track-event/track-event.handler';
|
||||
import { UpdateMarketIndexHandler } from './application/commands/update-market-index/update-market-index.handler';
|
||||
import { ListingCreatedModerationHandler } from './application/event-handlers/listing-created-moderation.handler';
|
||||
import { GetDistrictStatsHandler } from './application/queries/get-district-stats/get-district-stats.handler';
|
||||
import { GetHeatmapHandler } from './application/queries/get-heatmap/get-heatmap.handler';
|
||||
import { GetMarketReportHandler } from './application/queries/get-market-report/get-market-report.handler';
|
||||
@@ -13,6 +14,9 @@ import { VALUATION_REPOSITORY } from './domain/repositories/valuation.repository
|
||||
import { AVM_SERVICE } from './domain/services/avm-service';
|
||||
import { PrismaMarketIndexRepository } from './infrastructure/repositories/prisma-market-index.repository';
|
||||
import { PrismaValuationRepository } from './infrastructure/repositories/prisma-valuation.repository';
|
||||
import { AI_SERVICE_CLIENT, AiServiceClient } from './infrastructure/services/ai-service.client';
|
||||
import { HttpAVMService } from './infrastructure/services/http-avm.service';
|
||||
import { MarketIndexCronService } from './infrastructure/services/market-index-cron.service';
|
||||
import { PrismaAVMService } from './infrastructure/services/prisma-avm.service';
|
||||
import { AnalyticsController } from './presentation/controllers/analytics.controller';
|
||||
|
||||
@@ -30,19 +34,33 @@ const QueryHandlers = [
|
||||
GetValuationHandler,
|
||||
];
|
||||
|
||||
const EventHandlers = [
|
||||
ListingCreatedModerationHandler,
|
||||
];
|
||||
|
||||
@Module({
|
||||
imports: [CqrsModule],
|
||||
controllers: [AnalyticsController],
|
||||
providers: [
|
||||
// AI service client
|
||||
{ provide: AI_SERVICE_CLIENT, useClass: AiServiceClient },
|
||||
|
||||
// Repositories
|
||||
{ provide: MARKET_INDEX_REPOSITORY, useClass: PrismaMarketIndexRepository },
|
||||
{ provide: VALUATION_REPOSITORY, useClass: PrismaValuationRepository },
|
||||
{ provide: AVM_SERVICE, useClass: PrismaAVMService },
|
||||
|
||||
// AVM: HttpAVMService calls Python AI first, falls back to PrismaAVMService
|
||||
PrismaAVMService,
|
||||
{ provide: AVM_SERVICE, useClass: HttpAVMService },
|
||||
|
||||
// Cron
|
||||
MarketIndexCronService,
|
||||
|
||||
// CQRS
|
||||
...CommandHandlers,
|
||||
...QueryHandlers,
|
||||
...EventHandlers,
|
||||
],
|
||||
exports: [MARKET_INDEX_REPOSITORY, VALUATION_REPOSITORY, AVM_SERVICE],
|
||||
exports: [MARKET_INDEX_REPOSITORY, VALUATION_REPOSITORY, AVM_SERVICE, AI_SERVICE_CLIENT],
|
||||
})
|
||||
export class AnalyticsModule {}
|
||||
|
||||
Reference in New Issue
Block a user