Files
var-monorepo/apps/hub-server/modules/chron.ts
2025-06-05 10:18:52 -07:00

208 lines
4.9 KiB
TypeScript

import { getMoodleCourseCompletionStatus, getMoodleUserById } from "./moodle";
import { CronJob } from "cron";
import { DISCORD_ROLES, ParticipantLog, prisma } from "@repo/db";
import { sendCourseCompletedEmail } from "modules/mail";
import { handleParticipantFinished } from "modules/event";
import { eventCompleted } from "helper/events";
import { addRolesToMember, removeRolesFromMember } from "modules/discord";
import { JsonValueType } from "@repo/db/zod";
const syncMoodleIds = async () => {
try {
const user = await prisma.user.findMany({
where: {
moodleId: null,
},
});
await Promise.all(
user.map(async (u) => {
const moodleUser = await getMoodleUserById(u.id.toString());
const moodleId = moodleUser?.id.toString();
if (u.moodleId === parseInt(moodleId)) return;
await prisma.user.update({
where: {
id: u.id,
},
data: {
moodleId: parseInt(moodleId),
},
});
}),
);
} catch (error) {
console.error(error);
}
};
const updateParticipantMoodleResults = async () => {
const participantsMoodlePending = await prisma.participant.findMany({
where: {
finisherMoodleCurseCompleted: false,
Event: {
finisherMoodleCourseId: {
not: null,
},
},
},
include: {
Event: true,
User: true,
},
});
await Promise.all(
participantsMoodlePending.map(async (p) => {
if (!p.User) return;
if (!p.User.moodleId) return;
const quizzResult = await getMoodleCourseCompletionStatus(
p.User.moodleId.toString(),
p.Event.finisherMoodleCourseId!,
);
if (quizzResult?.completionstatus?.completed === true) {
return prisma.participant.update({
where: {
id: p.id,
},
data: {
finisherMoodleCurseCompleted: true,
statusLog: {
push: {
event: "Moodle-Kurs abgeschlossen",
timestamp: new Date(),
user: "system",
},
},
},
});
}
}),
);
};
export const checkFinishedParticipants = async () => {
const participantsPending = await prisma.participant.findMany({
where: {
completetionWorkflowFinished: false,
},
include: {
Event: true,
User: true,
},
});
participantsPending.forEach(async (p) => {
if (!p.User) return;
const completed = eventCompleted(p.Event, p);
if (!completed) return;
console.log(
`User ${p.User.firstname} ${p.User.lastname} - ${p.User.publicId} finished event ${p.Event.name}`,
);
handleParticipantFinished(p.Event, p, p.User);
});
};
const checkUnfinishedParticipants = async () => {
const participantsPending = await prisma.participant.findMany({
where: {
completetionWorkflowFinished: false,
},
include: {
Event: true,
User: {
include: {
discordAccounts: true,
},
},
},
});
participantsPending.forEach(async (p) => {
if (!p.User) return;
const completed = eventCompleted(p.Event, p);
if (completed) return;
if (!p.Event.discordRoleId) {
await prisma.participant.update({
where: {
id: p.id,
},
data: {
inscriptionWorkflowCompleted: true,
},
});
return;
}
console.log(
`User ${p.User.firstname} ${p.User.lastname} - ${p.User.publicId} did not finish event ${p.Event.name}`,
);
if (p.User.discordAccounts[0] && p.Event.discordRoleId) {
await addRolesToMember(p.User.discordAccounts[0].discordId, [p.Event.discordRoleId]);
await prisma.participant.update({
where: {
id: p.id,
},
data: {
inscriptionWorkflowCompleted: true,
statusLog: {
push: {
event: "Discord-Rolle hinzugefügt",
timestamp: new Date(),
user: "system",
} as ParticipantLog as any,
},
},
});
}
});
};
const checkDiscordRoles = async () => {
const user = await prisma.user.findMany({
where: {
discordAccounts: {
some: {},
},
},
include: {
discordAccounts: true,
},
});
for (const u of user) {
// Here ony member Roles regarding their rights are checked
if (!u.discordAccounts[0]) continue;
const discordAccount = u.discordAccounts[0];
// For Pilot
if (u.permissions.includes("PILOT")) {
await addRolesToMember(discordAccount.discordId, [DISCORD_ROLES.PILOT]); // ONLINE_PILOT
} else {
await removeRolesFromMember(discordAccount.discordId, [DISCORD_ROLES.PILOT]); // ONLINE_PILOT
}
// for Dispatcher
if (u.permissions.includes("DISPO")) {
await addRolesToMember(discordAccount.discordId, [DISCORD_ROLES.DISPATCHER]); // ONLINE_DISPATCHER
} else {
await removeRolesFromMember(discordAccount.discordId, [DISCORD_ROLES.DISPATCHER]); // ONLINE_DISPATCHER
}
}
};
CronJob.from({ cronTime: "0 * * * *", onTick: syncMoodleIds, start: true });
CronJob.from({
cronTime: "*/1 * * * *",
onTick: async () => {
await updateParticipantMoodleResults();
await checkFinishedParticipants();
await checkUnfinishedParticipants();
},
start: true,
});
CronJob.from({
cronTime: "0 * * * *",
onTick: checkDiscordRoles,
start: true,
});