mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
100 lines
3.4 KiB
TypeScript
100 lines
3.4 KiB
TypeScript
/* Throwaway harness: applies the operations migration to a scratch database and
|
|
* runs every operations report across several parameter sets. Delete after use. */
|
|
import { DataSource } from 'typeorm';
|
|
|
|
import { OperationsReporting3580000000000 } from '../migrations/3580000000000-OperationsReporting';
|
|
import { REPORTS } from '../modules/reports/report.registry';
|
|
import { ReportContext } from '../modules/reports/report.types';
|
|
|
|
const NEW_KEYS = [
|
|
'station-staying-time',
|
|
'turnaround-cycle',
|
|
'train-delays',
|
|
'trainset-performance',
|
|
'teu-performance',
|
|
'cargo-volume-performance',
|
|
'charged-vs-actual-volume',
|
|
'cargo-volume-by-station',
|
|
];
|
|
|
|
const PARAM_SETS: Record<string, unknown>[] = [
|
|
{},
|
|
{ period: 'month' },
|
|
{ period: 'quarter', direction: 'IMPORT' },
|
|
{ period: 'week', country: 'Djibouti' },
|
|
{ period: 'year', country: 'Ethiopia', categories: ['CONTAINER_IMPORT_MULTIMODAL', 'BULK'] },
|
|
{ dateFrom: '2020-01-01', dateTo: '2030-01-01', delayedOnly: 'true' },
|
|
{ trainNumber: 'X', origin: 'NAGAD', destination: 'KALITY' },
|
|
];
|
|
|
|
async function main(): Promise<void> {
|
|
const ds = new DataSource({
|
|
type: 'postgres',
|
|
host: 'localhost',
|
|
port: 5433,
|
|
username: 'nati',
|
|
password: 'password',
|
|
database: 'nati_wt_opsreport',
|
|
entities: ['src/**/*.entity.ts'],
|
|
synchronize: false,
|
|
logging: false,
|
|
});
|
|
await ds.initialize();
|
|
|
|
// Apply the migration's DDL by hand — this scratch database is not under
|
|
// migration control and only needs the two new tables and two columns.
|
|
const runner = ds.createQueryRunner();
|
|
await new OperationsReporting3580000000000().up(runner);
|
|
await runner.release();
|
|
console.log('migration applied\n');
|
|
|
|
let failures = 0;
|
|
for (const key of NEW_KEYS) {
|
|
const def = REPORTS.find((r) => r.key === key);
|
|
if (!def) {
|
|
console.log(`MISSING ${key}`);
|
|
failures++;
|
|
continue;
|
|
}
|
|
for (const [i, params] of PARAM_SETS.entries()) {
|
|
for (const directions of [null, ['IMPORT']] as (string[] | null)[]) {
|
|
const ctx: ReportContext = { ds, params, directions };
|
|
const label = `${key} [set ${i}${directions ? ' scoped' : ''}]`;
|
|
try {
|
|
const qb = def.query(ctx);
|
|
const rows = await qb.limit(5).getRawMany();
|
|
|
|
// The runner wraps every query for the total count — prove that works too.
|
|
const [sql, bound] = qb.getQueryAndParameters();
|
|
const counted = await ds.query(`SELECT COUNT(*)::int AS n FROM (${sql}) AS sub`, bound);
|
|
|
|
// Sorting: every sortable column must be a legal ORDER BY.
|
|
for (const col of def.columns.filter((c) => c.sortable)) {
|
|
await def
|
|
.query({ ds, params, directions })
|
|
.orderBy(col.sortExpr ?? `"${col.key}"`, 'DESC')
|
|
.limit(1)
|
|
.getRawMany();
|
|
}
|
|
|
|
const kpis = def.summary ? await def.summary(ctx) : [];
|
|
console.log(
|
|
`OK ${label.padEnd(50)} rows=${rows.length} total=${counted[0]?.n ?? '?'} kpis=${kpis
|
|
.map((k) => `${k.label}:${k.value}${k.unit ?? ''}`)
|
|
.join(' ')}`,
|
|
);
|
|
} catch (err) {
|
|
failures++;
|
|
console.log(`FAIL ${label}: ${(err as Error).message.split('\n')[0]}`);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
console.log(failures ? `\n${failures} failures` : '\nall checks passed');
|
|
await ds.destroy();
|
|
process.exit(failures ? 1 : 0);
|
|
}
|
|
|
|
void main();
|