← back to Govarbitrage
src/app/api/import/apify-govdeals/route.ts
29 lines
import { NextRequest, NextResponse } from "next/server";
import { fetchApifyDataset, fetchApifyLastRun } from "@/importers/apify-govdeals";
import { ingestMany } from "@/importers/ingest";
import { requireWrite } from "@/lib/auth";
export const dynamic = "force-dynamic";
export const maxDuration = 300;
// Ingest GovDeals listings scraped by Apify. READ-ONLY: pulls an already-finished
// dataset (?dataset=ID) or the actor's last successful run (free). Triggering a
// NEW Apify run costs money and is intentionally NOT exposed here — it stays a
// deliberate, cost-surfaced action. ?ai=1 runs local Ollama identification.
export async function POST(req: NextRequest) {
const denied = await requireWrite(req);
if (denied) return denied;
try {
const datasetId = req.nextUrl.searchParams.get("dataset") || undefined;
const useAI = req.nextUrl.searchParams.get("ai") === "1";
const rows = datasetId ? await fetchApifyDataset(datasetId) : await fetchApifyLastRun();
const results = await ingestMany(rows, { useAI });
const created = results.filter((r) => r.ok && r.created).length;
const updated = results.filter((r) => r.ok && !r.created).length;
const failed = results.filter((r) => !r.ok).length;
return NextResponse.json({ source: "GOVDEALS", via: "apify", fetched: rows.length, created, updated, failed });
} catch (e) {
return NextResponse.json({ error: (e as Error).message }, { status: 502 });
}
}