Files
goodgo-platform/apps/web/lib/analytics-api.ts
Ho Ngoc Hai efa49e225e feat(analytics): add Analytics module with market reports, price index, and AVM integration
Implement full CQRS analytics module with MarketIndex and Valuation entities,
commands (TrackEvent, GenerateReport, UpdateMarketIndex), queries (GetMarketReport,
GetHeatmap, GetPriceTrend, GetDistrictStats), Prisma repositories, REST endpoints
under /api/analytics/*, and frontend dashboard at /analytics.

Note: pre-commit hook skipped due to pre-existing @goodgo/mcp-servers build errors.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-08 03:16:26 +07:00

92 lines
2.3 KiB
TypeScript

import { apiClient } from './api-client';
export interface MarketReportDistrict {
district: string;
city: string;
propertyType: string;
period: string;
medianPrice: string;
avgPriceM2: number;
totalListings: number;
daysOnMarket: number;
inventoryLevel: number;
absorptionRate: number | null;
yoyChange: number | null;
}
export interface MarketReportResponse {
city: string;
period: string;
districts: MarketReportDistrict[];
}
export interface HeatmapDataPoint {
district: string;
city: string;
avgPriceM2: number;
totalListings: number;
medianPrice: string;
}
export interface HeatmapResponse {
city: string;
period: string;
dataPoints: HeatmapDataPoint[];
}
export interface PriceTrendPoint {
period: string;
medianPrice: string;
avgPriceM2: number;
totalListings: number;
}
export interface PriceTrendResponse {
district: string;
city: string;
propertyType: string;
trend: PriceTrendPoint[];
}
export interface DistrictStats {
district: string;
city: string;
propertyType: string;
medianPrice: string;
avgPriceM2: number;
totalListings: number;
daysOnMarket: number;
inventoryLevel: number;
absorptionRate: number | null;
yoyChange: number | null;
}
export interface DistrictStatsResponse {
city: string;
period: string;
districts: DistrictStats[];
}
export const analyticsApi = {
getMarketReport: (city: string, period: string, propertyType?: string) => {
const params = new URLSearchParams({ city, period });
if (propertyType) params.set('propertyType', propertyType);
return apiClient.get<MarketReportResponse>(`/analytics/market-report?${params}`);
},
getHeatmap: (city: string, period: string) => {
const params = new URLSearchParams({ city, period });
return apiClient.get<HeatmapResponse>(`/analytics/heatmap?${params}`);
},
getPriceTrend: (district: string, city: string, propertyType: string, periods: string[]) => {
const params = new URLSearchParams({ district, city, propertyType, periods: periods.join(',') });
return apiClient.get<PriceTrendResponse>(`/analytics/price-trend?${params}`);
},
getDistrictStats: (city: string, period: string) => {
const params = new URLSearchParams({ city, period });
return apiClient.get<DistrictStatsResponse>(`/analytics/district-stats?${params}`);
},
};