From 8219615591f669479a4f8029d30a556656dfe3b0 Mon Sep 17 00:00:00 2001 From: makearmy Date: Wed, 1 Oct 2025 17:27:00 -0400 Subject: [PATCH] settings list build error fix --- app/api/submit/settings/route.ts | 85 +++++++++++++++++++++++--------- 1 file changed, 62 insertions(+), 23 deletions(-) diff --git a/app/api/submit/settings/route.ts b/app/api/submit/settings/route.ts index fc5e2786..c419084a 100644 --- a/app/api/submit/settings/route.ts +++ b/app/api/submit/settings/route.ts @@ -113,23 +113,34 @@ export async function POST(req: Request) { return NextResponse.json({ error: "Rate limited" }, { status: 429 }); } - // NEW: enforce user auth + // Enforce user auth const bearer = requireBearer(req); const { mode, body, photoFile, screenFile } = await readJsonOrMultipart(req); const target: Target = body?.target; - if (!target || !["settings_fiber", "settings_co2gan", "settings_co2gal", "settings_uv"].includes(target)) { + if ( + !target || + !["settings_fiber", "settings_co2gan", "settings_co2gal", "settings_uv"].includes(target) + ) { return NextResponse.json({ error: "Invalid target" }, { status: 400 }); } // Required basics const setting_title = String(body?.setting_title || "").trim(); - if (!setting_title) return NextResponse.json({ error: "Missing required: setting_title" }, { status: 400 }); + if (!setting_title) + return NextResponse.json( + { error: "Missing required: setting_title" }, + { status: 400 } + ); - // Derive uploader from the authenticated user (ignore any spoofed value in body) - const me = await dxGET("/users/me?fields=id,username", bearer); - const uploader = me?.username || "user"; + // ── Current user (handle both shapes from dxGET) ───────────── + const meRes = await dxGET("/users/me?fields=id,username", bearer); + const meId = meRes?.data?.id ?? meRes?.id ?? null; + const meUsername = meRes?.data?.username ?? meRes?.username ?? null; + + // Derive uploader from the authenticated user (server-trusted) + const uploader = meUsername || "user"; // Relations & numerics const mat = body?.mat ?? null; @@ -142,9 +153,10 @@ export async function POST(req: Request) { const focus = num(body?.focus, null); const setting_notes = String(body?.setting_notes || "").trim(); - // Fiber-only - const laser_soft = body?.laser_soft ?? null; - const repeat_all = target === "settings_fiber" ? num(body?.repeat_all, null) : undefined; + // Fiber-only / shared string + const laser_soft = body?.laser_soft ?? null; // string + const repeat_all = + target === "settings_fiber" ? num(body?.repeat_all, null) : undefined; // Upload / accept existing file ids let photo_id: string | null = body?.photo ?? null; @@ -153,25 +165,44 @@ export async function POST(req: Request) { // photo is required: if no id on body, require file if (!photo_id && photoFile) { if (photoFile.size > MAX_BYTES) - return NextResponse.json({ error: `Photo exceeds ${MAX_MB} MB` }, { status: 400 }); - const up = await uploadFile(photoFile, (photoFile as File).name, bearer, { - folderNamePath: folderPathFor(target, "photo"), + return NextResponse.json( + { error: `Photo exceeds ${MAX_MB} MB` }, + { status: 400 } + ); + const up = await uploadFile( + photoFile, + (photoFile as File).name, + bearer, + { + folderNamePath: folderPathFor(target, "photo"), title: setting_title, - owner: me?.id || null, - }); + // NOTE: do NOT include `owner` here; uploadFile options don't accept it. + } + ); photo_id = up.id; } if (!photo_id) { - return NextResponse.json({ error: "Missing required: photo" }, { status: 400 }); + return NextResponse.json( + { error: "Missing required: photo" }, + { status: 400 } + ); } if (!screen_id && screenFile) { if (screenFile.size > MAX_BYTES) - return NextResponse.json({ error: `Screenshot exceeds ${MAX_MB} MB` }, { status: 400 }); - const up = await uploadFile(screenFile, (screenFile as File).name, bearer, { - folderNamePath: folderPathFor(target, "screen"), + return NextResponse.json( + { error: `Screenshot exceeds ${MAX_MB} MB` }, + { status: 400 } + ); + const up = await uploadFile( + screenFile, + (screenFile as File).name, + bearer, + { + folderNamePath: folderPathFor(target, "screen"), title: `${setting_title} (screen)`, - }); + } + ); screen_id = up.id; } @@ -185,15 +216,20 @@ export async function POST(req: Request) { const payload: Record = { setting_title, - uploader, // ← server-derived from /users/me + // Ownership & attribution + owner: meId || null, // ✅ M2O to directus_users + uploader, // ✅ mirror username into string field + setting_notes, - submission_date: nowIso, // required by your schema + submission_date: nowIso, // if required by schema last_modified_date: nowIso, // keep in sync photo: photo_id, screen: screen_id ?? null, - laser_soft: laser_soft, + + // ✅ exact key (string) + laser_soft, mat, mat_coat, @@ -221,7 +257,10 @@ export async function POST(req: Request) { return NextResponse.json({ ok: true, id: data.id }); } catch (err: any) { console.error("[submit/settings] error", err?.message || err); - return NextResponse.json({ error: err?.message || "Unknown error" }, { status: err?.status ?? 500 }); + return NextResponse.json( + { error: err?.message || "Unknown error" }, + { status: err?.status ?? 500 } + ); } finally { const ms = Date.now() - started; if (ms) console.log(`[submit/settings] handled in ~${ms}ms`);