280 lines
8.7 KiB
Plaintext
280 lines
8.7 KiB
Plaintext
// This is your Prisma schema file,
|
|
// learn more about it in the docs: https://pris.ly/d/prisma-schema
|
|
|
|
generator client {
|
|
provider = "prisma-client-js"
|
|
output = "../node_modules/.prisma/client"
|
|
}
|
|
|
|
datasource db {
|
|
provider = "postgresql"
|
|
url = env("DATABASE_URL")
|
|
}
|
|
|
|
model User {
|
|
id Int @id @default(autoincrement())
|
|
email String @unique
|
|
username String @unique
|
|
password String
|
|
role String @default("Student")
|
|
|
|
// Password Reset
|
|
passwordResetToken String?
|
|
passwordResetExpires DateTime?
|
|
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
receivedGrades Grade[] @relation("ReceivedGrades") // Noten, die Schüler erhalten haben
|
|
assignedGrades Grade[] @relation("AssignedGrades") // Noten, die Lehrer vergeben haben
|
|
chatMessages ChatMessage[]
|
|
chatGroups ChatGroupMember[]
|
|
studentFeedbacks Feedback[] @relation("StudentFeedbacks")
|
|
teacherFeedbacks Feedback[] @relation("TeacherFeedbacks")
|
|
taughtTimetableEntries TimetableEntry[] @relation("TeacherTimetableEntries")
|
|
createdChatGroups ChatGroup[] @relation("ChatGroupCreator")
|
|
uploadedFiles File[]
|
|
}
|
|
|
|
// Neue Tabelle: File (Dateien)
|
|
model File {
|
|
id Int @id @default(autoincrement())
|
|
filename String
|
|
path String
|
|
mimetype String
|
|
size Int
|
|
|
|
uploadedById Int
|
|
uploadedBy User @relation(fields: [uploadedById], references: [id], onDelete: Cascade)
|
|
|
|
timetableEntryId Int?
|
|
timetableEntry TimetableEntry? @relation(fields: [timetableEntryId], references: [id], onDelete: Cascade)
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
@@index([uploadedById])
|
|
@@index([timetableEntryId])
|
|
}
|
|
|
|
// Neue Tabelle: Subject (Fächer)
|
|
model Subject {
|
|
id Int @id @default(autoincrement())
|
|
name String @unique // z.B. "Mathematik", "Deutsch", "Englisch"
|
|
abbreviation String? // z.B. "Mathe", "DE", "EN"
|
|
color String? // Farbe für UI (z.B. "#FF5733")
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
timetableEntries TimetableEntry[]
|
|
|
|
@@index([name])
|
|
}
|
|
|
|
// Neue Tabelle: Room (Räume)
|
|
model Room {
|
|
id Int @id @default(autoincrement())
|
|
number String @unique // z.B. "A101", "B203"
|
|
building String? // z.B. "Hauptgebäude", "Neubau"
|
|
capacity Int? // Anzahl Sitzplätze
|
|
equipment String? // z.B. "Beamer, Whiteboard"
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
timetableEntries TimetableEntry[]
|
|
|
|
@@index([number])
|
|
}
|
|
|
|
model TimetableEntry {
|
|
id Int @id @default(autoincrement())
|
|
dayOfWeek Int // 1 = Montag, 2 = Dienstag, ..., 5 = Freitag
|
|
startTime String // Format: "08:00"
|
|
endTime String // Format: "09:30"
|
|
|
|
// Normalisierte Relationen
|
|
subjectId Int
|
|
subject Subject @relation(fields: [subjectId], references: [id], onDelete: Restrict)
|
|
|
|
teacherId Int?
|
|
teacher User? @relation("TeacherTimetableEntries", fields: [teacherId], references: [id], onDelete: SetNull)
|
|
|
|
roomId Int?
|
|
room Room? @relation(fields: [roomId], references: [id], onDelete: SetNull)
|
|
|
|
// Wochenbasierte Planung
|
|
weekNumber Int? // Kalenderwoche (1-53), null = alle Wochen
|
|
year Int? // Jahr (z.B. 2025), null = alle Jahre
|
|
isRecurring Boolean @default(true) // true = wiederholt sich jede Woche, false = nur für spezifische Woche
|
|
|
|
allowStudentUploads Boolean @default(false)
|
|
files File[]
|
|
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
feedbacks Feedback[]
|
|
grades Grade[]
|
|
|
|
@@index([dayOfWeek])
|
|
@@index([weekNumber, year])
|
|
@@index([subjectId])
|
|
@@index([teacherId])
|
|
@@index([roomId])
|
|
}
|
|
|
|
model Feedback {
|
|
id Int @id @default(autoincrement())
|
|
|
|
// Foreign Key Relations zu User-Tabelle
|
|
studentId Int
|
|
student User @relation("StudentFeedbacks", fields: [studentId], references: [id], onDelete: Cascade)
|
|
|
|
teacherId Int
|
|
teacher User @relation("TeacherFeedbacks", fields: [teacherId], references: [id], onDelete: Cascade)
|
|
|
|
// Foreign Key Relation zu TimetableEntry
|
|
lessonId Int
|
|
timetableEntry TimetableEntry @relation(fields: [lessonId], references: [id], onDelete: Cascade)
|
|
lessonDate DateTime
|
|
|
|
overallRating Int
|
|
|
|
// Prisma Json-Typ für Kategorien
|
|
categories Json?
|
|
|
|
whatWasGood String?
|
|
whatCanImprove String?
|
|
additionalComments String?
|
|
|
|
isAnonymous Boolean @default(false)
|
|
allowTeacherResponse Boolean @default(true)
|
|
|
|
teacherResponse String?
|
|
teacherRespondedAt DateTime?
|
|
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Unique Constraint: Ein Schüler kann nur einmal pro Stunde Feedback geben
|
|
@@unique([studentId, lessonId])
|
|
@@index([studentId])
|
|
@@index([teacherId])
|
|
@@index([lessonId])
|
|
}
|
|
|
|
model Grade {
|
|
id Int @id @default(autoincrement())
|
|
|
|
// Schüler-Information (erhält die Note)
|
|
studentId Int
|
|
student User @relation("ReceivedGrades", fields: [studentId], references: [id], onDelete: Cascade)
|
|
|
|
// Stundenplan-Bezug
|
|
timetableEntryId Int
|
|
timetableEntry TimetableEntry @relation(fields: [timetableEntryId], references: [id], onDelete: Cascade)
|
|
|
|
// Wochenbezug (Note gilt für eine spezifische Woche)
|
|
weekNumber Int // Kalenderwoche (1-53)
|
|
year Int // Jahr (z.B. 2025)
|
|
|
|
// Noten-Details
|
|
grade Float // z.B. 1.0, 2.5, 3.0 (deutsches Notensystem)
|
|
gradeType String // z.B. "Klausur", "Mitarbeit", "Hausaufgabe", "Mündlich"
|
|
weight Float? @default(1.0) // Gewichtung der Note (z.B. Klausur = 2.0, Mitarbeit = 1.0)
|
|
|
|
// Lehrer-Information (vergibt die Note)
|
|
teacherId Int
|
|
teacher User @relation("AssignedGrades", fields: [teacherId], references: [id], onDelete: Restrict)
|
|
|
|
// Optional: Detailbeschreibung
|
|
title String? // z.B. "Mathearbeit Kapitel 3"
|
|
description String? // Zusätzliche Informationen
|
|
maxPoints Float? // Maximale Punktzahl
|
|
achievedPoints Float? // Erreichte Punktzahl
|
|
|
|
// Datum
|
|
date DateTime // Datum der Leistung
|
|
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@unique([studentId, timetableEntryId, weekNumber, year, gradeType])
|
|
@@index([studentId])
|
|
@@index([timetableEntryId])
|
|
@@index([teacherId])
|
|
@@index([weekNumber, year])
|
|
}
|
|
|
|
model ChatGroup {
|
|
id Int @id @default(autoincrement())
|
|
name String
|
|
description String?
|
|
|
|
createdById Int // Lehrer, der die Gruppe erstellt hat
|
|
createdBy User @relation("ChatGroupCreator", fields: [createdById], references: [id], onDelete: Restrict)
|
|
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
members ChatGroupMember[]
|
|
messages ChatMessage[]
|
|
|
|
@@index([createdById])
|
|
}
|
|
|
|
model ChatGroupMember {
|
|
id Int @id @default(autoincrement())
|
|
|
|
userId Int
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
groupId Int
|
|
group ChatGroup @relation(fields: [groupId], references: [id], onDelete: Cascade)
|
|
|
|
joinedAt DateTime @default(now())
|
|
|
|
@@unique([userId, groupId])
|
|
@@index([userId])
|
|
@@index([groupId])
|
|
}
|
|
|
|
model ChatMessage {
|
|
id Int @id @default(autoincrement())
|
|
content String
|
|
|
|
userId Int
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
groupId Int
|
|
group ChatGroup @relation(fields: [groupId], references: [id], onDelete: Cascade)
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
@@index([groupId])
|
|
@@index([userId])
|
|
@@index([createdAt])
|
|
}
|
|
|
|
model Student {
|
|
studentId Int @id @default(autoincrement()) @map("student_id")
|
|
studentFirstName String @map("student_first_name")
|
|
studentLastName String @map("student_last_name")
|
|
studentClassName String? @map("student_class_name")
|
|
studentRfidCardUid String @unique @map("student_rfid_card_uid")
|
|
studentCardIsActive Boolean @default(true) @map("student_card_is_active")
|
|
attendanceLogs AttendanceLog[]
|
|
|
|
@@map("students")
|
|
}
|
|
|
|
model AttendanceLog {
|
|
attendanceLogId Int @id @default(autoincrement()) @map("attendance_log_id")
|
|
studentId Int @map("student_id")
|
|
student Student @relation(fields: [studentId], references: [studentId], onDelete: Cascade)
|
|
attendanceScannedAt DateTime @map("attendance_scanned_at")
|
|
attendanceEventType String @map("attendance_event_type")
|
|
wasManualEntry Boolean @default(false) @map("was_manual_entry")
|
|
manualEntryReason String? @map("manual_entry_reason")
|
|
|
|
@@index([studentId, attendanceScannedAt])
|
|
@@map("attendance_logs")
|
|
}
|