From 140f5132b7e2cab506dcab0a9e30b5569dadd100 Mon Sep 17 00:00:00 2001 From: "Builder.io" Date: Sun, 28 Sep 2025 04:46:41 +0000 Subject: [PATCH] Add admin endpoint to award achievements; route onboarding award via server cgen-eecee0bfec5545b194cfff15cc3875a0 --- server/index.ts | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/server/index.ts b/server/index.ts index 84e4e8bf..cbecc6c0 100644 --- a/server/index.ts +++ b/server/index.ts @@ -167,6 +167,35 @@ export function createServer() { } }); + app.post("/api/achievements/award", async (req, res) => { + const { user_id, achievement_names } = req.body || {}; + if (!user_id) return res.status(400).json({ error: "user_id required" }); + const names: string[] = Array.isArray(achievement_names) && achievement_names.length + ? achievement_names + : ["Welcome to AeThex"]; + try { + const { data: achievements, error: aErr } = await adminSupabase + .from("achievements") + .select("id, name") + .in("name", names); + if (aErr) return res.status(500).json({ error: aErr.message }); + const rows = (achievements || []).map((a: any) => ({ + user_id, + achievement_id: a.id, + })); + if (!rows.length) return res.json({ ok: true, awarded: [] }); + const { error: iErr } = await adminSupabase + .from("user_achievements") + .insert(rows, { upsert: true }); + if (iErr && iErr.code !== "23505") + return res.status(500).json({ error: iErr.message }); + return res.json({ ok: true, awarded: rows.length }); + } catch (e: any) { + console.error("[API] achievements/award exception", e); + return res.status(500).json({ error: e?.message || String(e) }); + } + }); + app.get("/api/applications", async (req, res) => { const owner = String(req.query.owner || ""); if (!owner) return res.status(400).json({ error: "owner required" });