Phase 3: Einsatz- und Uebungserfassung
Schnellerfassung im Alarmfall, sechs Zeitstempel mit Ausrueckzeit, Anfahrt und Hilfsfrist, Staerke nach FwDV 3, Personalvorschlag mit Qualifikationsstand, Einsatzbericht als PDF, Jahresexport fuer die Gemeinde, Statistik und Uebungen mit Anwesenheitsliste. Dazu das Einsatzportal fuer Fremdwehren: ein signierter Link ohne Anmeldung, zeitlich und mengenbegrenzt, der Stichwort, Ort, Zeiten und Lagemeldungen zeigt und Meldungen mit Foto annimmt. Es sind die ersten oeffentlich erreichbaren Endpunkte in FLORIAN. Acht neue Tabellen, alle mit organisationId und Row Level Security. Ein freigegebener Einsatzbericht ist unveraenderlich; ein Datenbanktrigger setzt das durch. Koordinaten liegen doppelt — als Dezimalgrad und als PostGIS-Punkt, zusammengehalten von einem Trigger. 57 neue Tests (32 Unit, 14 gegen eine echte Datenbank, 11 E2E). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
bc62a9c1e8
commit
91954c402b
@@ -180,6 +180,16 @@ model Organisation {
|
||||
rueckrufBetroffenheiten RueckrufBetroffenheit[]
|
||||
erinnerungen Erinnerung[]
|
||||
|
||||
// Phase 3 — Einsätze und Übungen
|
||||
einsaetze Einsatz[]
|
||||
einsatzfahrzeuge Einsatzfahrzeug[]
|
||||
einsatzkraefte Einsatzkraft[]
|
||||
materialverbrauch Materialverbrauch[]
|
||||
lagemeldungen Lagemeldung[]
|
||||
portalzugaenge PortalZugang[]
|
||||
uebungen Uebung[]
|
||||
uebungsteilnahmen Uebungsteilnahme[]
|
||||
|
||||
@@index([aktiv])
|
||||
@@map("organisation")
|
||||
}
|
||||
@@ -253,6 +263,15 @@ model Person {
|
||||
zugewieseneMaengel Mangel[] @relation("MangelZustaendig")
|
||||
behobeneMaengel Mangel[] @relation("MangelBehebung")
|
||||
|
||||
// Phase 3 — Einsätze und Übungen
|
||||
geleiteteEinsaetze Einsatz[] @relation("EinsatzLeitung")
|
||||
freigegebeneBerichte Einsatz[] @relation("EinsatzFreigabe")
|
||||
einsatzteilnahmen Einsatzkraft[] @relation("EinsatzTeilnahme")
|
||||
lagemeldungen Lagemeldung[] @relation("LagemeldungVerfasser")
|
||||
portalzugaenge PortalZugang[] @relation("PortalzugangErsteller")
|
||||
geleiteteUebungen Uebung[] @relation("UebungLeitung")
|
||||
uebungsteilnahmen Uebungsteilnahme[] @relation("UebungTeilnahme")
|
||||
|
||||
/// E-Mail und OIDC-Subject sind je Wehr eindeutig, nicht global — dieselbe
|
||||
/// Person kann in zwei Wehren Mitglied sein.
|
||||
@@unique([organisationId, email])
|
||||
@@ -482,6 +501,11 @@ model Datei {
|
||||
alsSignaturbild Signatur[] @relation("SignaturBild")
|
||||
alsMangelFoto Mangel[] @relation("MangelFoto")
|
||||
|
||||
// Phase 3
|
||||
alsEinsatzbericht Einsatz[] @relation("EinsatzBericht")
|
||||
alsLagemeldungsfoto Lagemeldung[] @relation("LagemeldungFoto")
|
||||
alsUebungsbericht Uebung[] @relation("UebungBericht")
|
||||
|
||||
@@unique([bucket, objektSchluessel])
|
||||
@@index([organisationId, entitaet, entitaetId])
|
||||
@@index([organisationId, kategorie])
|
||||
@@ -648,6 +672,10 @@ model Fahrzeug {
|
||||
geraeteraeume Geraeteraum[]
|
||||
geraete Geraet[]
|
||||
|
||||
// Phase 3
|
||||
einsaetze Einsatzfahrzeug[]
|
||||
einsatzkraefte Einsatzkraft[]
|
||||
|
||||
@@unique([organisationId, funkrufname])
|
||||
@@unique([organisationId, kennzeichen])
|
||||
@@index([organisationId, aktiv])
|
||||
@@ -783,6 +811,7 @@ model Geraet {
|
||||
pruefungen Pruefung[]
|
||||
maengel Mangel[]
|
||||
rueckrufBetroffenheiten RueckrufBetroffenheit[]
|
||||
materialverbrauch Materialverbrauch[]
|
||||
|
||||
@@unique([organisationId, inventarnummer])
|
||||
@@index([organisationId, status])
|
||||
@@ -1403,3 +1432,427 @@ model Erinnerung {
|
||||
@@index([organisationId, versendetAm(sort: Desc)])
|
||||
@@map("erinnerung")
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Phase 3 — Einsätze und Übungen
|
||||
//
|
||||
// Ordnungsprinzip:
|
||||
// Einsatz der Vorgang selbst, mit Ort, Zeitstempeln und Bericht
|
||||
// Einsatzfahrzeug welches Fahrzeug wann ausgerückt und eingerückt ist
|
||||
// Einsatzkraft wer mitgefahren ist, in welcher Funktion, wie lange
|
||||
// Materialverbrauch was dabei verbraucht oder beschädigt wurde
|
||||
// Lagemeldung was währenddessen gemeldet wurde, mit Foto
|
||||
// PortalZugang ein zeitlich begrenzter Link für eine Fremdwehr
|
||||
// Uebung dasselbe für Übungen, mit Thema und Lernzielen
|
||||
//
|
||||
// Drei Festlegungen, die den Aufbau erklären:
|
||||
//
|
||||
// 1. Die Zeitstempel sind der Kern. Alarmierung, Ausrücken, Eintreffen,
|
||||
// Einsatzende, Einrücken, Einsatzbereitschaft — daraus rechnet sich die
|
||||
// Ausrückzeit, die Anfahrtszeit und die Einsatzdauer. Sie stehen deshalb
|
||||
// einzeln und nicht als Sammelfeld.
|
||||
//
|
||||
// 2. Koordinaten liegen doppelt: als Dezimalgrad, die Prisma lesen kann, und
|
||||
// als PostGIS-Punkt für die Karte ab Phase 6. Ein Trigger hält beides
|
||||
// zusammen — sonst müsste jede Schreiboperation Roh-SQL sein.
|
||||
//
|
||||
// 3. Ein freigegebener Einsatzbericht ist unveränderbar, dieselbe Logik wie
|
||||
// beim Prüfprotokoll: er geht an die Gemeinde und an die Versicherung.
|
||||
// =============================================================================
|
||||
|
||||
/// Einsatzkategorie nach der bayerischen Feuerwehrstatistik. Danach meldet die
|
||||
/// Wehr ihre Zahlen an die Gemeinde und den Landkreis.
|
||||
enum EinsatzKategorie {
|
||||
BRAND_KLEIN
|
||||
BRAND_MITTEL
|
||||
BRAND_GROSS
|
||||
TECHNISCHE_HILFE_KLEIN
|
||||
TECHNISCHE_HILFE_MITTEL
|
||||
TECHNISCHE_HILFE_GROSS
|
||||
GEFAHRGUT
|
||||
/// Unterstützung des Rettungsdienstes, z. B. Türöffnung, Tragehilfe.
|
||||
RETTUNGSDIENST
|
||||
/// Auslösung einer Brandmeldeanlage ohne Schadenfeuer.
|
||||
BRANDMELDEANLAGE
|
||||
BOESWILLIGER_ALARM
|
||||
SICHERHEITSWACHE
|
||||
/// Amtshilfe, Nachbarschaftshilfe, Sonstiges.
|
||||
UNTERSTUETZUNG
|
||||
SONSTIGES
|
||||
}
|
||||
|
||||
/// Lebenszyklus eines Einsatzes.
|
||||
enum EinsatzStatus {
|
||||
/// Schnellerfassung: Stichwort und Fahrzeuge stehen, der Rest fehlt noch.
|
||||
ENTWURF
|
||||
/// Läuft gerade — der Alarmmonitor und das Portal zeigen ihn an.
|
||||
LAUFEND
|
||||
/// Nachbereitet und abgeschlossen.
|
||||
ABGESCHLOSSEN
|
||||
/// Bericht freigegeben und festgeschrieben.
|
||||
FREIGEGEBEN
|
||||
}
|
||||
|
||||
/// Wie alarmiert wurde. Für die Auswertung, ob die Alarmierungswege greifen.
|
||||
enum Alarmierungsart {
|
||||
SIRENE
|
||||
MELDEEMPFAENGER
|
||||
TELEFON
|
||||
APP
|
||||
PERSOENLICH
|
||||
SONSTIGES
|
||||
}
|
||||
|
||||
/// Funktion einer Einsatzkraft. Aus ihr ergibt sich die Stärke nach FwDV 3.
|
||||
enum EinsatzFunktion {
|
||||
EINSATZLEITER
|
||||
ZUGFUEHRER
|
||||
GRUPPENFUEHRER
|
||||
STAFFELFUEHRER
|
||||
TRUPPFUEHRER
|
||||
MASCHINIST
|
||||
MELDER
|
||||
TRUPPMANN
|
||||
ATEMSCHUTZTRAEGER
|
||||
SICHERHEITSTRUPP
|
||||
SANITAETER
|
||||
SONSTIGES
|
||||
}
|
||||
|
||||
/// Art einer Übung.
|
||||
enum UebungsArt {
|
||||
PRAXIS
|
||||
THEORIE
|
||||
ATEMSCHUTZ
|
||||
MASCHINIST
|
||||
FUNK
|
||||
ERSTE_HILFE
|
||||
/// Gemeinsam mit Nachbarwehren, THW oder Rettungsdienst.
|
||||
GEMEINSCHAFTSUEBUNG
|
||||
SONSTIGES
|
||||
}
|
||||
|
||||
/// Woher eine Lagemeldung kommt.
|
||||
enum LagemeldungQuelle {
|
||||
/// Aus der Anwendung, von einer angemeldeten Person.
|
||||
INTERN
|
||||
/// Über den Portal-Link, von einer Fremdwehr ohne Konto.
|
||||
PORTAL
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/// Ein Einsatz.
|
||||
model Einsatz {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
organisationId String @db.Uuid
|
||||
|
||||
/// Fortlaufend je Wehr und Jahr, Format "JJJJ-NNNN".
|
||||
einsatznummer String @db.VarChar(40)
|
||||
/// Einsatzstichwort der Leitstelle, z. B. "B 3 Wohnhausbrand".
|
||||
stichwort String @db.VarChar(160)
|
||||
kategorie EinsatzKategorie @default(SONSTIGES)
|
||||
status EinsatzStatus @default(ENTWURF)
|
||||
|
||||
/// Einsatznummer der Integrierten Leitstelle — die Klammer zu deren Akte.
|
||||
ilsNummer String? @db.VarChar(60)
|
||||
alarmierungsart Alarmierungsart?
|
||||
|
||||
// Ort
|
||||
strasse String? @db.VarChar(200)
|
||||
hausnummer String? @db.VarChar(20)
|
||||
plz String? @db.VarChar(10)
|
||||
ort String? @db.VarChar(120)
|
||||
ortsteil String? @db.VarChar(120)
|
||||
/// Objektbezeichnung, z. B. "Grundschule", "Autobahn A9, km 312".
|
||||
objekt String? @db.VarChar(200)
|
||||
|
||||
/// Koordinaten als Dezimalgrad — von Prisma lesbar.
|
||||
breitengrad Decimal? @db.Decimal(9, 6)
|
||||
laengengrad Decimal? @db.Decimal(9, 6)
|
||||
/// Dieselben Koordinaten als PostGIS-Punkt, von einem Trigger gepflegt.
|
||||
/// Ab Phase 6 zeichnet die Karte daraus.
|
||||
koordinaten Unsupported("geography(Point, 4326)")?
|
||||
/// Woher sie stammen: "nominatim", "manuell", "leitstelle".
|
||||
koordinatenQuelle String? @db.VarChar(40)
|
||||
|
||||
// Zeitstempel — der Kern jeder Einsatzauswertung
|
||||
alarmiertUm DateTime? @db.Timestamptz(3)
|
||||
ausgeruecktUm DateTime? @db.Timestamptz(3)
|
||||
eingetroffenUm DateTime? @db.Timestamptz(3)
|
||||
einsatzendeUm DateTime? @db.Timestamptz(3)
|
||||
eingeruecktUm DateTime? @db.Timestamptz(3)
|
||||
einsatzbereitUm DateTime? @db.Timestamptz(3)
|
||||
|
||||
einsatzleiterId String? @db.Uuid
|
||||
|
||||
beschreibung String? @db.VarChar(4000)
|
||||
bericht String?
|
||||
|
||||
wetter String? @db.VarChar(200)
|
||||
temperatur Int?
|
||||
/// Wer sonst vor Ort war: Polizei, Rettungsdienst, THW, Nachbarwehren.
|
||||
weitereKraefte String? @db.VarChar(500)
|
||||
|
||||
/// Zahlen für die Statistik der Gemeinde.
|
||||
geretteteePersonen Int @default(0)
|
||||
verletztePersonen Int @default(0)
|
||||
totePersonen Int @default(0)
|
||||
sachschaden Decimal? @db.Decimal(12, 2)
|
||||
/// Kostenersatzpflichtiger Einsatz (Art. 28 BayFwG).
|
||||
kostenpflichtig Boolean @default(false)
|
||||
|
||||
/// Der erzeugte Einsatzbericht als PDF.
|
||||
berichtDateiId String? @db.Uuid
|
||||
freigegebenAm DateTime? @db.Timestamptz(3)
|
||||
freigegebenVonId String? @db.Uuid
|
||||
|
||||
erstelltAm DateTime @default(now()) @db.Timestamptz(3)
|
||||
geaendertAm DateTime @updatedAt @db.Timestamptz(3)
|
||||
geloeschtAm DateTime? @db.Timestamptz(3)
|
||||
|
||||
organisation Organisation @relation(fields: [organisationId], references: [id], onDelete: Cascade)
|
||||
einsatzleiter Person? @relation("EinsatzLeitung", fields: [einsatzleiterId], references: [id], onDelete: SetNull)
|
||||
freigegebenVon Person? @relation("EinsatzFreigabe", fields: [freigegebenVonId], references: [id], onDelete: SetNull)
|
||||
berichtDatei Datei? @relation("EinsatzBericht", fields: [berichtDateiId], references: [id], onDelete: SetNull)
|
||||
fahrzeuge Einsatzfahrzeug[]
|
||||
kraefte Einsatzkraft[]
|
||||
material Materialverbrauch[]
|
||||
lagemeldungen Lagemeldung[]
|
||||
portalzugaenge PortalZugang[]
|
||||
|
||||
@@unique([organisationId, einsatznummer])
|
||||
@@index([organisationId, alarmiertUm(sort: Desc)])
|
||||
@@index([organisationId, status])
|
||||
@@index([organisationId, kategorie])
|
||||
@@map("einsatz")
|
||||
}
|
||||
|
||||
/// Ein Fahrzeug in einem Einsatz, mit eigenen Zeiten: nicht jedes Fahrzeug
|
||||
/// rückt gleichzeitig aus, und die Nachalarmierung soll sichtbar bleiben.
|
||||
model Einsatzfahrzeug {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
organisationId String @db.Uuid
|
||||
einsatzId String @db.Uuid
|
||||
fahrzeugId String @db.Uuid
|
||||
|
||||
ausgeruecktUm DateTime? @db.Timestamptz(3)
|
||||
eingetroffenUm DateTime? @db.Timestamptz(3)
|
||||
eingeruecktUm DateTime? @db.Timestamptz(3)
|
||||
|
||||
kilometerAbfahrt Int?
|
||||
kilometerRueckkehr Int?
|
||||
/// Verbrauchtes Löschwasser in Litern.
|
||||
wasserabgabe Int?
|
||||
bemerkung String? @db.VarChar(500)
|
||||
|
||||
erstelltAm DateTime @default(now()) @db.Timestamptz(3)
|
||||
geaendertAm DateTime @updatedAt @db.Timestamptz(3)
|
||||
|
||||
organisation Organisation @relation(fields: [organisationId], references: [id], onDelete: Cascade)
|
||||
einsatz Einsatz @relation(fields: [einsatzId], references: [id], onDelete: Cascade)
|
||||
fahrzeug Fahrzeug @relation(fields: [fahrzeugId], references: [id], onDelete: Restrict)
|
||||
|
||||
@@unique([einsatzId, fahrzeugId])
|
||||
@@index([organisationId, einsatzId])
|
||||
@@index([organisationId, fahrzeugId])
|
||||
@@map("einsatzfahrzeug")
|
||||
}
|
||||
|
||||
/// Wer mitgefahren ist. Grundlage für die Stärkemeldung nach FwDV 3 und für
|
||||
/// den Beteiligungsnachweis je Person.
|
||||
model Einsatzkraft {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
organisationId String @db.Uuid
|
||||
einsatzId String @db.Uuid
|
||||
personId String @db.Uuid
|
||||
|
||||
funktion EinsatzFunktion @default(TRUPPMANN)
|
||||
/// Auf welchem Fahrzeug — leer, wenn jemand selbst angefahren ist.
|
||||
fahrzeugId String? @db.Uuid
|
||||
|
||||
vonUm DateTime? @db.Timestamptz(3)
|
||||
bisUm DateTime? @db.Timestamptz(3)
|
||||
|
||||
/// War unter Atemschutz im Einsatz. Zählt auf die Nachweise nach FwDV 7.
|
||||
atemschutz Boolean @default(false)
|
||||
bemerkung String? @db.VarChar(500)
|
||||
|
||||
erstelltAm DateTime @default(now()) @db.Timestamptz(3)
|
||||
geaendertAm DateTime @updatedAt @db.Timestamptz(3)
|
||||
|
||||
organisation Organisation @relation(fields: [organisationId], references: [id], onDelete: Cascade)
|
||||
einsatz Einsatz @relation(fields: [einsatzId], references: [id], onDelete: Cascade)
|
||||
person Person @relation("EinsatzTeilnahme", fields: [personId], references: [id], onDelete: Cascade)
|
||||
fahrzeug Fahrzeug? @relation(fields: [fahrzeugId], references: [id], onDelete: SetNull)
|
||||
|
||||
@@unique([einsatzId, personId])
|
||||
@@index([organisationId, einsatzId])
|
||||
@@index([organisationId, personId])
|
||||
@@map("einsatzkraft")
|
||||
}
|
||||
|
||||
/// Was verbraucht oder beschädigt wurde — Schaummittel, Bindemittel, ein
|
||||
/// zerschnittener Schlauch. Grundlage für Nachbeschaffung und Kostenersatz.
|
||||
model Materialverbrauch {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
organisationId String @db.Uuid
|
||||
einsatzId String @db.Uuid
|
||||
/// Verweis auf ein erfasstes Gerät, wo es eines gibt.
|
||||
geraetId String? @db.Uuid
|
||||
|
||||
bezeichnung String @db.VarChar(200)
|
||||
menge Decimal @db.Decimal(10, 2)
|
||||
einheit String @db.VarChar(20)
|
||||
kosten Decimal? @db.Decimal(10, 2)
|
||||
/// Nicht verbraucht, sondern kaputtgegangen — dann folgt ein Mangel.
|
||||
beschaedigt Boolean @default(false)
|
||||
bemerkung String? @db.VarChar(500)
|
||||
|
||||
erstelltAm DateTime @default(now()) @db.Timestamptz(3)
|
||||
|
||||
organisation Organisation @relation(fields: [organisationId], references: [id], onDelete: Cascade)
|
||||
einsatz Einsatz @relation(fields: [einsatzId], references: [id], onDelete: Cascade)
|
||||
geraet Geraet? @relation(fields: [geraetId], references: [id], onDelete: SetNull)
|
||||
|
||||
@@index([organisationId, einsatzId])
|
||||
@@map("materialverbrauch")
|
||||
}
|
||||
|
||||
/// Eine Meldung während des Einsatzes. Aus der Anwendung oder über den
|
||||
/// Portal-Link einer Fremdwehr.
|
||||
model Lagemeldung {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
organisationId String @db.Uuid
|
||||
einsatzId String @db.Uuid
|
||||
|
||||
zeitpunkt DateTime @default(now()) @db.Timestamptz(3)
|
||||
text String @db.VarChar(2000)
|
||||
quelle LagemeldungQuelle @default(INTERN)
|
||||
|
||||
verfasserId String? @db.Uuid
|
||||
/// Klarname oder Wehrname — bei Portalmeldungen die einzige Angabe.
|
||||
verfasserName String? @db.VarChar(200)
|
||||
|
||||
fotoDateiId String? @db.Uuid
|
||||
/// Hebt die Meldung im Verlauf hervor: Menschenrettung, Nachforderung,
|
||||
/// Lageänderung.
|
||||
wichtig Boolean @default(false)
|
||||
|
||||
/// Über welchen Portalzugang die Meldung kam.
|
||||
portalZugangId String? @db.Uuid
|
||||
|
||||
erstelltAm DateTime @default(now()) @db.Timestamptz(3)
|
||||
geloeschtAm DateTime? @db.Timestamptz(3)
|
||||
|
||||
organisation Organisation @relation(fields: [organisationId], references: [id], onDelete: Cascade)
|
||||
einsatz Einsatz @relation(fields: [einsatzId], references: [id], onDelete: Cascade)
|
||||
verfasser Person? @relation("LagemeldungVerfasser", fields: [verfasserId], references: [id], onDelete: SetNull)
|
||||
foto Datei? @relation("LagemeldungFoto", fields: [fotoDateiId], references: [id], onDelete: SetNull)
|
||||
portalZugang PortalZugang? @relation(fields: [portalZugangId], references: [id], onDelete: SetNull)
|
||||
|
||||
@@index([organisationId, einsatzId, zeitpunkt])
|
||||
@@map("lagemeldung")
|
||||
}
|
||||
|
||||
/// Ein zeitlich begrenzter Zugang zum Einsatzportal für eine Fremdwehr.
|
||||
///
|
||||
/// Der Link enthält die Kennung und ein Geheimnis; gespeichert wird nur dessen
|
||||
/// Hash. Er gilt bis gueltigBis, lässt sich jederzeit widerrufen und zählt
|
||||
/// jeden Aufruf mit — ein Link, der nach dem Einsatz noch benutzt wird, fällt
|
||||
/// so auf.
|
||||
model PortalZugang {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
organisationId String @db.Uuid
|
||||
einsatzId String @db.Uuid
|
||||
|
||||
/// Für wen der Link ist, z. B. "FF Nachbarhausen".
|
||||
bezeichnung String @db.VarChar(160)
|
||||
/// bcrypt-Hash des Geheimnisses aus dem Link.
|
||||
tokenHash String @db.VarChar(120)
|
||||
|
||||
gueltigBis DateTime @db.Timestamptz(3)
|
||||
widerrufenAm DateTime? @db.Timestamptz(3)
|
||||
|
||||
aufrufe Int @default(0)
|
||||
letzterAufruf DateTime? @db.Timestamptz(3)
|
||||
/// Zuletzt sehende IP — für den Fall, dass ein Link weitergegeben wurde.
|
||||
letzteIp String? @db.Inet
|
||||
|
||||
erstelltVonId String? @db.Uuid
|
||||
erstelltAm DateTime @default(now()) @db.Timestamptz(3)
|
||||
geaendertAm DateTime @updatedAt @db.Timestamptz(3)
|
||||
|
||||
organisation Organisation @relation(fields: [organisationId], references: [id], onDelete: Cascade)
|
||||
einsatz Einsatz @relation(fields: [einsatzId], references: [id], onDelete: Cascade)
|
||||
erstelltVon Person? @relation("PortalzugangErsteller", fields: [erstelltVonId], references: [id], onDelete: SetNull)
|
||||
lagemeldungen Lagemeldung[]
|
||||
|
||||
@@index([organisationId, einsatzId])
|
||||
@@index([gueltigBis])
|
||||
@@map("portal_zugang")
|
||||
}
|
||||
|
||||
/// Eine Übung. Aufgebaut wie ein Einsatz, aber mit Ausbildungsthema und
|
||||
/// Lernzielen statt Schadenlage — und ohne Portal.
|
||||
model Uebung {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
organisationId String @db.Uuid
|
||||
|
||||
/// Fortlaufend je Wehr und Jahr, Format "JJJJ-NNNN".
|
||||
nummer String @db.VarChar(40)
|
||||
thema String @db.VarChar(200)
|
||||
art UebungsArt @default(PRAXIS)
|
||||
|
||||
datum DateTime @db.Date
|
||||
beginnUm DateTime? @db.Timestamptz(3)
|
||||
endeUm DateTime? @db.Timestamptz(3)
|
||||
|
||||
ort String? @db.VarChar(200)
|
||||
leiterId String? @db.Uuid
|
||||
|
||||
/// Was gelernt werden soll — die Lernziele der Ausbildung.
|
||||
lernziele String? @db.VarChar(2000)
|
||||
beschreibung String? @db.VarChar(4000)
|
||||
bericht String?
|
||||
|
||||
berichtDateiId String? @db.Uuid
|
||||
|
||||
erstelltAm DateTime @default(now()) @db.Timestamptz(3)
|
||||
geaendertAm DateTime @updatedAt @db.Timestamptz(3)
|
||||
geloeschtAm DateTime? @db.Timestamptz(3)
|
||||
|
||||
organisation Organisation @relation(fields: [organisationId], references: [id], onDelete: Cascade)
|
||||
leiter Person? @relation("UebungLeitung", fields: [leiterId], references: [id], onDelete: SetNull)
|
||||
berichtDatei Datei? @relation("UebungBericht", fields: [berichtDateiId], references: [id], onDelete: SetNull)
|
||||
teilnahmen Uebungsteilnahme[]
|
||||
|
||||
@@unique([organisationId, nummer])
|
||||
@@index([organisationId, datum(sort: Desc)])
|
||||
@@index([organisationId, art])
|
||||
@@map("uebung")
|
||||
}
|
||||
|
||||
/// Wer an einer Übung teilgenommen hat. Der Nachweis, den eine Wehr für die
|
||||
/// Beförderung und für die Statistik braucht.
|
||||
model Uebungsteilnahme {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
organisationId String @db.Uuid
|
||||
uebungId String @db.Uuid
|
||||
personId String @db.Uuid
|
||||
|
||||
funktion EinsatzFunktion?
|
||||
vonUm DateTime? @db.Timestamptz(3)
|
||||
bisUm DateTime? @db.Timestamptz(3)
|
||||
bemerkung String? @db.VarChar(500)
|
||||
|
||||
erstelltAm DateTime @default(now()) @db.Timestamptz(3)
|
||||
|
||||
organisation Organisation @relation(fields: [organisationId], references: [id], onDelete: Cascade)
|
||||
uebung Uebung @relation(fields: [uebungId], references: [id], onDelete: Cascade)
|
||||
person Person @relation("UebungTeilnahme", fields: [personId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([uebungId, personId])
|
||||
@@index([organisationId, personId])
|
||||
@@map("uebungsteilnahme")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user