SPB Git

Repository Public

route.ts 2.6 KB 36 lines typescript

1// Vrai-Prix — admin méthode du coût : correspondances produit ↔ article (liste, création manuelle).2import { NextRequest, NextResponse } from "next/server";3import { adminAuth } from "@/lib/cost/connectors/admin";4import { getCostDb, sourceIdByKey } from "@/lib/cost/db";5import { reviewMapping } from "@/lib/cost/connectors/matching";6import { isRunnable } from "@/lib/cost/connectors/registry";78export const runtime = "nodejs";910export function GET(req: NextRequest) {11  const denied = adminAuth(req);12  if (denied) return denied;13  const status = req.nextUrl.searchParams.get("status");14  const rows = getCostDb().prepare(`SELECT m.id, s.key source, m.product_url url, m.product_title title, m.proposed_item_code itemCode, m.pack_qty packQty, m.pack_unit packUnit, m.method, m.confidence, m.rationale, m.status, m.reviewed_at reviewedAt, m.created_at createdAt15    FROM product_mappings m JOIN cost_sources s ON s.id=m.source_id ${status ? "WHERE m.status=?" : ""} ORDER BY m.created_at DESC LIMIT 500`).all(...(status ? [status] : []));16  return NextResponse.json({ mappings: rows });17}1819/** Création/approbation manuelle : { source, itemCode, url, title?, packQty?, packUnit? } */20export async function POST(req: NextRequest) {21  const denied = adminAuth(req);22  if (denied) return denied;23  let b: { source?: string; itemCode?: string; url?: string; title?: string; packQty?: number; packUnit?: string };24  try { b = await req.json(); } catch { return NextResponse.json({ error: "JSON invalide" }, { status: 400 }); }25  if (!b.source || !isRunnable(b.source) || !b.itemCode || !b.url) return NextResponse.json({ error: "source, itemCode et url requis" }, { status: 400 });26  const d = getCostDb();27  const item = d.prepare("SELECT id FROM cost_items WHERE canonical_code=?").get(b.itemCode) as { id: number } | undefined;28  if (!item) return NextResponse.json({ error: "article inconnu" }, { status: 404 });29  const sid = sourceIdByKey(b.source, d);30  d.prepare(`INSERT INTO product_mappings(source_id,product_url,product_title,proposed_item_code,pack_qty,pack_unit,method,confidence,rationale,status) VALUES(?,?,?,?,?,?,'manual',1,'saisie administrateur','pending')31    ON CONFLICT(source_id,product_url) DO UPDATE SET proposed_item_code=excluded.proposed_item_code, pack_qty=excluded.pack_qty, pack_unit=excluded.pack_unit, method='manual', confidence=1`).run(sid, b.url, b.title ?? null, b.itemCode, b.packQty ?? null, b.packUnit ?? null);32  const id = (d.prepare("SELECT id FROM product_mappings WHERE source_id=? AND product_url=?").get(sid, b.url) as { id: number }).id;33  reviewMapping(id, "approved", d);34  return NextResponse.json({ ok: true, id });35}36
Files main
Menu

Theme