50 lines
1.9 KiB
TypeScript
50 lines
1.9 KiB
TypeScript
import { NextRequest, NextResponse } from "next/server";
|
|
import { computeEstimate, type EntityType, type Frequency } from "@/lib/data";
|
|
import { engineFetch } from "@/lib/engine";
|
|
|
|
// POST /api/estimates (docs/04) — price/time/confidence for a configured job.
|
|
// Single source of truth for the estimate math; the configurator calls this.
|
|
export async function POST(req: NextRequest) {
|
|
let body: Record<string, unknown>;
|
|
try {
|
|
body = await req.json();
|
|
} catch {
|
|
return NextResponse.json({ error: { code: "bad_json", message: "Invalid JSON body" } }, { status: 400 });
|
|
}
|
|
if (!body || typeof body !== "object") {
|
|
return NextResponse.json({ error: { code: "bad_json", message: "Invalid JSON body" } }, { status: 400 });
|
|
}
|
|
|
|
// Defer to the FastAPI data engine when it's running; fall back to local math.
|
|
const eng = await engineFetch("/estimates", { method: "POST", body: JSON.stringify(body) });
|
|
if (eng && eng.ok) return NextResponse.json(await eng.json());
|
|
|
|
const markets = Array.isArray(body.markets) ? (body.markets as string[]) : [];
|
|
const entity_type = (body.entity_type as EntityType) || "Bolag";
|
|
const fields = Array.isArray(body.fields) ? (body.fields as string[]) : [];
|
|
const enrichment = Array.isArray(body.enrichment) ? (body.enrichment as string[]) : [];
|
|
const volume = Number(body.volume) || 1000;
|
|
const frequency = (body.frequency as Frequency) || "Engångs";
|
|
const confidence_target = Number(body.confidence_target) || 92;
|
|
|
|
const est = computeEstimate({
|
|
markets,
|
|
type: entity_type,
|
|
fieldIds: fields,
|
|
enrichmentIds: enrichment,
|
|
volume,
|
|
frequency,
|
|
confidence: confidence_target,
|
|
});
|
|
|
|
// amounts in öre (docs/03 convention)
|
|
return NextResponse.json({
|
|
total_ore: est.price * 100,
|
|
deposit_ore: est.deposit * 100,
|
|
balance_ore: est.remainder * 100,
|
|
est_days: est.timelineDays,
|
|
est_confidence: est.estConfidence / 100,
|
|
recurring: est.recurring,
|
|
});
|
|
}
|