Add admin routes for posts, profile, interests using service role
cgen-d051e943f1c54709899b7e6b462242d9
This commit is contained in:
parent
c4eb0d7db9
commit
34c1d995e9
1 changed files with 119 additions and 0 deletions
119
server/index.ts
119
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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue