feat(analytics): add NeighborhoodScoreService with POI-based scoring and API endpoint

- Create INeighborhoodScoreService interface and implementation
- Score districts 0-100 across 6 categories: education, healthcare, transport, shopping, greenery, safety
- Calculate scores from POI data with configurable weights and max counts
- Add GetNeighborhoodScoreQuery handler with lazy calculation
- Add GET /analytics/neighborhoods/:district/score endpoint
- Wire service and handler into AnalyticsModule

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Ho Ngoc Hai
2026-04-16 05:21:28 +07:00
parent 5db3dfbda6
commit 30d3039b94
6 changed files with 214 additions and 0 deletions

View File

@@ -1,5 +1,6 @@
import { Module } from '@nestjs/common';
import { CqrsModule } from '@nestjs/cqrs';
import { GetNeighborhoodScoreHandler } from './application/queries/get-neighborhood-score/get-neighborhood-score.handler';
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';
@@ -20,6 +21,8 @@ import { PrismaValuationRepository } from './infrastructure/repositories/prisma-
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 { NEIGHBORHOOD_SCORE_SERVICE } from './domain/services/neighborhood-score.service';
import { NeighborhoodScoreServiceImpl } from './infrastructure/services/neighborhood-score.service';
import { PrismaAVMService } from './infrastructure/services/prisma-avm.service';
import { AnalyticsController } from './presentation/controllers/analytics.controller';
@@ -38,6 +41,7 @@ const QueryHandlers = [
BatchValuationHandler,
ValuationHistoryHandler,
ValuationComparisonHandler,
GetNeighborhoodScoreHandler,
];
const EventHandlers = [
@@ -59,6 +63,9 @@ const EventHandlers = [
PrismaAVMService,
{ provide: AVM_SERVICE, useClass: HttpAVMService },
// Neighborhood scoring
{ provide: NEIGHBORHOOD_SCORE_SERVICE, useClass: NeighborhoodScoreServiceImpl },
// Cron
MarketIndexCronService,