Round 26: Grade Analytics, School Transport, Peer Assessment, Styling
- Grade Analytics & Reporting View: distribution histogram, student trajectory, class comparison, subject analysis, report generation - School Transport & Bus Routes View: route management, student assignment, transport schedule, stop management - Peer Assessment View: creation wizard, rating sliders, results radar chart, self vs peer comparison - 3 new Prisma models: GradeReport, TransportRoute, TransportStop - Extended PeerAssessment and StudentTransport models - Enhanced classes-view with gradient header, glassmorphism cards - Enhanced attendance-view with attendance rate gauge, status indicators - Fixed duplicate variable name bugs in school-transport-view.tsx - 12+ new API route files - 300+ i18n keys added - All views verified working in browser
This commit is contained in:
1 parent
3d0d518bb9
commit
7f0810c88f
28 files changed
+10264
-127
No files matched your search
+119
-13
@@ -68,10 +68,12 @@ model School {
|
||||
resources Resource[]
|
||||
emailTemplates EmailTemplate[]
|
||||
emailLogs EmailLog[]
|
||||
peerAssessments PeerAssessment[]
|
||||
emergencyContacts EmergencyContact[]
|
||||
peerAssessments PeerAssessment[]
|
||||
peerAssessmentSessions PeerAssessmentSession[]
|
||||
emergencyContacts EmergencyContact[]
|
||||
schoolEvents SchoolEvent[]
|
||||
studentTransports StudentTransport[]
|
||||
transportRoutes TransportRoute[]
|
||||
healthRecords HealthRecord[]
|
||||
badges Badge[]
|
||||
studentBadges StudentBadge[]
|
||||
@@ -93,6 +95,7 @@ model School {
|
||||
counselingAppointments CounselingAppointment[]
|
||||
disciplinaryCommittees DisciplinaryCommittee[]
|
||||
communicationRooms CommunicationRoom[]
|
||||
gradeReports GradeReport[]
|
||||
aiTestGenerations AITestGeneration[]
|
||||
gradingReviews TeacherGradingReview[]
|
||||
gradingAnnotations GradingAnnotation[]
|
||||
@@ -195,7 +198,9 @@ model User {
|
||||
responsibleClasses ClassGroup[] @relation("ResponsibleTeacher")
|
||||
examPlans ExamPlan[]
|
||||
seatingCharts SeatingChart[]
|
||||
peerAssessmentSessions PeerAssessmentSession[] @relation("PeerAssessmentTeacher")
|
||||
bookCheckouts BookCheckout[]
|
||||
gradeReports GradeReport[] @relation("GradeReportGenerator")
|
||||
bookReservations BookReservation[]
|
||||
dataImportJobs DataImportJob[]
|
||||
dataExportJobs DataExportJob[]
|
||||
@@ -256,6 +261,7 @@ model ClassGroup {
|
||||
timetableSlots TimetableSlot[]
|
||||
resources Resource[]
|
||||
peerAssessments PeerAssessment[]
|
||||
peerAssessmentSessions PeerAssessmentSession[] @relation("PeerAssessmentClassGroup")
|
||||
schoolEvents SchoolEvent[]
|
||||
aiTestGenerations AITestGeneration[]
|
||||
examPlans ExamPlan[]
|
||||
@@ -1579,24 +1585,57 @@ model EmailLog {
|
||||
|
||||
// ─── Peer Assessment ──────────────────────────────────────────────
|
||||
|
||||
model PeerAssessment {
|
||||
model PeerAssessmentSession {
|
||||
id String @id @default(cuid())
|
||||
schoolId String
|
||||
assessorId String // student who is assessing
|
||||
assessedId String // student being assessed
|
||||
competencyId String?
|
||||
teacherId String? // teacher who created the session
|
||||
classGroupId String?
|
||||
assessmentType String // "competency", "project", "presentation", "teamwork", "behavior"
|
||||
level Int? // 1-6 rating
|
||||
comment String?
|
||||
rubricId String? // optional rubric reference
|
||||
isAnonymous Boolean @default(false)
|
||||
title String
|
||||
description String?
|
||||
assessmentType String @default("competency") // competency, project, presentation, teamwork
|
||||
criteria String? // JSON: [{ name, description, maxScore }]
|
||||
anonymityMode String @default("anonymous") // anonymous, semi-anonymous, open
|
||||
status String @default("active") // active, completed, closed
|
||||
deadline DateTime?
|
||||
assignMode String @default("manual") // random, manual, group-based
|
||||
assignedPairs String? // JSON: [{ assessorId, assessedId }]
|
||||
isDemo Boolean @default(false)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime?
|
||||
|
||||
school School @relation(fields: [schoolId], references: [id])
|
||||
teacher User? @relation("PeerAssessmentTeacher", fields: [teacherId], references: [id])
|
||||
classGroup ClassGroup? @relation("PeerAssessmentClassGroup", fields: [classGroupId], references: [id])
|
||||
peerAssessments PeerAssessment[]
|
||||
|
||||
@@index([schoolId, status])
|
||||
@@index([schoolId, teacherId])
|
||||
@@map("peer_assessment_sessions")
|
||||
}
|
||||
|
||||
model PeerAssessment {
|
||||
id String @id @default(cuid())
|
||||
schoolId String
|
||||
sessionId String? // link to session
|
||||
assessorId String // student who is assessing
|
||||
assessedId String // student being assessed
|
||||
competencyId String?
|
||||
classGroupId String?
|
||||
assessmentType String // "competency", "project", "presentation", "teamwork", "behavior"
|
||||
criteria String? // JSON: [{ name, score, maxScore }] — individual criterion scores
|
||||
level Int? // 1-6 rating (overall)
|
||||
comment String?
|
||||
rubricId String? // optional rubric reference
|
||||
isAnonymous Boolean @default(false)
|
||||
status String @default("pending") // pending, submitted
|
||||
isDemo Boolean @default(false)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime?
|
||||
|
||||
school School @relation(fields: [schoolId], references: [id])
|
||||
session PeerAssessmentSession? @relation(fields: [sessionId], references: [id])
|
||||
assessor Student @relation("PeerAssessor", fields: [assessorId], references: [id])
|
||||
assessed Student @relation("PeerAssessed", fields: [assessedId], references: [id])
|
||||
competency Competency? @relation(fields: [competencyId], references: [id])
|
||||
@@ -1605,6 +1644,7 @@ model PeerAssessment {
|
||||
|
||||
@@index([schoolId, assessedId])
|
||||
@@index([schoolId, assessorId])
|
||||
@@index([sessionId])
|
||||
@@map("peer_assessments")
|
||||
}
|
||||
|
||||
@@ -1721,19 +1761,62 @@ model StudentTransport {
|
||||
driverName String? // for car/bus
|
||||
driverPhone String? // for car/bus
|
||||
distanceKm Float? // distance in km
|
||||
routeId String? // link to TransportRoute
|
||||
notes String?
|
||||
isDemo Boolean @default(false)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime?
|
||||
|
||||
school School @relation(fields: [schoolId], references: [id])
|
||||
student Student @relation(fields: [studentId], references: [id])
|
||||
school School @relation(fields: [schoolId], references: [id])
|
||||
student Student @relation(fields: [studentId], references: [id])
|
||||
route TransportRoute? @relation(fields: [routeId], references: [id])
|
||||
|
||||
@@index([schoolId, studentId])
|
||||
@@map("student_transport")
|
||||
}
|
||||
|
||||
model TransportRoute {
|
||||
id String @id @default(cuid())
|
||||
schoolId String
|
||||
routeNumber String
|
||||
routeName String
|
||||
transportType String // bus, tram, train
|
||||
driverName String?
|
||||
driverPhone String?
|
||||
capacity Int @default(40)
|
||||
isActive Boolean @default(true)
|
||||
notes String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime?
|
||||
|
||||
school School @relation(fields: [schoolId], references: [id])
|
||||
stops TransportStop[]
|
||||
assignments StudentTransport[]
|
||||
|
||||
@@index([schoolId])
|
||||
@@map("transport_route")
|
||||
}
|
||||
|
||||
model TransportStop {
|
||||
id String @id @default(cuid())
|
||||
routeId String
|
||||
stopName String
|
||||
stopOrder Int
|
||||
pickupTime String? // "07:45"
|
||||
dropoffTime String? // "15:30"
|
||||
address String?
|
||||
latitude Float?
|
||||
longitude Float?
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
route TransportRoute @relation(fields: [routeId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([routeId])
|
||||
@@map("transport_stop")
|
||||
}
|
||||
|
||||
// ─── Health Records ──────────────────────────────────────────────
|
||||
|
||||
model HealthRecord {
|
||||
@@ -3110,3 +3193,26 @@ model SubstitutionAssignment {
|
||||
@@index([date])
|
||||
@@map("substitution_assignments")
|
||||
}
|
||||
|
||||
// ─── Grade Analytics & Reporting ──────────────────────────────────
|
||||
|
||||
model GradeReport {
|
||||
id String @id @default(cuid())
|
||||
schoolId String
|
||||
generatedBy String
|
||||
title String
|
||||
type String @default("custom") // quarterly, semester, annual, custom
|
||||
dateRange String // JSON: { from, to }
|
||||
classIds String? // JSON: array of class IDs
|
||||
subjectIds String? // JSON: array of subject IDs
|
||||
metrics String? // JSON: array of selected metrics
|
||||
status String @default("pending") // pending, completed, failed
|
||||
fileData String? // Base64 encoded or JSON report data
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
school School @relation(fields: [schoolId], references: [id])
|
||||
generator User @relation("GradeReportGenerator", fields: [generatedBy], references: [id])
|
||||
|
||||
@@index([schoolId])
|
||||
@@index([generatedBy])
|
||||
}
|
||||
Reference in new issue
Block a user