feat: implement emergency duty (Notdienst) swapping for parents

This commit is contained in:
t.indorf
2026-05-23 19:18:30 +02:00
parent 4cd16773c1
commit 3ce5638449
9 changed files with 1638 additions and 119 deletions
+49
View File
@@ -84,6 +84,13 @@ enum NotdienstAlertStatus {
CANCELLED
}
enum NotdienstSwapStatus {
PENDING
ACCEPTED
DECLINED
CANCELLED
}
enum DutyAssignmentStatus {
PLANNED
DONE
@@ -136,6 +143,7 @@ model Kita {
notdienstAvailabilities NotdienstAvailability[]
notdienstAssignments NotdienstAssignment[]
notdienstAlerts NotdienstAlert[]
notdienstSwapRequests NotdienstSwapRequest[]
@@map("kitas")
}
@@ -158,6 +166,7 @@ model Family {
users User[]
children Child[]
dutyAssignments DutyAssignment[]
notdienstSwapRequestsStarted NotdienstSwapRequest[] @relation("NotdienstSwapRequesterFamily")
@@index([kitaId])
@@map("families")
@@ -219,6 +228,8 @@ model User {
notdienstAlertsAssigned NotdienstAlert[] @relation("NotdienstAlertParent")
notdienstAlertsTriggered NotdienstAlert[] @relation("NotdienstAlertTrigger")
notdienstPlansCreated NotdienstPlan[] @relation("NotdienstPlanCreator")
notdienstSwapRequestsStarted NotdienstSwapRequest[] @relation("NotdienstSwapRequester")
notdienstSwapRequestsResponded NotdienstSwapRequest[] @relation("NotdienstSwapResponder")
announcementsAuthored Announcement[] @relation("AnnouncementAuthor")
announcementReads AnnouncementRead[]
@@ -647,12 +658,50 @@ model NotdienstAssignment {
updatedAt DateTime @updatedAt
alerts NotdienstAlert[]
swapRequestsAsTarget NotdienstSwapRequest[] @relation("NotdienstSwapTargetAssignment")
swapRequestsAsOffered NotdienstSwapRequest[] @relation("NotdienstSwapOfferedAssignment")
@@unique([planId, date])
@@index([kitaId, date])
@@map("notdienst_assignments")
}
/// Tauschanfrage zwischen Eltern fuer zwei bereits veroeffentlichte
/// zukuenftige Notdienst-Zuteilungen.
model NotdienstSwapRequest {
id String @id @default(cuid())
kitaId String
kita Kita @relation(fields: [kitaId], references: [id], onDelete: Cascade)
requesterUserId String
requesterUser User @relation("NotdienstSwapRequester", fields: [requesterUserId], references: [id], onDelete: Cascade)
requesterFamilyId String
requesterFamily Family @relation("NotdienstSwapRequesterFamily", fields: [requesterFamilyId], references: [id], onDelete: Cascade)
targetAssignmentId String
targetAssignment NotdienstAssignment @relation("NotdienstSwapTargetAssignment", fields: [targetAssignmentId], references: [id], onDelete: Cascade)
offeredAssignmentId String
offeredAssignment NotdienstAssignment @relation("NotdienstSwapOfferedAssignment", fields: [offeredAssignmentId], references: [id], onDelete: Cascade)
status NotdienstSwapStatus @default(PENDING)
message String?
respondedById String?
respondedBy User? @relation("NotdienstSwapResponder", fields: [respondedById], references: [id], onDelete: SetNull)
respondedAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([kitaId, status])
@@index([requesterFamilyId, status])
@@index([targetAssignmentId, status])
@@index([offeredAssignmentId, status])
@@map("notdienst_swap_requests")
}
/// Aktive Alarmierung — wird bei Krankmeldung einer Fachkraft
/// vom Koordinator ausgelöst. Bestätigung via Magic-Link (Token).
model NotdienstAlert {