105 lines
3.7 KiB
TypeScript
105 lines
3.7 KiB
TypeScript
// app/api/rigs/route.ts
|
|
import { NextResponse } from "next/server";
|
|
import { dxGET, dxPOST, dxDELETE } from "@/lib/directus";
|
|
import { requireBearer } from "@/app/api/_lib/auth";
|
|
|
|
export const runtime = "nodejs";
|
|
|
|
function bad(msg: string, code = 400) {
|
|
return NextResponse.json({ error: msg }, { status: code });
|
|
}
|
|
|
|
// tiny helper so we handle either `dxGET` shape
|
|
async function dxArray<T = any>(path: string, bearer: string): Promise<T[]> {
|
|
const res = await dxGET<any>(path, bearer);
|
|
if (Array.isArray(res)) return res as T[];
|
|
if (res?.data && Array.isArray(res.data)) return res.data as T[];
|
|
return [];
|
|
}
|
|
|
|
export async function GET(req: Request) {
|
|
try {
|
|
const bearer = requireBearer(req);
|
|
const me = await dxGET<{ id: string }>("/users/me?fields=id", bearer);
|
|
|
|
const q = new URL(req.url).searchParams;
|
|
const limit = Math.min(parseInt(q.get("limit") || "50", 10), 100);
|
|
const wantDebug = q.get("debug") === "1";
|
|
|
|
const fields = [
|
|
"id",
|
|
"name",
|
|
"notes",
|
|
"rig_type.id",
|
|
"rig_type.name",
|
|
"laser_source.submission_id",
|
|
"laser_source.make",
|
|
"laser_source.model",
|
|
"laser_scan_lens.id",
|
|
"laser_scan_lens.field_size",
|
|
"laser_scan_lens.focal_length",
|
|
"laser_focus_lens.id",
|
|
"laser_focus_lens.name",
|
|
"laser_software.id",
|
|
"laser_software.name",
|
|
"date_created",
|
|
"date_updated",
|
|
].join(",");
|
|
|
|
const base = `/items/user_rigs?fields=${encodeURIComponent(
|
|
fields
|
|
)}&sort=-date_updated&limit=${limit}`;
|
|
|
|
// Attempt A: filter by owner
|
|
const byOwnerPath = `${base}&filter[owner][_eq]=${encodeURIComponent(
|
|
me.id
|
|
)}`;
|
|
const rowsOwner = await dxArray(byOwnerPath, bearer);
|
|
|
|
// If nothing, Attempt B: fall back to user_created
|
|
let picked = "owner";
|
|
let rows = rowsOwner;
|
|
if (!rowsOwner.length) {
|
|
const byCreatedPath = `${base}&filter[user_created][_eq]=${encodeURIComponent(
|
|
me.id
|
|
)}`;
|
|
const rowsCreated = await dxArray(byCreatedPath, bearer);
|
|
|
|
// Prefer created if owner == 0, otherwise merge (dedupe by id)
|
|
if (rowsCreated.length) {
|
|
picked = "user_created";
|
|
const map = new Map<number | string, any>();
|
|
for (const r of [...rowsOwner, ...rowsCreated]) map.set(r.id, r);
|
|
rows = Array.from(map.values());
|
|
}
|
|
}
|
|
|
|
if (wantDebug) {
|
|
// also fetch counts for the debug panel
|
|
const ownerCount = rowsOwner.length;
|
|
// Re-run created count only if needed
|
|
let createdCount = 0;
|
|
if (picked === "user_created") {
|
|
const createdCountPath = `${base}&filter[user_created][_eq]=${encodeURIComponent(
|
|
me.id
|
|
)}&limit=1`;
|
|
const createdProbe = await dxArray(createdCountPath, bearer);
|
|
createdCount = createdProbe.length ? rows.length : 0;
|
|
}
|
|
return NextResponse.json({
|
|
meta: {
|
|
picked,
|
|
attempts: [
|
|
{ label: "owner", count: ownerCount },
|
|
{ label: "user_created", count: picked === "user_created" ? rows.length : 0 },
|
|
],
|
|
},
|
|
data: rows,
|
|
});
|
|
}
|
|
|
|
return NextResponse.json(rows);
|
|
} catch (e: any) {
|
|
return bad(e?.message || "Failed to load rigs", e?.status || 500);
|
|
}
|
|
}
|