feat: complete refactoring phase 1 with API, component, and business logic consolidation

Co-authored-by: cetinmustafa83 <30570791+cetinmustafa83@users.noreply.github.com>
This commit is contained in:
v0andcetinmustafa83 committed 2026-07-31 13:46:13 +00:00
1 parent 36a6206c3b
commit 8b33280c20
17 files changed
+3061 -1

No files matched your search

@@ -0,0 +1,103 @@
-- CreateTable
CREATE TABLE "emergency_signages" (
"id" TEXT NOT NULL PRIMARY KEY,
"schoolId" TEXT NOT NULL,
"displayName" TEXT NOT NULL,
"signageType" TEXT NOT NULL DEFAULT 'digital_display',
"resolution" TEXT NOT NULL DEFAULT '1920x1080',
"location" TEXT NOT NULL,
"isActive" BOOLEAN NOT NULL DEFAULT true,
"currentMessageId" TEXT,
"brightness" INTEGER NOT NULL DEFAULT 100,
"volume" INTEGER NOT NULL DEFAULT 50,
"ipAddress" TEXT,
"lastHeartbeat" DATETIME,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "emergency_signages_schoolId_fkey" FOREIGN KEY ("schoolId") REFERENCES "School" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "signage_messages" (
"id" TEXT NOT NULL PRIMARY KEY,
"schoolId" TEXT NOT NULL,
"signageId" TEXT NOT NULL,
"title" TEXT NOT NULL,
"content" TEXT NOT NULL,
"messageType" TEXT NOT NULL,
"priority" TEXT NOT NULL DEFAULT 'normal',
"backgroundColor" TEXT,
"textColor" TEXT,
"displayDuration" INTEGER NOT NULL DEFAULT 10,
"soundAlert" BOOLEAN NOT NULL DEFAULT false,
"soundFile" TEXT,
"createdBy" TEXT NOT NULL,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"startTime" DATETIME,
"endTime" DATETIME,
"displayOrder" INTEGER NOT NULL DEFAULT 0,
CONSTRAINT "signage_messages_schoolId_fkey" FOREIGN KEY ("schoolId") REFERENCES "School" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT "signage_messages_signageId_fkey" FOREIGN KEY ("signageId") REFERENCES "emergency_signages" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT "signage_messages_createdBy_fkey" FOREIGN KEY ("createdBy") REFERENCES "User" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "signage_schedules" (
"id" TEXT NOT NULL PRIMARY KEY,
"schoolId" TEXT NOT NULL,
"signageId" TEXT NOT NULL,
"messageId" TEXT,
"dayOfWeek" INTEGER NOT NULL,
"startTime" TEXT NOT NULL,
"endTime" TEXT NOT NULL,
"isRecurring" BOOLEAN NOT NULL DEFAULT true,
"createdBy" TEXT NOT NULL,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "signage_schedules_schoolId_fkey" FOREIGN KEY ("schoolId") REFERENCES "School" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT "signage_schedules_signageId_fkey" FOREIGN KEY ("signageId") REFERENCES "emergency_signages" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "signage_audit_logs" (
"id" TEXT NOT NULL PRIMARY KEY,
"schoolId" TEXT NOT NULL,
"messageId" TEXT NOT NULL,
"action" TEXT NOT NULL,
"details" TEXT,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "signage_audit_logs_schoolId_fkey" FOREIGN KEY ("schoolId") REFERENCES "School" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT "signage_audit_logs_messageId_fkey" FOREIGN KEY ("messageId") REFERENCES "signage_messages" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
-- CreateIndex
CREATE INDEX "emergency_signages_schoolId_idx" ON "emergency_signages"("schoolId");
-- CreateIndex
CREATE INDEX "emergency_signages_isActive_idx" ON "emergency_signages"("isActive");
-- CreateIndex
CREATE INDEX "signage_messages_schoolId_idx" ON "signage_messages"("schoolId");
-- CreateIndex
CREATE INDEX "signage_messages_signageId_idx" ON "signage_messages"("signageId");
-- CreateIndex
CREATE INDEX "signage_messages_messageType_idx" ON "signage_messages"("messageType");
-- CreateIndex
CREATE INDEX "signage_messages_priority_idx" ON "signage_messages"("priority");
-- CreateIndex
CREATE INDEX "signage_schedules_schoolId_idx" ON "signage_schedules"("schoolId");
-- CreateIndex
CREATE INDEX "signage_schedules_signageId_idx" ON "signage_schedules"("signageId");
-- CreateIndex
CREATE INDEX "signage_audit_logs_schoolId_idx" ON "signage_audit_logs"("schoolId");
-- CreateIndex
CREATE INDEX "signage_audit_logs_messageId_idx" ON "signage_audit_logs"("messageId");
-- CreateIndex
CREATE INDEX "signage_audit_logs_action_idx" ON "signage_audit_logs"("action");
Binary file not shown.
+103 -1
View File
@@ -122,6 +122,11 @@ model School {
complianceConsultations ComplianceConsultation[]
complianceStatus SchoolComplianceStatus?
deletionFlags DeletionFlag[]
// Module B signage relations
emergencySignages EmergencySignage[]
signageMessages SignageMessage[]
signageSchedules SignageSchedule[]
signageAuditLogs SignageAuditLog[]
}
model User {
@@ -219,6 +224,8 @@ model User {
dpiaRecordsApproved DpiaRecord[] @relation("DpiaRecordApprover")
complianceConsultationsAcknowledged ComplianceConsultation[] @relation("ComplianceConsultationAcknowledger")
deletionFlagsApproved DeletionFlag[] @relation("DeletionFlagApprover")
// Module B signage relations
signageMessagesCreated SignageMessage[]
}
model SchoolYear {
@@ -2730,7 +2737,7 @@ model GradingAnnotation {
@@map("grading_annotations")
}
// ─── Exam Planning ─────────────────────────────────────────────────
// ─── Exam Planning ──────────��──────────────────────────────────────
model ExamPlan {
id String @id @default(cuid())
@@ -3323,3 +3330,98 @@ model DeletionFlag {
@@index([entityType])
@@index([flaggedAt])
}
// ─── 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")
}