feat: add household emergency duty alarms and deadline worker
This commit is contained in:
@@ -1,123 +1,10 @@
|
||||
"use server";
|
||||
|
||||
import crypto from "crypto";
|
||||
import { createElement } from "react";
|
||||
import { format } from "date-fns";
|
||||
import { de } from "date-fns/locale";
|
||||
import { revalidatePath } from "next/cache";
|
||||
import { NotdienstAlertStatus, UserRole } from "@prisma/client";
|
||||
|
||||
import { AlertEmail } from "@/emails/AlertEmail";
|
||||
import { requireRole } from "@/lib/auth-utils";
|
||||
import { getAppEmailConfigError, sendAppEmail } from "@/lib/mail";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
|
||||
const BASE_URL =
|
||||
process.env.NEXTAUTH_URL ?? process.env.AUTH_URL ?? "http://localhost:3000";
|
||||
|
||||
import { alarmAction } from "./notdienst/alarm/actions";
|
||||
// Existing callers use the shared household workflow and the same guards.
|
||||
export async function triggerAlertAction(assignmentId: string) {
|
||||
const session = await requireRole([UserRole.ADMIN, UserRole.KOORDINATOR]);
|
||||
const kitaId = session.user.kitaId!;
|
||||
|
||||
try {
|
||||
const [existing, assignment] = await Promise.all([
|
||||
// Prüfen ob es schon einen aktiven Alert für dieses Assignment gibt
|
||||
prisma.notdienstAlert.findFirst({
|
||||
where: { assignmentId, kitaId },
|
||||
}),
|
||||
prisma.notdienstAssignment.findFirst({
|
||||
where: { id: assignmentId, kitaId },
|
||||
include: {
|
||||
child: {
|
||||
select: {
|
||||
id: true,
|
||||
firstName: true,
|
||||
lastName: true,
|
||||
family: {
|
||||
select: {
|
||||
users: {
|
||||
where: { role: UserRole.ELTERN },
|
||||
select: {
|
||||
id: true,
|
||||
email: true,
|
||||
firstName: true,
|
||||
lastName: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
]);
|
||||
|
||||
if (existing) {
|
||||
return { error: "Für diese Einteilung wurde bereits ein Alarm ausgelöst." };
|
||||
}
|
||||
|
||||
if (!assignment) {
|
||||
return { error: "Notdienst-Einteilung wurde nicht gefunden." };
|
||||
}
|
||||
|
||||
const parents = assignment.child.family.users;
|
||||
|
||||
if (parents.length === 0) {
|
||||
return { error: "Kein Elternteil für diesen Notdienst hinterlegt." };
|
||||
}
|
||||
|
||||
const mailConfigError = getAppEmailConfigError();
|
||||
if (mailConfigError) {
|
||||
return { error: mailConfigError };
|
||||
}
|
||||
|
||||
const dateLabel = format(assignment.date, "EEEE, dd. MMMM yyyy", {
|
||||
locale: de,
|
||||
});
|
||||
const childName = `${assignment.child.firstName} ${assignment.child.lastName}`;
|
||||
const alertJobs: { email: string; token: string }[] = [];
|
||||
|
||||
await prisma.$transaction(
|
||||
parents.map((parent) => {
|
||||
const token = crypto.randomUUID();
|
||||
alertJobs.push({ email: parent.email, token });
|
||||
return prisma.notdienstAlert.create({
|
||||
data: {
|
||||
kitaId,
|
||||
assignmentId,
|
||||
parentUserId: parent.id,
|
||||
triggeredById: session.user.id,
|
||||
status: NotdienstAlertStatus.PENDING,
|
||||
confirmationToken: token,
|
||||
},
|
||||
});
|
||||
}),
|
||||
);
|
||||
|
||||
for (const job of alertJobs) {
|
||||
const emailResult = await sendAppEmail({
|
||||
to: job.email,
|
||||
subject: `Dringender Notdienst-Alarm für ${dateLabel}`,
|
||||
react: createElement(AlertEmail, {
|
||||
date: dateLabel,
|
||||
childName,
|
||||
confirmLink: `${BASE_URL}/alert/${job.token}`,
|
||||
}),
|
||||
});
|
||||
|
||||
if (!emailResult.success) {
|
||||
revalidatePath("/dashboard");
|
||||
return {
|
||||
error: `Alarm wurde angelegt, aber mindestens eine E-Mail konnte nicht versendet werden: ${emailResult.error}`,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
revalidatePath("/dashboard");
|
||||
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return { error: "Fehler beim Auslösen des Alarms." };
|
||||
}
|
||||
return alarmAction("create", {
|
||||
assignmentId,
|
||||
wholeDay: true,
|
||||
replyMinutes: 30,
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user