rename core-server

This commit is contained in:
PxlLoewe
2025-06-29 01:41:01 -07:00
parent 4d55e2aa97
commit c0e488b3fd
21 changed files with 39 additions and 59 deletions

View File

@@ -0,0 +1,56 @@
import { DISCORD_ROLES, Event, getPublicUser, Participant, prisma } from "@repo/db";
import { Router } from "express";
import { changeMemberRoles, getMember } from "routes/member";
const router: Router = Router();
export const eventCompleted = (event: Event, participant?: Participant) => {
if (!participant) return false;
if (event.finisherMoodleCourseId && !participant.finisherMoodleCurseCompleted) return false;
if (event.hasPresenceEvents && !participant.attended) return false;
return true;
};
router.post("/set-standard-name", async (req, res) => {
const { memberId, userId } = req.body;
const user = await prisma.user.findUnique({
where: {
id: userId,
},
});
console.log(`Setting standard name for user ${userId} (${user?.publicId}) to member ${memberId}`);
if (!user) {
res.status(404).json({ error: "User not found" });
return;
}
const participant = await prisma.participant.findMany({
where: {
userId: user.id,
},
include: {
Event: true,
},
});
participant.forEach(async (p) => {
if (!p.Event.discordRoleId) return;
if (eventCompleted(p.Event, p)) {
await changeMemberRoles(memberId, [p.Event.discordRoleId], "remove");
} else {
await changeMemberRoles(memberId, [p.Event.discordRoleId], "add");
}
});
const publicUser = getPublicUser(user);
const member = await getMember(memberId);
await member.setNickname(`${publicUser.fullName} - ${user.publicId}`);
const isPilot = user.permissions.includes("PILOT");
const isDispatcher = user.permissions.includes("DISPO");
await changeMemberRoles(memberId, [DISCORD_ROLES.PILOT], isPilot ? "add" : "remove");
await changeMemberRoles(memberId, [DISCORD_ROLES.DISPATCHER], isDispatcher ? "add" : "remove");
});
export default router;

View File

@@ -0,0 +1,78 @@
import { Router, Request, Response } from "express";
import client from "modules/discord";
const GUILD_ID = process.env.DISCORD_GUILD_ID;
if (!GUILD_ID) {
throw new Error("DISCORD_GUILD_ID environment variable is not set.");
}
const router: Router = Router();
export const getMember = async (memberId: string) => {
const guild = client.guilds.cache.get(GUILD_ID);
if (!guild) throw new Error("Guild not found");
try {
return guild.members.cache.get(memberId) ?? (await guild.members.fetch(memberId));
} catch (error) {
console.error("Error fetching member:", error);
throw new Error("Member not found");
}
};
router.post("/rename", async (req: Request, res: Response) => {
const { newName, memberId } = req.body;
if (typeof newName !== "string" || !memberId) {
res.status(400).json({ error: "Invalid or missing newName or memberId" });
return;
}
try {
const member = await getMember(memberId);
await member.setNickname(newName);
console.log(`Member ${member.id} renamed to ${newName}`);
res.status(200).json({ message: "Member renamed successfully" });
} catch (error) {
console.error("Error renaming member:", error);
res.status(500).json({ error: "Failed to rename member" });
}
});
export const changeMemberRoles = async (
memberId: string,
roleIds: string[],
action: "add" | "remove",
) => {
const member = await getMember(memberId);
const currentRoleIds = member.roles.cache.map((role) => role.id);
const filteredRoleIds =
action === "add"
? roleIds.filter((id: string) => !currentRoleIds.includes(id))
: roleIds.filter((id: string) => currentRoleIds.includes(id));
if (filteredRoleIds.length === 0) {
return { message: `No roles to ${action}` };
}
await member.roles[action](filteredRoleIds);
return { message: `Roles ${action}ed successfully` };
};
const handleRoleChange = (action: "add" | "remove") => async (req: Request, res: Response) => {
const { roleIds, memberId } = req.body;
if (!Array.isArray(roleIds) || !memberId) {
res.status(400).json({ error: "Invalid or missing roleIds or memberId" });
return;
}
try {
const result = await changeMemberRoles(memberId, roleIds, action);
res.status(200).json(result);
} catch (error) {
console.error(`Error ${action}ing roles:`, error);
res.status(500).json({ error: `Failed to ${action} roles` });
}
};
router.post("/add-role", handleRoleChange("add"));
router.post("/remove-role", handleRoleChange("remove"));
export default router;

View File

@@ -0,0 +1,9 @@
import { Router } from "express";
import { promRegister } from "modules/prometheus";
export const metricsRouter: Router = Router();
metricsRouter.get("/", async (req, res) => {
res.setHeader("Content-Type", promRegister.contentType);
res.end(await promRegister.metrics());
});

View File

@@ -0,0 +1,72 @@
import { prisma } from "@repo/db";
import { Embed, EmbedBuilder } from "discord.js";
import { Router } from "express";
import client from "modules/discord";
if (!process.env.DISCORD_REPORT_CHANNEL)
throw new Error("DISCORD_REPORT_CHANNEL environment variable is not set.");
const router: Router = Router();
router.post("/admin-embed", async (req, res) => {
try {
const { reportId } = req.body;
if (!reportId) {
res.status(400).json({ error: "reportId is required" });
return;
}
const report = await prisma.report.findUnique({
where: {
id: Number(reportId),
},
include: {
Reported: true,
Sender: true,
},
});
if (!report) {
res.status(404).json({ error: "Report not found" });
return;
}
const embed = new EmbedBuilder()
.setTitle(`Report #${report.id}`)
.setURL(`${process.env.NEXT_PUBLIC_HUB_URL}/admin/report/${report.id}`)
.setDescription(report.text)
.addFields(
{
name: "gemeldeter Nutzer",
value: `${report.Reported?.firstname} ${report.Reported?.lastname} (${report.Reported?.publicId})`,
inline: true,
},
{ name: "angemeldet als", value: report.reportedUserRole, inline: true },
{
name: "gemeldet von",
value: `${report.Sender?.firstname} ${report.Sender?.lastname} (${report.Sender?.publicId})`,
},
)
.setFooter({
text: "Bitte reagiere mit 🫡, wenn du den Report bearbeitet hast, oder mit ✅, wenn er abgeschlossen ist.",
})
.setTimestamp(new Date(report.timestamp))
.setColor("DarkRed");
const reportsChannel = await client.channels.fetch(process.env.DISCORD_REPORT_CHANNEL!);
if (!reportsChannel || !reportsChannel.isSendable()) {
res.status(500).json({ error: "Reports channel not found or is not a text channel" });
return;
}
const message = await reportsChannel.send({ embeds: [embed] });
message.react("🫡").catch(console.error);
message.react("✅").catch(console.error);
res.json({
message: "Report embed sent to Discord channel",
});
} catch (error) {
console.error("Error sending report embed:", error);
res.status(500).json({ error: "Failed to send report embed" });
}
});
export default router;

View File

@@ -0,0 +1,14 @@
import { Router } from "express";
import memberRouter from "./member";
import helperRouter from "./helper";
import reportRouter from "./report";
import { metricsRouter } from "routes/metrics";
const router: Router = Router();
router.use("/member", memberRouter);
router.use("/helper", helperRouter);
router.use("/report", reportRouter);
router.use("/metrics", metricsRouter);
export default router;