feat: add scenario analysis workspace
This commit is contained in:
@@ -415,6 +415,59 @@ export type SimilarNeighborhoodResponse = {
|
||||
items: SimilarNeighborhood[];
|
||||
};
|
||||
|
||||
export type ScenarioRun = {
|
||||
scenario_run_id: number;
|
||||
name: string;
|
||||
target_month: string;
|
||||
area_id: string | null;
|
||||
interest_rate_delta_bps: number;
|
||||
policy_signal_delta: number;
|
||||
supply_delta_pct: number;
|
||||
rent_delta_pct: number;
|
||||
notes: string;
|
||||
created_at: string;
|
||||
};
|
||||
|
||||
export type CreateScenarioRun = {
|
||||
name: string;
|
||||
target_month: string;
|
||||
area_id?: string;
|
||||
interest_rate_delta_bps: number;
|
||||
policy_signal_delta: number;
|
||||
supply_delta_pct: number;
|
||||
rent_delta_pct: number;
|
||||
notes?: string;
|
||||
};
|
||||
|
||||
export type ScenarioAreaResult = {
|
||||
area_id: string;
|
||||
name: string;
|
||||
district: string;
|
||||
baseline_score: number;
|
||||
projected_score: number;
|
||||
score_delta: number;
|
||||
baseline_price_psm: number;
|
||||
projected_price_psm: number;
|
||||
price_delta_pct: number;
|
||||
projected_rent_yield_pct: number;
|
||||
projected_liquidity_score: number;
|
||||
projected_supply_risk_score: number;
|
||||
recommendation: string;
|
||||
risk_notes: string[];
|
||||
};
|
||||
|
||||
export type ScenarioVariant = {
|
||||
key: string;
|
||||
name: string;
|
||||
assumptions: string[];
|
||||
items: ScenarioAreaResult[];
|
||||
};
|
||||
|
||||
export type ScenarioRunResponse = {
|
||||
run: ScenarioRun;
|
||||
variants: ScenarioVariant[];
|
||||
};
|
||||
|
||||
export type ComparisonMetricValue = {
|
||||
id: string;
|
||||
value: number | null;
|
||||
@@ -663,6 +716,29 @@ export async function fetchAreaScoreLineage(
|
||||
);
|
||||
}
|
||||
|
||||
export async function fetchScenarioRuns(filters: {
|
||||
target_month?: string;
|
||||
area_id?: string;
|
||||
} = {}): Promise<ScenarioRun[]> {
|
||||
const params = new URLSearchParams();
|
||||
for (const [key, value] of Object.entries(filters)) {
|
||||
if (value) {
|
||||
params.set(key, value);
|
||||
}
|
||||
}
|
||||
const query = params.toString();
|
||||
return fetchJson(`/api/v1/scenario-runs${query ? `?${query}` : ""}`);
|
||||
}
|
||||
|
||||
export async function createScenarioRun(
|
||||
payload: CreateScenarioRun,
|
||||
): Promise<ScenarioRunResponse> {
|
||||
return fetchJson("/api/v1/scenario-runs", {
|
||||
method: "POST",
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
}
|
||||
|
||||
async function fetchJson<T>(path: string, init?: RequestInit): Promise<T> {
|
||||
const response = await fetch(`${API_BASE_URL}${path}`, {
|
||||
...init,
|
||||
|
||||
Reference in New Issue
Block a user