feat(analytics): add GET /analytics/market-snapshot endpoint

Dashboard tile endpoint returning activeCount, avgPrice, medianPrice,
priceChangePct (1d/7d/30d), avgPricePerM2, daysOnMarket, newListings24h.
Redis cache-aside with 5min TTL. CQRS query handler with parallel
Prisma queries for p95 <200ms on cache hit.

Refs: TEC-3049

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Ho Ngoc Hai
2026-04-21 02:06:57 +07:00
parent d91e3f6fe2
commit bcd8b6685a
7 changed files with 366 additions and 0 deletions

View File

@@ -32,6 +32,8 @@ export const CacheTTL = {
PLAN_LIST: 3600, // 1 hour
/** Reference data (districts, wards) — very long TTL, static data */
REFERENCE_DATA: 86400, // 24 hours
/** Market snapshot — 5 min TTL, dashboard tile data */
MARKET_SNAPSHOT: 300, // 5 min
} as const;
export enum CachePrefix {
@@ -48,6 +50,7 @@ export enum CachePrefix {
PLAN_LIST = 'cache:plan:list',
REFERENCE = 'cache:reference',
AGENT_LISTINGS = 'cache:agent:listings',
MARKET_SNAPSHOT = 'cache:analytics:market_snapshot',
}
@Injectable()