← back to Govarbitrage
scripts/import-govdeals-free.ts
51 lines
// FREE daily GovDeals refresh — hits GovDeals' own backend API directly ($0,
// no Apify, no browser). Replaces the paid Apify path.
//
// Usage: npx tsx scripts/import-govdeals-free.ts [limit] (default 120)
import { fetchGovdealsFree } from "../src/importers/govdeals-free";
import { ingestMany } from "../src/importers/ingest";
import { prisma } from "../src/lib/db";
// Liquidity Services marketplaces, all on the same free API. GovDeals gets the
// most; the industrial siblings a smaller slice.
const MARKETS: { biz: string; limit: number }[] = [
{ biz: "GD", limit: Number(process.argv[2] || 120) },
{ biz: "GI", limit: 60 },
{ biz: "NI", limit: 60 },
];
async function main() {
let created = 0, updated = 0, failed = 0, fetched = 0, marketErrors = 0;
for (const { biz, limit } of MARKETS) {
console.log(`[${new Date().toISOString()}] Fetching ${limit} newest ${biz} listings (FREE maestro API)…`);
// Isolate each market: one market's transient failure must not abort the
// siblings in the same run.
try {
const rows = await fetchGovdealsFree({ limit, businessId: biz });
fetched += rows.length;
const results = await ingestMany(rows, { useAI: false });
created += results.filter((r) => r.ok && r.created).length;
updated += results.filter((r) => r.ok && !r.created).length;
failed += results.filter((r) => !r.ok).length;
} catch (e) {
marketErrors++;
console.error(` ✗ market ${biz} failed:`, e instanceof Error ? e.message : e);
}
}
console.log(`Done: fetched ${fetched}, ${created} created, ${updated} updated, ${failed} failed, ${marketErrors} market(s) errored. Cost: $0 (free API).`);
// Fail the run (non-zero exit) so a scheduler sees red when nothing was
// fetched or every market errored — not a false "success".
if (fetched === 0 || marketErrors === MARKETS.length) {
console.error(`[import-govdeals-free] RUN FAILED: fetched ${fetched}, ${marketErrors}/${MARKETS.length} markets errored.`);
process.exitCode = 1;
}
await prisma.$disconnect();
}
main().catch(async (e) => {
console.error("[import-govdeals-free] ERROR:", e.message);
await prisma.$disconnect();
process.exit(1);
});