- Claude-Extraktion (PDF nativ/Bild, Structured Output, Konfidenzen, Volltext), FakeProvider - Plausibilitätsprüfung, Mapping Extraktion → Formular, Korrektur-Diff - Services Upload/Verarbeitung/Bestätigung/Verwerfen/Neu verarbeiten, Processor import-extraction - Stubs: storeFile (§4.3), findDuplicateCustomers (L1), createWorkOrder (L2) - Tests test-import-rules/-flow/-live, Beispiel-PDFs + Generator Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
63 lines
2.9 KiB
TypeScript
63 lines
2.9 KiB
TypeScript
// Lane L3 (Auftragsimport) — optional live test of the Claude extraction against a generated
|
|
// sample order confirmation. Runs ONLY when ANTHROPIC_API_KEY is set (costs tokens); otherwise
|
|
// it skips with exit 0 so the default gate stays offline.
|
|
//
|
|
// Lauf: ANTHROPIC_API_KEY=… npx tsx scripts/test-import-live.ts
|
|
|
|
import "dotenv/config";
|
|
import { getExtractionProvider } from "../src/server/ai/extraction/anthropic";
|
|
import { checkPlausibility } from "../src/lib/imports/plausibility";
|
|
import { buildPdf } from "./make-sample-pdfs";
|
|
|
|
async function main() {
|
|
if (!process.env.ANTHROPIC_API_KEY?.trim()) {
|
|
console.log("↷ übersprungen: kein ANTHROPIC_API_KEY gesetzt (Live-Extraktion gegen Claude).");
|
|
process.exit(0);
|
|
}
|
|
const provider = getExtractionProvider();
|
|
if (!provider) {
|
|
console.log("↷ übersprungen: AI_EXTRACTION_PROVIDER ist nicht anthropic.");
|
|
process.exit(0);
|
|
}
|
|
|
|
let failures = 0;
|
|
const ok = (cond: boolean, msg: string) => {
|
|
console.log(`${cond ? "✓" : "✗ FEHLER"} ${msg}`);
|
|
if (!cond) failures++;
|
|
};
|
|
|
|
const pdf = buildPdf([
|
|
[
|
|
{ text: "Kranich Haustechnik GmbH", size: 16, bold: true },
|
|
{ text: "Musterbau GmbH", gap: 40 },
|
|
{ text: "Hafenstraße 12" },
|
|
{ text: "20457 Hamburg" },
|
|
{ text: "Auftragsbestätigung", size: 14, bold: true, gap: 30 },
|
|
{ text: "Auftragsnummer: AB-2026-0815 Datum: 02.09.2026 Kundennummer: K-10042", gap: 20 },
|
|
{ text: "Bauvorhaben: Speicherhof, Am Kaiserkai 30, 20457 Hamburg" },
|
|
{ text: "Ausführung: 12.10.2026 bis 16.10.2026" },
|
|
{ text: "1 Wärmepumpe Aerotherm 12 kW WP-AT-12 1 Stk", gap: 20 },
|
|
{ text: "2 Kupferrohr 22 mm CU-22 24 m" },
|
|
],
|
|
]);
|
|
|
|
const started = Date.now();
|
|
const result = await provider.extract({ bytes: pdf, mimeType: "application/pdf", fileName: "live-sample.pdf" });
|
|
const { extraction } = checkPlausibility(result.extraction);
|
|
console.log(` Modell ${result.meta.model}, ${result.meta.inputTokens} in / ${result.meta.outputTokens} out, ${((Date.now() - started) / 1000).toFixed(1)} s`);
|
|
|
|
ok(result.text.includes("AB-2026-0815"), "(L1) full text contains the order number");
|
|
ok(extraction.companyName.value?.includes("Musterbau") === true, "(L2) customer company recognised (not the letterhead)");
|
|
ok(extraction.orderNumber.value === "AB-2026-0815" && extraction.orderNumber.confidence > 0.5, "(L3) order number with confidence");
|
|
ok(extraction.plannedStart.value === "2026-10-12", "(L4) German date normalised to ISO");
|
|
ok(extraction.siteAddress.value?.street?.includes("Kaiserkai") === true, "(L5) site address separated from customer address");
|
|
ok((extraction.positions.value ?? []).some((p) => p.quantity === 24 && p.isMaterial === true), "(L6) positions with quantity and material flag");
|
|
|
|
process.exit(failures === 0 ? 0 : 1);
|
|
}
|
|
|
|
main().catch((e) => {
|
|
console.error(e);
|
|
process.exit(1);
|
|
});
|