Files
0pt/app/api/estimates/route.ts
T

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