mirror of
https://github.com/koala73/worldmonitor.git
synced 2026-04-25 17:14:57 +02:00
* chore(railway): add seed-sovereign-wealth to resilience-recovery bundle Wires the seeder landed in #3305 into the existing Railway cron service `seed-bundle-resilience-recovery`. One-line bundle entry; no new Railway service (the bundle pattern amortizes cron cost across the recovery-domain seeders). Config matches the rest of the bundle: - intervalMs: 30 * DAY (parity with CACHE_TTL_SECONDS=35d in the seeder + the quarterly manifest revision cadence) - timeoutMs: 600_000 (longer than peers because Tier 3b does N per-fund Wikipedia article fetches for any fund missing from the list article; today Temasek is the only miss but leaving headroom) After deploy, the next cron tick populates `resilience:recovery:sovereign-wealth:v1`, which then unblocks the follow-up PR that adds the scorer + dimension wiring. * fix(tests): update resilience-recovery bundle test for 6th entry Static-analysis test in tests/seed-bundle-resilience-recovery.test.mjs was hardcoded to `5 entries` / `all 5 entries use 30 * DAY`. Adding Sovereign-Wealth to the bundle (previous commit) made the count 6, breaking both assertions. Replaced hardcoded `5` with `EXPECTED_ENTRIES.length` so the next addition only requires appending to the allow-list at the top of the file (and the assertion message prompts the author to do that if the count drifts). Also appended the Sovereign-Wealth entry to the EXPECTED_ENTRIES list. 6566/6566 data-tier tests pass locally.
54 lines
2.7 KiB
JavaScript
54 lines
2.7 KiB
JavaScript
import { describe, it } from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { readFileSync, existsSync } from 'node:fs';
|
|
import { join, dirname } from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
const scriptsDir = join(__dirname, '..', 'scripts');
|
|
|
|
const bundleSource = readFileSync(join(scriptsDir, 'seed-bundle-resilience-recovery.mjs'), 'utf8');
|
|
|
|
const EXPECTED_ENTRIES = [
|
|
{ label: 'Fiscal-Space', script: 'seed-recovery-fiscal-space.mjs', seedMetaKey: 'resilience:recovery:fiscal-space' },
|
|
{ label: 'Reserve-Adequacy', script: 'seed-recovery-reserve-adequacy.mjs', seedMetaKey: 'resilience:recovery:reserve-adequacy' },
|
|
{ label: 'External-Debt', script: 'seed-recovery-external-debt.mjs', seedMetaKey: 'resilience:recovery:external-debt' },
|
|
{ label: 'Import-HHI', script: 'seed-recovery-import-hhi.mjs', seedMetaKey: 'resilience:recovery:import-hhi' },
|
|
{ label: 'Fuel-Stocks', script: 'seed-recovery-fuel-stocks.mjs', seedMetaKey: 'resilience:recovery:fuel-stocks' },
|
|
{ label: 'Sovereign-Wealth', script: 'seed-sovereign-wealth.mjs', seedMetaKey: 'resilience:recovery:sovereign-wealth' },
|
|
];
|
|
|
|
describe('seed-bundle-resilience-recovery', () => {
|
|
it(`has exactly ${EXPECTED_ENTRIES.length} entries`, () => {
|
|
const labelMatches = bundleSource.match(/label:\s*'[^']+'/g) ?? [];
|
|
assert.equal(labelMatches.length, EXPECTED_ENTRIES.length,
|
|
`Expected ${EXPECTED_ENTRIES.length} entries, found ${labelMatches.length}. ` +
|
|
`If you added a new seeder, update EXPECTED_ENTRIES above.`);
|
|
});
|
|
|
|
for (const entry of EXPECTED_ENTRIES) {
|
|
it(`contains entry for ${entry.label}`, () => {
|
|
assert.ok(bundleSource.includes(entry.label), `Missing label: ${entry.label}`);
|
|
assert.ok(bundleSource.includes(entry.script), `Missing script: ${entry.script}`);
|
|
assert.ok(bundleSource.includes(entry.seedMetaKey), `Missing seedMetaKey: ${entry.seedMetaKey}`);
|
|
});
|
|
|
|
it(`script ${entry.script} exists on disk`, () => {
|
|
const scriptPath = join(scriptsDir, entry.script);
|
|
assert.ok(existsSync(scriptPath), `Script not found: ${scriptPath}`);
|
|
});
|
|
}
|
|
|
|
it('all entries use 30 * DAY interval', () => {
|
|
const intervalMatches = bundleSource.match(/intervalMs:\s*30\s*\*\s*DAY/g) ?? [];
|
|
assert.equal(intervalMatches.length, EXPECTED_ENTRIES.length,
|
|
`Expected all ${EXPECTED_ENTRIES.length} entries to use 30 * DAY interval`);
|
|
});
|
|
|
|
it('imports runBundle and DAY from _bundle-runner.mjs', () => {
|
|
assert.ok(bundleSource.includes("from './_bundle-runner.mjs'"), 'Missing import from _bundle-runner.mjs');
|
|
assert.ok(bundleSource.includes('runBundle'), 'Missing runBundle import');
|
|
assert.ok(bundleSource.includes('DAY'), 'Missing DAY import');
|
|
});
|
|
});
|