makearmy-app/app/api/rigs/route.ts
2025-09-29 21:59:25 -04:00

167 lines
5.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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 });
}
function takeRows<T = any>(res: any): T[] {
if (Array.isArray(res)) return res;
if (Array.isArray(res?.data)) return res.data;
return [];
}
export async function GET(req: Request) {
try {
const bearer = requireBearer(req);
// who am i?
const me = await dxGET<{ id: string; role?: { id: string; name?: string } }>(
"/users/me?fields=id,role.id,role.name",
bearer
);
const q = new URL(req.url).searchParams;
const limit = Math.min(parseInt(q.get("limit") || "50", 10), 100);
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(",");
// well try multiple filters; first non-empty result wins
const base = `&fields=${encodeURIComponent(fields)}&sort=-date_updated&limit=${limit}`;
const tries = [
{ label: "owner.id", path: `/items/user_rigs?filter[owner][id][_eq]=${encodeURIComponent(me.id)}${base}` },
{ label: "owner", path: `/items/user_rigs?filter[owner][_eq]=${encodeURIComponent(me.id)}${base}` },
{ label: "user_created", path: `/items/user_rigs?filter[user_created][_eq]=${encodeURIComponent(me.id)}${base}` },
];
const attempts: Array<{ label: string; count: number }> = [];
let picked: string | null = null;
let rows: any[] = [];
for (const t of tries) {
const res = await dxGET<any>(t.path, bearer);
const r = takeRows(res);
attempts.push({ label: t.label, count: r.length });
if (r.length) {
picked = t.label;
rows = r;
break;
}
}
// last resort: rely entirely on Directus role rule (no filter)
if (!rows.length) {
const res = await dxGET<any>(`/items/user_rigs?${base.slice(1)}`, bearer);
const r = takeRows(res);
attempts.push({ label: "(no filter, rely on role rule)", count: r.length });
if (r.length) {
picked = "(role rule)";
rows = r;
}
}
if (q.get("debug") === "1") {
return NextResponse.json({
meta: {
me: { id: me.id, role: me.role?.name || me.role?.id || null },
picked,
attempts,
},
data: rows,
});
}
return NextResponse.json(rows);
} catch (e: any) {
return bad(e?.message || "Failed to load rigs", e?.status || 500);
}
}
export async function POST(req: Request) {
try {
const bearer = requireBearer(req);
const body = await req.json().catch(() => ({}));
const name = (body?.name || "").trim();
const rig_type = body?.rig_type; // id
const laser_source = body?.laser_source; // submission_id
const laser_scan_lens = body?.laser_scan_lens || null;
const laser_focus_lens = body?.laser_focus_lens || null;
const laser_software = body?.laser_software || null;
const notes = (body?.notes || "").trim();
if (!name) return bad("Missing: name");
if (!rig_type) return bad("Missing: rig_type");
if (!laser_source) return bad("Missing: laser_source");
// derive owner from the authenticated user
const me = await dxGET<{ id: string }>("/users/me?fields=id", bearer);
const payload: any = {
owner: me.id,
name,
rig_type,
laser_source,
laser_scan_lens,
laser_focus_lens,
laser_software,
notes,
};
const res = await dxPOST<{ data: { id: string } }>(
"/items/user_rigs",
bearer,
payload
);
return NextResponse.json({ ok: true, id: String(res?.data?.id) });
} catch (e: any) {
return bad(e?.message || "Failed to create rig", e?.status || 500);
}
}
export async function DELETE(req: Request) {
try {
const bearer = requireBearer(req);
const url = new URL(req.url);
const id = url.searchParams.get("id");
if (!id) return bad("Missing: id");
// ensure the rig belongs to the current user
const me = await dxGET<{ id: string }>("/users/me?fields=id", bearer);
const rig = await dxGET<any>(
`/items/user_rigs/${encodeURIComponent(id)}?fields=id,owner`,
bearer
);
if (!rig || String(rig.owner) !== String(me.id)) {
return bad("Not your rig", 403);
}
await dxDELETE(`/items/user_rigs/${encodeURIComponent(id)}`, bearer);
return NextResponse.json({ ok: true });
} catch (e: any) {
return bad(e?.message || "Failed to delete rig", e?.status || 500);
}
}