aethex-forge/api/discord/role-mappings.ts
2025-11-08 21:09:45 +00:00

207 lines
5.8 KiB
TypeScript

import type { VercelRequest, VercelResponse } from "@vercel/node";
import { createClient } from "@supabase/supabase-js";
// Initialize Supabase with service role
let supabase: any = null;
try {
supabase = createClient(
process.env.SUPABASE_URL || "",
process.env.SUPABASE_SERVICE_ROLE || "",
);
} catch (e) {
console.error("Failed to initialize Supabase client:", e);
}
interface RoleMapping {
id: string;
arm: string;
user_type: string;
discord_role_name: string;
discord_role_id?: string;
server_id?: string;
created_at: string;
updated_at: string;
}
export default async function handler(req: VercelRequest, res: VercelResponse) {
// Set CORS headers
res.setHeader("Access-Control-Allow-Credentials", "true");
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader(
"Access-Control-Allow-Methods",
"GET,OPTIONS,PATCH,DELETE,POST,PUT",
);
res.setHeader(
"Access-Control-Allow-Headers",
"X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version",
);
if (req.method === "OPTIONS") {
res.status(200).end();
return;
}
try {
// Validate Supabase is initialized
if (!supabase) {
console.error("Supabase client not initialized");
return res.status(500).json({
error: "Server configuration error: Missing Supabase credentials",
});
}
// GET - Fetch all role mappings
if (req.method === "GET") {
try {
const { data, error } = await supabase
.from("discord_role_mappings")
.select("*")
.order("created_at", { ascending: false });
if (error) {
console.error("Supabase error:", error);
return res.status(500).json({
error: `Failed to fetch role mappings: ${error.message}`,
});
}
return res.status(200).json(data || []);
} catch (queryErr: any) {
console.error("Query error:", queryErr);
return res.status(500).json({
error: `Database query error: ${queryErr?.message || "Unknown error"}`,
});
}
}
// POST - Create new role mapping
if (req.method === "POST") {
try {
const { arm, discord_role, discord_role_name, server_id, user_type } =
req.body;
// Support both discord_role and discord_role_name for compatibility
const roleName = discord_role_name || discord_role;
if (!arm || !roleName) {
return res.status(400).json({
error: "arm and discord_role (or discord_role_name) are required",
});
}
const { data, error } = await supabase
.from("discord_role_mappings")
.insert({
arm,
user_type: user_type || "community_member",
discord_role_name: roleName,
server_id: server_id || null,
})
.select()
.single();
if (error) {
console.error("Supabase error:", error);
return res.status(500).json({
error: `Failed to create mapping: ${error.message}`,
});
}
return res.status(201).json(data);
} catch (insertErr: any) {
console.error("Insert error:", insertErr);
return res.status(500).json({
error: `Insert error: ${insertErr?.message || "Unknown error"}`,
});
}
}
// PUT - Update role mapping
if (req.method === "PUT") {
try {
const {
id,
arm,
discord_role,
discord_role_name,
server_id,
user_type,
} = req.body;
if (!id) {
return res.status(400).json({ error: "id is required" });
}
const updateData: any = {};
if (arm) updateData.arm = arm;
const roleName = discord_role_name || discord_role;
if (roleName) updateData.discord_role_name = roleName;
if (server_id !== undefined) updateData.server_id = server_id;
if (user_type) updateData.user_type = user_type;
const { data, error } = await supabase
.from("discord_role_mappings")
.update(updateData)
.eq("id", id)
.select()
.single();
if (error) {
console.error("Supabase error:", error);
return res.status(500).json({
error: `Failed to update mapping: ${error.message}`,
});
}
return res.status(200).json(data);
} catch (updateErr: any) {
console.error("Update error:", updateErr);
return res.status(500).json({
error: `Update error: ${updateErr?.message || "Unknown error"}`,
});
}
}
// DELETE - Delete role mapping
if (req.method === "DELETE") {
try {
const { id } = req.query;
if (!id) {
return res
.status(400)
.json({ error: "id query parameter is required" });
}
const { error } = await supabase
.from("discord_role_mappings")
.delete()
.eq("id", id);
if (error) {
console.error("Supabase error:", error);
return res.status(500).json({
error: `Failed to delete mapping: ${error.message}`,
});
}
return res.status(200).json({ success: true });
} catch (deleteErr: any) {
console.error("Delete error:", deleteErr);
return res.status(500).json({
error: `Delete error: ${deleteErr?.message || "Unknown error"}`,
});
}
}
return res.status(405).json({ error: "Method not allowed" });
} catch (error: any) {
console.error("API error:", error);
// Ensure we always return JSON, never HTML
return res.status(500).json({
error: error?.message || "Internal server error",
type: "api_error",
});
}
}