Architecture cleanup: Remove orphans from audit report (37 files)

Deleted orphan component files (4):
- dashboard-customizer.tsx (never imported)
- unified-communication.tsx (never imported)
- data-table.tsx (never imported)
- widget-container.tsx (only imported by orphan dashboard-customizer)

Deleted unused shadcn/ui primitives (15):
- accordion, aspect-ratio, calendar, carousel, chart, form,
  hover-card, input-otp, menubar, navigation-menu, pagination,
  radio-group, resizable, toaster, toggle-group
(All verified as zero importers)

Deleted orphan API route groups (6 directories, 13 route files):
- ai-grading-audit (no caller)
- demo-data (no caller)
- exam-plans (no caller)
- grade-analytics (no caller, dead renderView case also removed)
- grading-annotations (no caller)
- grading-reviews (no caller)

Removed dead grade-analytics renderView case + ViewName type entry

Removed 10 orphan database models from schema:
- NotificationHub, NotificationArchive (superseded by Notification)
- WidgetTemplate (dashboard customizer feature abandoned)
- EmergencySignage, SignageMessage, SignageSchedule, SignageAuditLog
  (signage feature - no API routes implemented)
- SchoolPolicy, EscalationPolicy, ClassMessagingLock
  (policy/messaging lock feature - never wired)
Also removed 16 relation fields pointing to deleted models.

Schema validated, db pushed, lint passes, all 10 tested modules work.
This commit is contained in:
Z User committed 2026-08-11 11:03:24 +00:00
1 parent 333f3e9466
commit e5c761a179
37 files changed
-5279

No files matched your search

