60 lines
3.0 KiB
TypeScript
60 lines
3.0 KiB
TypeScript
import { NextRequest, NextResponse } from "next/server";
|
|
import { engineFetch } from "@/lib/engine";
|
|
|
|
// POST /api/ai/parse (docs/04) — natural-language need -> prefilled order config.
|
|
// Uses the engine's LLM when available; otherwise a transparent keyword heuristic.
|
|
const MARKETS: [RegExp, string][] = [
|
|
[/sverige|svensk|\bse\b/i, "SE"], [/norge|norsk|\bno\b/i, "NO"], [/danmark|dansk|\bdk\b/i, "DK"],
|
|
[/finland|finsk|\bfi\b/i, "FI"], [/tyskland|\bde\b/i, "DE"], [/storbritannien|\buk\b|\bgb\b/i, "GB"],
|
|
];
|
|
const SERVICE: [RegExp, string][] = [
|
|
[/skrap|scrap/i, "scraping"], [/mappa|matcha|match|koppla/i, "mapping"],
|
|
[/normaliser|städ|dedup|tvätta/i, "normalization"], [/konsolider|crm|erp|hubspot|salesforce|dynamics|pipedrive|fivecrm/i, "consolidation"],
|
|
[/dokument|ocr|pdf|scann/i, "documents"], [/berik|enrich/i, "enrichment"],
|
|
[/\bicp\b|leads?|målgrupp|beslutsfattare/i, "icp"], [/\bml\b|modell|scoring|prognos|kluster/i, "ml"],
|
|
[/\bbi\b|dashboard|analys|marknadsanalys/i, "bi"], [/flöde|feed|övervak|freshness/i, "feeds"],
|
|
];
|
|
const FIELDS: [RegExp, string][] = [
|
|
[/e-?post|email|mejl|kontakt|telefon/i, "contact"], [/omsättning|finans|bokslut|resultat|nyckeltal/i, "financials"],
|
|
[/lei|cross-?border/i, "lei"], [/huvudman|ubo|ägar/i, "ubo"], [/intent|köpsignal|signal/i, "intent"],
|
|
];
|
|
const DEST: [RegExp, string][] = [
|
|
[/hubspot/i, "HubSpot"], [/salesforce/i, "Salesforce"], [/dynamics/i, "Microsoft Dynamics"],
|
|
[/pipedrive/i, "Pipedrive"], [/fivecrm/i, "FiveCRM"], [/sheets/i, "Google Sheets"],
|
|
];
|
|
|
|
export async function POST(req: NextRequest) {
|
|
const parsed = await req.json().catch(() => ({ text: "" }));
|
|
const body = parsed && typeof parsed === "object" ? parsed : { text: "" };
|
|
const { text } = body as { text?: string };
|
|
if (!text) return NextResponse.json({ error: { code: "bad_request", message: "text krävs" } }, { status: 400 });
|
|
|
|
const eng = await engineFetch("/ai/parse", { method: "POST", body: JSON.stringify({ text }) });
|
|
if (eng && eng.ok) return NextResponse.json(await eng.json());
|
|
|
|
const pick = (table: [RegExp, string][]) => table.filter(([re]) => re.test(text)).map(([, v]) => v);
|
|
const markets = [...new Set(pick(MARKETS))];
|
|
const service = pick(SERVICE)[0] ?? "data";
|
|
const fields = [...new Set(pick(FIELDS))];
|
|
const destination = pick(DEST)[0] ?? null;
|
|
const volMatch = text.replace(/\s/g, "").match(/(\d{3,})/);
|
|
const volume = volMatch ? Math.min(1_000_000, parseInt(volMatch[1], 10)) : 5000;
|
|
|
|
return NextResponse.json({
|
|
config: {
|
|
service_type: service,
|
|
markets: markets.length ? markets : ["SE"],
|
|
type: "Bolag",
|
|
fieldIds: fields.length ? fields : ["lei"],
|
|
enrichmentIds: [],
|
|
volume,
|
|
frequency: service === "feeds" || service === "enrichment" ? "Veckovis" : "Engångs",
|
|
confidence: 92,
|
|
destination,
|
|
description: text,
|
|
},
|
|
rationale: `Tolkat som ${service}${markets.length ? ` · ${markets.join(", ")}` : ""}${destination ? ` · ${destination}` : ""}. Justera fritt.`,
|
|
heuristic: true,
|
|
});
|
|
}
|