export type AreaScore = { area_id: string; name: string; district: string; segment: string; month: string; investment_score: number; recommendation: string; liquidity_score: number; momentum_score: number; rent_support_score: number; safety_margin_score: number; credit_support_score: number; supply_risk_score: number; valuation_pressure_score: number; transaction_count: number; transaction_price_psm: number; listing_count: number; listing_price_psm: number; rent_price_psm: number; median_days_on_market: number; annual_rent_yield_pct: number; listing_pressure_ratio: number; discount_pct: number; price_momentum_pct: number; volume_momentum_pct: number; }; export type AreaScoreSummary = { area_id: string; name: string; district: string; investment_score: number; recommendation: string; }; export type MarketOverview = { month: string; area_count: number; average_investment_score: number; average_rent_yield_pct: number; top_area: AreaScoreSummary | null; weakest_area: AreaScoreSummary | null; highest_supply_risk_area: AreaScoreSummary | null; }; export type WatchlistItem = { watchlist_item_id: number; neighborhood_id: string | null; area_id: string | null; target_price_psm: number | null; status: string; notes: string; }; export type CreateWatchlistItem = { area_id?: string; neighborhood_id?: string; target_price_psm?: number; notes?: string; }; const API_BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL?.replace(/\/$/, "") ?? "http://127.0.0.1:8080"; export async function fetchMarketOverview(month: string): Promise { return fetchJson(`/api/v1/market/overview?month=${encodeURIComponent(month)}`); } export async function fetchAreaScores(month: string): Promise { return fetchJson(`/api/v1/areas/scores?month=${encodeURIComponent(month)}`); } export async function fetchWatchlistItems(): Promise { return fetchJson("/api/v1/watchlist"); } export async function createWatchlistItem( payload: CreateWatchlistItem, ): Promise { return fetchJson("/api/v1/watchlist", { method: "POST", body: JSON.stringify(payload), }); } export async function archiveWatchlistItem(id: number): Promise { return fetchJson(`/api/v1/watchlist/${id}`, { method: "DELETE", }); } async function fetchJson(path: string, init?: RequestInit): Promise { const response = await fetch(`${API_BASE_URL}${path}`, { ...init, headers: { "Content-Type": "application/json", ...init?.headers, }, }); if (!response.ok) { throw new Error(`API request failed with ${response.status}`); } return response.json() as Promise; }