feat: add area detail workspace

This commit is contained in:
2026-06-24 12:03:17 +08:00
parent db09615004
commit 6ca67e7555
6 changed files with 538 additions and 17 deletions

View File

@@ -219,6 +219,40 @@ export type AreaScoreLineage = {
score_computed_at: string;
};
export type AreaProfile = {
area_id: string;
name: string;
district: string;
segment: string;
notes: string;
};
export type AreaMonthlyMetric = {
area_id: string;
month: string;
transaction_count: number;
transaction_price_psm: number;
listing_count: number;
listing_price_psm: number;
median_days_on_market: number;
rent_price_psm: number;
new_supply_units: number;
land_residential_gfa_sqm: number;
mortgage_rate_pct: number;
policy_signal: number;
source: string;
ingestion_run_id: number | null;
raw_artifact_id: number | null;
};
export type AreaDetail = {
profile: AreaProfile;
current_score: AreaScore | null;
score_lineage: AreaScoreLineage | null;
monthly_metrics: AreaMonthlyMetric[];
neighborhood_scores: NeighborhoodScore[];
};
const API_BASE_URL =
process.env.NEXT_PUBLIC_API_BASE_URL?.replace(/\/$/, "") ?? "http://127.0.0.1:8080";
@@ -230,6 +264,12 @@ export async function fetchAreaScores(month: string): Promise<AreaScore[]> {
return fetchJson(`/api/v1/areas/scores?month=${encodeURIComponent(month)}`);
}
export async function fetchAreaDetail(areaId: string, month: string): Promise<AreaDetail> {
return fetchJson(
`/api/v1/areas/${encodeURIComponent(areaId)}/detail?month=${encodeURIComponent(month)}`,
);
}
export async function fetchNeighborhoodScores(month: string): Promise<NeighborhoodScore[]> {
return fetchJson(`/api/v1/neighborhoods/scores?month=${encodeURIComponent(month)}`);
}