-231
View File
@@ -35,9 +35,6 @@ model School {
phone String? // school phone number
users User[]
schoolPolicies SchoolPolicy[]
escalationPolicies EscalationPolicy[]
classMessagingLocks ClassMessagingLock[]
schoolYears SchoolYear[]
classGroups ClassGroup[]
students Student[]
@@ -126,19 +123,12 @@ model School {
complianceStatus SchoolComplianceStatus?
deletionFlags DeletionFlag[]
// Module B signage relations
emergencySignages EmergencySignage[]
signageMessages SignageMessage[]
signageSchedules SignageSchedule[]
signageAuditLogs SignageAuditLog[]
// Module F exam mode relations
examSessions ExamSession[]
// Module H notifications relations
notificationHubs NotificationHub[]
notificationArchives NotificationArchive[]
// Module J widgets relations
dashboardWidgets DashboardWidget[]
dashboardLayouts DashboardLayout[]
widgetTemplates WidgetTemplate[]
}
model User {
@@ -240,15 +230,10 @@ model User {
complianceConsultationsAcknowledged ComplianceConsultation[] @relation("ComplianceConsultationAcknowledger")
deletionFlagsApproved DeletionFlag[] @relation("DeletionFlagApprover")
// Module B signage relations
signageMessagesCreated SignageMessage[]
// Module H notifications relations
notificationHubs NotificationHub[]
notificationArchives NotificationArchive[]
// Module J widgets relations
dashboardWidgets DashboardWidget[]
dashboardLayouts DashboardLayout[]
escalationPoliciesOverridden EscalationPolicy[] @relation("EscalationOverriddenBy")
classMessagingLocksLocked ClassMessagingLock[] @relation("ClassMessagingLockLockedBy")
passwordResetTokens PasswordResetToken[]
twoFactorRecoveryCodes TwoFactorRecoveryCode[]
}
@@ -338,7 +323,6 @@ model ClassGroup {
examPlans ExamPlan[]
seatingCharts SeatingChart[]
substitutionAssignments SubstitutionAssignment[]
classMessagingLocks ClassMessagingLock[]
}
model ClassGroupTeacher {
@@ -3439,99 +3423,6 @@ model DeletionFlag {
// ─── Module B: Emergency Signage System ─────────────────────────────
model EmergencySignage {
id String @id @default(cuid())
schoolId String
displayName String // Room name or location (e.g., "Main Hallway", "Cafeteria TV 1")
signageType String @default("digital_display") // digital_display, led_board, tv_monitor
resolution String @default("1920x1080") // resolution info
location String // Physical location in school
isActive Boolean @default(true)
currentMessageId String? // Current active message
brightness Int @default(100) // 1-100
volume Int @default(50) // 1-100 for audio
ipAddress String? // For network monitoring
lastHeartbeat DateTime? // Last connection check
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
school School @relation(fields: [schoolId], references: [id])
messages SignageMessage[]
schedules SignageSchedule[]
@@index([schoolId])
@@index([isActive])
@@map("emergency_signages")
}
model SignageMessage {
id String @id @default(cuid())
schoolId String
signageId String
title String
content String // HTML or plain text
messageType String // emergency, notification, schedule, announcement, alert
priority String @default("normal") // low, normal, high, critical
backgroundColor String? // Hex color
textColor String? // Hex color
displayDuration Int @default(10) // seconds to display
soundAlert Boolean @default(false) // Play sound on emergency
soundFile String? // URL to audio file
createdBy String // userId who created
createdAt DateTime @default(now())
startTime DateTime?
endTime DateTime?
displayOrder Int @default(0)
school School @relation(fields: [schoolId], references: [id])
signage EmergencySignage @relation(fields: [signageId], references: [id], onDelete: Cascade)
creator User @relation(fields: [createdBy], references: [id])
audits SignageAuditLog[]
@@index([schoolId])
@@index([signageId])
@@index([messageType])
@@index([priority])
@@map("signage_messages")
}
model SignageSchedule {
id String @id @default(cuid())
schoolId String
signageId String
messageId String? // Optional: specific message to display
dayOfWeek Int // 0-6 (Sunday-Saturday)
startTime String // HH:mm format
endTime String // HH:mm format
isRecurring Boolean @default(true)
createdBy String // userId
createdAt DateTime @default(now())
school School @relation(fields: [schoolId], references: [id])
signage EmergencySignage @relation(fields: [signageId], references: [id], onDelete: Cascade)
@@index([schoolId])
@@index([signageId])
@@map("signage_schedules")
}
model SignageAuditLog {
id String @id @default(cuid())
schoolId String
messageId String
action String // created, updated, displayed, error, offline
details String? // JSON: { status, device, error, etc }
createdAt DateTime @default(now())
school School @relation(fields: [schoolId], references: [id])
message SignageMessage @relation(fields: [messageId], references: [id], onDelete: Cascade)
@@index([schoolId])
@@index([messageId])
@@index([action])
@@map("signage_audit_logs")
}
// ─── Module F: Exam Mode / Digital Test Environment ──────────────────
model ExamSession {
@@ -3618,55 +3509,6 @@ model ExamWarning {
// ─── Module H: Centralized Notifications Hub ───────────────────────
model NotificationHub {
id String @id @default(cuid())
schoolId String
userId String
category String // assessment, behavior, communication, wellness, system, announcement
priority String @default("normal") // low, normal, high, critical
title String
message String
actionUrl String? // Link to related resource
actionLabel String? // e.g. "View Grade", "Respond"
isRead Boolean @default(false)
readAt DateTime?
isDismissed Boolean @default(false)
dismissedAt DateTime?
sourceType String? // assessment, incident, message, announcement, etc
sourceId String? // ID of related entity
createdAt DateTime @default(now())
expiresAt DateTime? // Auto-archive if set
school School @relation(fields: [schoolId], references: [id])
user User @relation(fields: [userId], references: [id])
@@index([schoolId])
@@index([userId])
@@index([isRead])
@@index([category])
@@index([createdAt])
@@map("notification_hubs")
}
model NotificationArchive {
id String @id @default(cuid())
schoolId String
userId String
originalId String? // reference to NotificationHub.id if archived
title String
message String
category String
archivedAt DateTime @default(now())
school School @relation(fields: [schoolId], references: [id])
user User @relation(fields: [userId], references: [id])
@@index([schoolId])
@@index([userId])
@@index([archivedAt])
@@map("notification_archives")
}
// ─── Module J: Customizable Dashboard Widgets ──────────────────────
model DashboardWidget {
@@ -3716,76 +3558,3 @@ model DashboardLayout {
@@map("dashboard_layouts")
}
model WidgetTemplate {
id String @id @default(cuid())
schoolId String
widgetType String // Same types as DashboardWidget
name String
description String?
defaultConfig String // JSON: default configuration
thumbnail String? // URL to preview image
createdAt DateTime @default(now())
school School @relation(fields: [schoolId], references: [id])
@@unique([schoolId, widgetType])
@@index([schoolId])
@@map("widget_templates")
}
model SchoolPolicy {
id String @id @default(cuid())
schoolId String
policyType String // ESCALATION, CLASS_LOCKING, etc.
policyData String // JSON: policy configuration
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
school School @relation(fields: [schoolId], references: [id])
@@index([schoolId])
@@map("school_policies")
}
model EscalationPolicy {
id String @id @default(cuid())
schoolId String
fromRole String // PARENT, TEACHER, ADMIN, etc.
toRole String // ADMIN, TEACHER, etc.
requiredPriorContactRole String // TEACHER, etc.
waitingPeriodBusinessDays Int @default(3)
isActive Boolean @default(true)
overriddenByUserId String? // nullable, admin-configured exceptions
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
school School @relation(fields: [schoolId], references: [id])
overriddenByUser User? @relation("EscalationOverriddenBy", fields: [overriddenByUserId], references: [id])
@@index([schoolId])
@@index([fromRole, toRole])
@@map("escalation_policies")
}
model ClassMessagingLock {
id String @id @default(cuid())
classGroupId String
schoolId String
lockedByUserId String // teacher who locked
lockedFrom DateTime
lockedUntil DateTime? // nullable = "until class ends"
reason String? // optional reason for lock
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
classGroup ClassGroup @relation(fields: [classGroupId], references: [id])
school School @relation(fields: [schoolId], references: [id])
lockedByUser User @relation("ClassMessagingLockLockedBy", fields: [lockedByUserId], references: [id])
@@index([classGroupId])
@@index([schoolId])
@@index([lockedByUserId])
@@index([lockedFrom, lockedUntil])
@@map("class_messaging_locks")
}