rigs route fix

This commit is contained in:
makearmy 2025-09-29 21:59:25 -04:00
parent eef73cb729
commit 9607830c2f
2 changed files with 107 additions and 45 deletions

View file

@ -9,22 +9,24 @@ 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[];
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);
const me = await dxGET<{ id: string }>("/users/me?fields=id", bearer);
// 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 wantDebug = q.get("debug") === "1";
const fields = [
"id",
@ -46,53 +48,46 @@ export async function GET(req: Request) {
"date_updated",
].join(",");
const base = `/items/user_rigs?fields=${encodeURIComponent(
fields
)}&sort=-date_updated&limit=${limit}`;
// 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}` },
];
// Attempt A: filter by owner
const byOwnerPath = `${base}&filter[owner][_eq]=${encodeURIComponent(
me.id
)}`;
const rowsOwner = await dxArray(byOwnerPath, bearer);
const attempts: Array<{ label: string; count: number }> = [];
let picked: string | null = null;
let rows: any[] = [];
// 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());
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;
}
}
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;
// 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: [
{ label: "owner", count: ownerCount },
{ label: "user_created", count: picked === "user_created" ? rows.length : 0 },
],
attempts,
},
data: rows,
});
@ -103,3 +98,70 @@ export async function GET(req: Request) {
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);
}
}

Binary file not shown.