stats: /stats/countries comparison and /stats/countries/[iso3] profiles (Curaçao via World Bank), more WB indicators, Countries + Curaçao cards, nav/sitemap/start links
All checks were successful
Deploy production / deploy (push) Successful in 1m13s
All checks were successful
Deploy production / deploy (push) Successful in 1m13s
This commit is contained in:
@@ -25,6 +25,8 @@ export type StatSeries = {
|
||||
region: string | null;
|
||||
sourceId: string;
|
||||
points: StatPoint[];
|
||||
/** First forecast year (IMF WEO vintages); points from that year on are projections. */
|
||||
forecastFrom?: number;
|
||||
};
|
||||
export type SeriesRequest = {
|
||||
id: string;
|
||||
@@ -48,8 +50,10 @@ export async function loadSeries(
|
||||
freq: string;
|
||||
region_code: string | null;
|
||||
source_id: string;
|
||||
forecast_from: string | null;
|
||||
}[]
|
||||
>`select series_id, title, unit, freq, region_code, source_id from stats.series
|
||||
>`select series_id, title, unit, freq, region_code, source_id, meta->>'forecastFrom' as forecast_from
|
||||
from stats.series
|
||||
where series_id = any(${reqs.map((r) => r.id)})`;
|
||||
const out: Record<string, StatSeries> = {};
|
||||
await Promise.all(
|
||||
@@ -72,6 +76,7 @@ export async function loadSeries(
|
||||
freq: m.freq,
|
||||
region: m.region_code,
|
||||
sourceId: m.source_id,
|
||||
...(m.forecast_from ? { forecastFrom: Number(m.forecast_from) } : {}),
|
||||
points: rows.map((r) => [r.period, Math.round(r.value * 1e6) / 1e6])
|
||||
};
|
||||
})
|
||||
@@ -181,3 +186,15 @@ export async function loadCbsCross(
|
||||
}
|
||||
return [...byCode.values()].sort((a, b) => a.code.localeCompare(b.code));
|
||||
}
|
||||
|
||||
export type LatestValue = { period: string; value: number };
|
||||
/** Latest observed (non-forecast) value per series; missing ids are absent. */
|
||||
export async function loadLatest(ids: string[]): Promise<Record<string, LatestValue>> {
|
||||
if (!ids.length) return {};
|
||||
const rows = await client<{ series_id: string; period: string; value: number }[]>`
|
||||
select distinct on (series_id) series_id, to_char(period, 'YYYY-MM-DD') as period, value
|
||||
from stats.obs
|
||||
where series_id = any(${ids}) and value is not null and status is distinct from 'forecast'
|
||||
order by series_id, period desc`;
|
||||
return Object.fromEntries(rows.map((r) => [r.series_id, { period: r.period, value: r.value }]));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user