// Adds Netherlands relevance to a refresh report (stdin JSON -> stdout JSON), so a "new // entries" ping can be limited to things that actually show up in NL. // // bun scripts/cars-import.ts --report-new | bun scripts/spotters-report-nl.ts cars // // Every new item (newModels / newTypes / newSpecies, matched by the /trackers/... url) gets // `nl` (its activity score in NL from .activity, 0 when none) and the report gets // `newInNl`: the same items with nl > 0, most active first. Needs DB_URL. Run after // scripts/spotters-activity.ts so new entries already have scores. import postgres from 'postgres'; const tracker = process.argv[2]; const CFG = { cars: { key: 'newModels', sql: "select a.score from cars.activity a join cars.models m on m.id = a.model_id join cars.brands b on b.id = m.brand_id where a.area = 'nl' and b.slug = $1 and m.slug = $2" }, planes: { key: 'newTypes', sql: "select a.score from planes.activity a join planes.types t on t.id = a.type_id join planes.makers m on m.id = t.maker_id where a.area = 'nl' and m.slug = $1 and t.slug = $2" }, trains: { key: 'newTypes', sql: "select a.score from trains.activity a join trains.types t on t.id = a.type_id join trains.makers m on m.id = t.maker_id where a.area = 'nl' and m.slug = $1 and t.slug = $2" }, wildlife: { key: 'newSpecies', sql: "select a.score from wildlife.activity a join wildlife.species s on s.id = a.species_id join wildlife.groups g on g.id = s.group_id where a.area = 'nl' and g.slug = $1 and s.slug = $2" } } as const; if (!(tracker in CFG)) { console.error( 'usage: bun scripts/spotters-report-nl.ts < report.json' ); process.exit(2); } const cfg = CFG[tracker as keyof typeof CFG]; const input = await new Response(Bun.stdin.stream()).text(); if (!input.trim()) process.exit(0); const report = JSON.parse(input) as Record; const items = (report[cfg.key] ?? []) as { url?: string; nl?: number }[]; const sql = postgres(process.env.DB_URL!, { max: 1 }); try { for (const item of items) { const path = item.url ? new URL(item.url, 'https://x').pathname : ''; const [a, b] = path.replace(/^\/trackers\/[a-z]+\//, '').split('/'); const [row] = a && b ? await sql.unsafe<{ score: number }[]>(cfg.sql, [a, b]) : []; item.nl = row ? Math.round(row.score * 10) / 10 : 0; } report.newInNl = items .filter((x) => (x.nl ?? 0) > 0) .toSorted((x, y) => (y.nl ?? 0) - (x.nl ?? 0)); } finally { await sql.end(); } console.log(JSON.stringify(report, null, 1));