stats §8: CBS Curaçao collector (topic-page scrape, sha256 manifest, CPI since 1970 from PDF, GDP by industry, government finance, population since 1900, LFS, tourism) into cw_cbs_* + stats.obs region CUW; cw_cbcs_bop for manual uploads; weekly timer
Some checks failed
Deploy production / deploy (push) Has been cancelled

This commit is contained in:
2026-10-25 21:38:30 +00:00
parent 27a15f0428
commit ff1520ae8b
10 changed files with 34730 additions and 3 deletions

View File

@@ -369,3 +369,101 @@ export const statsEpLabelAgg = statsSchema.table(
},
(t) => [primaryKey({ columns: [t.snapshot, t.area, t.label] })]
);
// ── §8 Curaçao: CBS Curaçao files (hash-tracked) and CBCS manual uploads ───────────────────
/** One row per CBS Curaçao table: the file last imported and its hash (re-import on change). */
export const statsCwCbsFile = statsSchema.table('cw_cbs_file', {
url: text('url').primaryKey(),
topic: text('topic').notNull(),
filename: text('filename').notNull(),
sha256: text('sha256').notNull(),
fetchedAt: timestamptz('fetched_at').notNull().defaultNow()
});
export const statsCwCbsCpi = statsSchema.table('cw_cbs_cpi', {
period: date('period', { mode: 'string' }).primaryKey(),
cpiIndex: doublePrecision('cpi_index').notNull(),
inflMom: doublePrecision('infl_mom'),
inflYoy: doublePrecision('infl_yoy'),
/** CBS's inflation figure: change of the 12-month average index. */
infl12mAvg: doublePrecision('infl_12m_avg'),
base: text('base')
});
export const statsCwCbsGdpIndustry = statsSchema.table(
'cw_cbs_gdp_industry',
{
year: integer('year').notNull(),
/** ISIC 4 section(s), or GVA / TLS / GDP / REAL_GROWTH_PCT / NOMINAL_GROWTH_PCT. */
isic: text('isic').notNull(),
label: text('label').notNull(),
/** mln ANG (current prices); % for the *_PCT rows. */
mlnAng: doublePrecision('mln_ang'),
provisional: boolean('provisional').notNull().default(false)
},
(t) => [primaryKey({ columns: [t.year, t.isic] })]
);
export const statsCwCbsGovFinance = statsSchema.table(
'cw_cbs_gov_finance',
{
year: integer('year').notNull(),
/** R./E. + ESA code (R.D2, E.D1, …) or R.TOTAL / E.TOTAL. */
itemCode: text('item_code').notNull(),
label: text('label').notNull(),
mlnAng: doublePrecision('mln_ang'),
provisional: boolean('provisional').notNull().default(true)
},
(t) => [primaryKey({ columns: [t.year, t.itemCode] })]
);
export const statsCwCbsPopulation = statsSchema.table(
'cw_cbs_population',
{
year: integer('year').notNull(),
sex: text('sex').notNull(),
ageGroup: text('age_group').notNull(),
/** jan1, dec31 (before 1992), census, midyear. */
kind: text('kind').notNull(),
value: doublePrecision('value')
},
(t) => [primaryKey({ columns: [t.year, t.sex, t.ageGroup, t.kind] })]
);
export const statsCwCbsLfs = statsSchema.table(
'cw_cbs_lfs',
{
year: integer('year').notNull(),
sex: text('sex').notNull(),
ageGroup: text('age_group').notNull(),
measure: text('measure').notNull(),
value: doublePrecision('value')
},
(t) => [primaryKey({ columns: [t.year, t.sex, t.ageGroup, t.measure] })]
);
export const statsCwCbsTourism = statsSchema.table(
'cw_cbs_tourism',
{
period: date('period', { mode: 'string' }).notNull(),
/** cruise_calls, cruise_pax, daytrippers, nights, air_landings_scheduled, air_landings_civil. */
measure: text('measure').notNull(),
/** total or source market (north_america, europe, …). */
market: text('market').notNull(),
value: doublePrecision('value')
},
(t) => [primaryKey({ columns: [t.period, t.measure, t.market] })]
);
/** CBCS balance of payments: manual upload only (centralbank.cw blocks scripted access). */
export const statsCwCbcsBop = statsSchema.table(
'cw_cbcs_bop',
{
period: date('period', { mode: 'string' }).notNull(),
item: text('item').notNull(),
mlnAng: doublePrecision('mln_ang'),
uploadedAt: timestamptz('uploaded_at').notNull().defaultNow()
},
(t) => [primaryKey({ columns: [t.period, t.item] })]
);