diff --git a/server/index.ts b/server/index.ts index b3ca6c86..49953828 100644 --- a/server/index.ts +++ b/server/index.ts @@ -16,5 +16,124 @@ export function createServer() { res.json({ message: ping }); }); + // Admin-backed API (service role) + try { + const { adminSupabase } = await import("./supabase"); + + app.get("/api/health", async (_req, res) => { + try { + const { error } = await adminSupabase.from("user_profiles").select("count", { count: "exact", head: true }); + if (error) return res.status(500).json({ ok: false, error: error.message }); + return res.json({ ok: true }); + } catch (e: any) { + return res.status(500).json({ ok: false, error: e?.message || String(e) }); + } + }); + + app.get("/api/posts", async (req, res) => { + const limit = Math.max(1, Math.min(50, Number(req.query.limit) || 10)); + try { + const { data, error } = await adminSupabase + .from("community_posts") + .select(`*, user_profiles ( username, full_name, avatar_url )`) + .eq("is_published", true) + .order("created_at", { ascending: false }) + .limit(limit); + if (error) return res.status(500).json({ error: error.message }); + res.json(data || []); + } catch (e: any) { + res.status(500).json({ error: e?.message || String(e) }); + } + }); + + app.get("/api/user/:id/posts", async (req, res) => { + const userId = req.params.id; + try { + const { data, error } = await adminSupabase + .from("community_posts") + .select("*") + .eq("author_id", userId) + .order("created_at", { ascending: false }); + if (error) return res.status(500).json({ error: error.message }); + res.json(data || []); + } catch (e: any) { + res.status(500).json({ error: e?.message || String(e) }); + } + }); + + app.post("/api/posts", async (req, res) => { + const payload = req.body || {}; + try { + const { data, error } = await adminSupabase + .from("community_posts") + .insert({ + author_id: payload.author_id, + title: payload.title, + content: payload.content, + category: payload.category, + tags: payload.tags, + is_published: payload.is_published ?? true, + }) + .select() + .single(); + if (error) return res.status(500).json({ error: error.message }); + res.json(data); + } catch (e: any) { + res.status(500).json({ error: e?.message || String(e) }); + } + }); + + app.post("/api/profile/ensure", async (req, res) => { + const { id, profile } = req.body || {}; + if (!id) return res.status(400).json({ error: "missing id" }); + try { + const { data, error } = await adminSupabase + .from("user_profiles") + .upsert({ id, ...profile }, { onConflict: "id" }) + .select() + .single(); + if (error) return res.status(500).json({ error: error.message }); + res.json(data); + } catch (e: any) { + res.status(500).json({ error: e?.message || String(e) }); + } + }); + + app.post("/api/interests", async (req, res) => { + const { user_id, interests } = req.body || {}; + if (!user_id || !Array.isArray(interests)) return res.status(400).json({ error: "invalid payload" }); + try { + await adminSupabase.from("user_interests").delete().eq("user_id", user_id); + if (interests.length) { + const rows = interests.map((interest: string) => ({ user_id, interest })); + const { error } = await adminSupabase.from("user_interests").insert(rows); + if (error) return res.status(500).json({ error: error.message }); + } + res.json({ ok: true }); + } catch (e: any) { + 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" }); + try { + const { data, error } = await adminSupabase + .from("project_applications") + .select(`*, projects!inner(id, title, user_id)`) + .eq("projects.user_id", owner) + .order("created_at", { ascending: false }) + .limit(50); + if (error) return res.status(500).json({ error: error.message }); + res.json(data || []); + } catch (e: any) { + res.status(500).json({ error: e?.message || String(e) }); + } + }); + } catch (e) { + console.warn("Admin API not initialized:", e); + } + return app; }