← 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 });
  }
}