🎉 Complete AI-Enhanced University Portal - Ready for Production

 Major Features Added:
- AI Chat with conversation memory and university-specific knowledge base
- Multi-tenant university support with white-label capabilities
- Professional admin interface for knowledge base management
- Advanced database schema with Prisma ORM
- Comprehensive documentation and guides
- Modern Next.js 15 + React 19 architecture
- Bilingual support (English/Arabic)
- Role-based access control
- Real-time chat interface with loading states

🔧 Technical Improvements:
- Fixed all linter errors and TypeScript issues
- Cleaned up codebase and removed legacy files
- Added comprehensive .gitignore
- Updated README with detailed setup instructions
- Optimized database schema and migrations
- Enhanced error handling and user experience

📚 Documentation:
- AI Conversation Memory Guide
- AI Enhancement Summary
- Developer Guide
- User Guide
- Complete setup and deployment instructions

🚀 Ready for GitHub deployment and production use!
This commit is contained in:
Krikorios
2025-07-20 08:26:25 +04:00
parent 868c9b252c
commit aa459f4bd6
159 changed files with 25019 additions and 16607 deletions
BIN
View File
Binary file not shown.
@@ -0,0 +1,171 @@
-- CreateTable
CREATE TABLE "universities" (
"id" TEXT NOT NULL PRIMARY KEY,
"slug" TEXT NOT NULL,
"name" TEXT NOT NULL,
"shortName" TEXT,
"domain" TEXT,
"subdomain" TEXT,
"branding" JSONB NOT NULL,
"contact" JSONB NOT NULL,
"features" JSONB NOT NULL,
"ai" JSONB NOT NULL,
"status" TEXT NOT NULL DEFAULT 'SETUP',
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL
);
-- CreateTable
CREATE TABLE "academic_programs" (
"id" TEXT NOT NULL PRIMARY KEY,
"universityId" TEXT NOT NULL,
"title" TEXT NOT NULL,
"titleAr" TEXT,
"description" TEXT,
"descriptionAr" TEXT,
"level" TEXT NOT NULL,
"duration" TEXT,
"fees" TEXT,
"entryRequirements" TEXT,
"campusLocations" JSONB,
"isActive" BOOLEAN NOT NULL DEFAULT true,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "academic_programs_universityId_fkey" FOREIGN KEY ("universityId") REFERENCES "universities" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "university_content" (
"id" TEXT NOT NULL PRIMARY KEY,
"universityId" TEXT NOT NULL,
"contentType" TEXT NOT NULL,
"title" TEXT NOT NULL,
"titleAr" TEXT,
"content" TEXT,
"contentAr" TEXT,
"metadata" JSONB,
"isPublished" BOOLEAN NOT NULL DEFAULT false,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "university_content_universityId_fkey" FOREIGN KEY ("universityId") REFERENCES "universities" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "ai_knowledge_base" (
"id" TEXT NOT NULL PRIMARY KEY,
"universityId" TEXT NOT NULL,
"category" TEXT,
"question" TEXT NOT NULL,
"questionAr" TEXT,
"answer" TEXT NOT NULL,
"answerAr" TEXT,
"priority" INTEGER NOT NULL DEFAULT 1,
"isActive" BOOLEAN NOT NULL DEFAULT true,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "ai_knowledge_base_universityId_fkey" FOREIGN KEY ("universityId") REFERENCES "universities" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "users" (
"id" TEXT NOT NULL PRIMARY KEY,
"universityId" TEXT,
"email" TEXT NOT NULL,
"name" TEXT NOT NULL,
"role" TEXT NOT NULL DEFAULT 'STUDENT',
"year" INTEGER,
"faculty" TEXT,
"balance" REAL,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
"advisorId" TEXT,
CONSTRAINT "users_universityId_fkey" FOREIGN KEY ("universityId") REFERENCES "universities" ("id") ON DELETE SET NULL ON UPDATE CASCADE,
CONSTRAINT "users_advisorId_fkey" FOREIGN KEY ("advisorId") REFERENCES "users" ("id") ON DELETE SET NULL ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "courses" (
"id" TEXT NOT NULL PRIMARY KEY,
"universityId" TEXT,
"code" TEXT NOT NULL,
"name" TEXT NOT NULL,
"description" TEXT,
"credits" INTEGER NOT NULL,
"semester" TEXT NOT NULL,
"schedule" TEXT,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "courses_universityId_fkey" FOREIGN KEY ("universityId") REFERENCES "universities" ("id") ON DELETE SET NULL ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "faqs" (
"id" TEXT NOT NULL PRIMARY KEY,
"universityId" TEXT,
"question" TEXT NOT NULL,
"answer" TEXT NOT NULL,
"category" TEXT NOT NULL,
"language" TEXT NOT NULL DEFAULT 'en',
"priority" INTEGER NOT NULL DEFAULT 1,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "faqs_universityId_fkey" FOREIGN KEY ("universityId") REFERENCES "universities" ("id") ON DELETE SET NULL ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "enrollments" (
"id" TEXT NOT NULL PRIMARY KEY,
"userId" TEXT NOT NULL,
"courseId" TEXT NOT NULL,
"grade" TEXT,
"status" TEXT NOT NULL DEFAULT 'ENROLLED',
CONSTRAINT "enrollments_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT "enrollments_courseId_fkey" FOREIGN KEY ("courseId") REFERENCES "courses" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "chat_sessions" (
"id" TEXT NOT NULL PRIMARY KEY,
"userId" TEXT,
"type" TEXT NOT NULL DEFAULT 'GENERAL',
"messages" JSONB NOT NULL,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "chat_sessions_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users" ("id") ON DELETE SET NULL ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "surveys" (
"id" TEXT NOT NULL PRIMARY KEY,
"userId" TEXT,
"type" TEXT NOT NULL,
"rating" INTEGER NOT NULL,
"feedback" TEXT,
"sessionId" TEXT,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "surveys_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users" ("id") ON DELETE SET NULL ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "accessibility_audits" (
"id" TEXT NOT NULL PRIMARY KEY,
"url" TEXT NOT NULL,
"imagePath" TEXT,
"altText" TEXT,
"wcagScore" REAL,
"issues" JSONB,
"suggestions" JSONB,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);
-- CreateIndex
CREATE UNIQUE INDEX "universities_slug_key" ON "universities"("slug");
-- CreateIndex
CREATE UNIQUE INDEX "users_email_key" ON "users"("email");
-- CreateIndex
CREATE UNIQUE INDEX "courses_code_key" ON "courses"("code");
-- CreateIndex
CREATE UNIQUE INDEX "enrollments_userId_courseId_key" ON "enrollments"("userId", "courseId");
@@ -0,0 +1,19 @@
-- CreateTable
CREATE TABLE "assets" (
"id" TEXT NOT NULL PRIMARY KEY,
"universityId" TEXT NOT NULL,
"type" TEXT NOT NULL,
"filename" TEXT NOT NULL,
"originalName" TEXT NOT NULL,
"mimeType" TEXT NOT NULL,
"size" INTEGER NOT NULL,
"path" TEXT NOT NULL,
"url" TEXT NOT NULL,
"altText" TEXT,
"altTextAr" TEXT,
"metadata" JSONB,
"isPublic" BOOLEAN NOT NULL DEFAULT true,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "assets_universityId_fkey" FOREIGN KEY ("universityId") REFERENCES "universities" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
@@ -0,0 +1,155 @@
-- CreateTable
CREATE TABLE "domain_configs" (
"id" TEXT NOT NULL PRIMARY KEY,
"universityId" TEXT NOT NULL,
"type" TEXT NOT NULL,
"domain" TEXT NOT NULL,
"subdomain" TEXT,
"sslStatus" TEXT NOT NULL DEFAULT 'PENDING',
"sslExpiryDate" DATETIME,
"dnsStatus" TEXT NOT NULL DEFAULT 'PENDING',
"isActive" BOOLEAN NOT NULL DEFAULT false,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "domain_configs_universityId_fkey" FOREIGN KEY ("universityId") REFERENCES "universities" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "ssl_configs" (
"id" TEXT NOT NULL PRIMARY KEY,
"domainId" TEXT NOT NULL,
"provider" TEXT NOT NULL,
"certificatePath" TEXT,
"privateKeyPath" TEXT,
"autoRenewal" BOOLEAN NOT NULL DEFAULT true,
"renewalThreshold" INTEGER NOT NULL DEFAULT 30,
"lastRenewalDate" DATETIME,
"nextRenewalDate" DATETIME,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "ssl_configs_domainId_fkey" FOREIGN KEY ("domainId") REFERENCES "domain_configs" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "dns_configs" (
"id" TEXT NOT NULL PRIMARY KEY,
"domainId" TEXT NOT NULL,
"provider" TEXT NOT NULL,
"apiKey" TEXT,
"zoneId" TEXT,
"recordType" TEXT NOT NULL,
"recordValue" TEXT NOT NULL,
"ttl" INTEGER NOT NULL DEFAULT 300,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "dns_configs_domainId_fkey" FOREIGN KEY ("domainId") REFERENCES "domain_configs" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "domain_analytics" (
"id" TEXT NOT NULL PRIMARY KEY,
"domainId" TEXT NOT NULL,
"uptime" REAL NOT NULL,
"responseTime" INTEGER NOT NULL,
"sslStatus" TEXT NOT NULL,
"dnsStatus" TEXT NOT NULL,
"checkedAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "domain_analytics_domainId_fkey" FOREIGN KEY ("domainId") REFERENCES "domain_configs" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "deployment_configs" (
"id" TEXT NOT NULL PRIMARY KEY,
"universityId" TEXT NOT NULL,
"environment" TEXT NOT NULL,
"version" TEXT NOT NULL,
"status" TEXT NOT NULL DEFAULT 'PENDING',
"deploymentType" TEXT NOT NULL DEFAULT 'FULL',
"startTime" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"endTime" DATETIME,
"logs" JSONB NOT NULL,
"metadata" JSONB NOT NULL,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "deployment_configs_universityId_fkey" FOREIGN KEY ("universityId") REFERENCES "universities" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "environment_configs" (
"id" TEXT NOT NULL PRIMARY KEY,
"name" TEXT NOT NULL,
"type" TEXT NOT NULL,
"domain" TEXT NOT NULL,
"databaseUrl" TEXT NOT NULL,
"apiKeys" JSONB NOT NULL,
"features" JSONB NOT NULL,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL
);
-- CreateTable
CREATE TABLE "cdn_configs" (
"id" TEXT NOT NULL PRIMARY KEY,
"universityId" TEXT NOT NULL,
"provider" TEXT NOT NULL,
"bucketName" TEXT,
"region" TEXT,
"accessKey" TEXT,
"secretKey" TEXT,
"domain" TEXT NOT NULL,
"isActive" BOOLEAN NOT NULL DEFAULT false,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "cdn_configs_universityId_fkey" FOREIGN KEY ("universityId") REFERENCES "universities" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "cdn_assets" (
"id" TEXT NOT NULL PRIMARY KEY,
"universityId" TEXT NOT NULL,
"originalPath" TEXT NOT NULL,
"cdnUrl" TEXT NOT NULL,
"optimizedUrls" JSONB NOT NULL,
"metadata" JSONB NOT NULL,
"uploadedAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "cdn_assets_universityId_fkey" FOREIGN KEY ("universityId") REFERENCES "universities" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT "cdn_assets_universityId_fkey" FOREIGN KEY ("universityId") REFERENCES "cdn_configs" ("universityId") ON DELETE RESTRICT ON UPDATE CASCADE
);
-- RedefineTables
PRAGMA defer_foreign_keys=ON;
PRAGMA foreign_keys=OFF;
CREATE TABLE "new_universities" (
"id" TEXT NOT NULL PRIMARY KEY,
"slug" TEXT NOT NULL,
"name" TEXT NOT NULL,
"shortName" TEXT,
"domain" TEXT,
"subdomain" TEXT,
"branding" JSONB NOT NULL,
"contact" JSONB NOT NULL,
"features" JSONB NOT NULL,
"ai" JSONB NOT NULL,
"isMultiBranch" BOOLEAN NOT NULL DEFAULT false,
"parentUniversityId" TEXT,
"branchType" TEXT,
"status" TEXT NOT NULL DEFAULT 'SETUP',
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "universities_parentUniversityId_fkey" FOREIGN KEY ("parentUniversityId") REFERENCES "universities" ("id") ON DELETE SET NULL ON UPDATE CASCADE
);
INSERT INTO "new_universities" ("ai", "branding", "contact", "createdAt", "domain", "features", "id", "name", "shortName", "slug", "status", "subdomain", "updatedAt") SELECT "ai", "branding", "contact", "createdAt", "domain", "features", "id", "name", "shortName", "slug", "status", "subdomain", "updatedAt" FROM "universities";
DROP TABLE "universities";
ALTER TABLE "new_universities" RENAME TO "universities";
CREATE UNIQUE INDEX "universities_slug_key" ON "universities"("slug");
PRAGMA foreign_keys=ON;
PRAGMA defer_foreign_keys=OFF;
-- CreateIndex
CREATE UNIQUE INDEX "ssl_configs_domainId_key" ON "ssl_configs"("domainId");
-- CreateIndex
CREATE UNIQUE INDEX "dns_configs_domainId_key" ON "dns_configs"("domainId");
-- CreateIndex
CREATE UNIQUE INDEX "cdn_configs_universityId_key" ON "cdn_configs"("universityId");
@@ -0,0 +1,89 @@
/*
Warnings:
- Added the required column `password` to the `users` table without a default value. This is not possible if the table is not empty.
*/
-- CreateTable
CREATE TABLE "user_sessions" (
"id" TEXT NOT NULL PRIMARY KEY,
"userId" TEXT NOT NULL,
"token" TEXT NOT NULL,
"expiresAt" DATETIME NOT NULL,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "user_sessions_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
-- RedefineTables
PRAGMA defer_foreign_keys=ON;
PRAGMA foreign_keys=OFF;
CREATE TABLE "new_academic_programs" (
"id" TEXT NOT NULL PRIMARY KEY,
"universityId" TEXT NOT NULL,
"title" TEXT NOT NULL,
"titleAr" TEXT,
"description" TEXT,
"descriptionAr" TEXT,
"level" TEXT NOT NULL,
"duration" TEXT,
"fees" TEXT,
"entryRequirements" TEXT,
"campusLocations" JSONB,
"totalCredits" INTEGER NOT NULL DEFAULT 120,
"isActive" BOOLEAN NOT NULL DEFAULT true,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "academic_programs_universityId_fkey" FOREIGN KEY ("universityId") REFERENCES "universities" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
INSERT INTO "new_academic_programs" ("campusLocations", "createdAt", "description", "descriptionAr", "duration", "entryRequirements", "fees", "id", "isActive", "level", "title", "titleAr", "universityId", "updatedAt") SELECT "campusLocations", "createdAt", "description", "descriptionAr", "duration", "entryRequirements", "fees", "id", "isActive", "level", "title", "titleAr", "universityId", "updatedAt" FROM "academic_programs";
DROP TABLE "academic_programs";
ALTER TABLE "new_academic_programs" RENAME TO "academic_programs";
CREATE TABLE "new_courses" (
"id" TEXT NOT NULL PRIMARY KEY,
"universityId" TEXT,
"programId" TEXT,
"code" TEXT NOT NULL,
"name" TEXT NOT NULL,
"description" TEXT,
"credits" INTEGER NOT NULL,
"semester" TEXT NOT NULL,
"schedule" TEXT,
"prerequisites" TEXT,
"isRequired" BOOLEAN NOT NULL DEFAULT true,
"isActive" BOOLEAN NOT NULL DEFAULT true,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "courses_universityId_fkey" FOREIGN KEY ("universityId") REFERENCES "universities" ("id") ON DELETE SET NULL ON UPDATE CASCADE,
CONSTRAINT "courses_programId_fkey" FOREIGN KEY ("programId") REFERENCES "academic_programs" ("id") ON DELETE SET NULL ON UPDATE CASCADE
);
INSERT INTO "new_courses" ("code", "createdAt", "credits", "description", "id", "name", "schedule", "semester", "universityId", "updatedAt") SELECT "code", "createdAt", "credits", "description", "id", "name", "schedule", "semester", "universityId", "updatedAt" FROM "courses";
DROP TABLE "courses";
ALTER TABLE "new_courses" RENAME TO "courses";
CREATE UNIQUE INDEX "courses_code_key" ON "courses"("code");
CREATE TABLE "new_users" (
"id" TEXT NOT NULL PRIMARY KEY,
"universityId" TEXT,
"email" TEXT NOT NULL,
"name" TEXT NOT NULL,
"password" TEXT NOT NULL,
"role" TEXT NOT NULL DEFAULT 'STUDENT',
"year" INTEGER,
"faculty" TEXT,
"balance" REAL,
"isActive" BOOLEAN NOT NULL DEFAULT true,
"lastLogin" DATETIME,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
"advisorId" TEXT,
CONSTRAINT "users_universityId_fkey" FOREIGN KEY ("universityId") REFERENCES "universities" ("id") ON DELETE SET NULL ON UPDATE CASCADE,
CONSTRAINT "users_advisorId_fkey" FOREIGN KEY ("advisorId") REFERENCES "users" ("id") ON DELETE SET NULL ON UPDATE CASCADE
);
INSERT INTO "new_users" ("advisorId", "balance", "createdAt", "email", "faculty", "id", "name", "role", "universityId", "updatedAt", "year") SELECT "advisorId", "balance", "createdAt", "email", "faculty", "id", "name", "role", "universityId", "updatedAt", "year" FROM "users";
DROP TABLE "users";
ALTER TABLE "new_users" RENAME TO "users";
CREATE UNIQUE INDEX "users_email_key" ON "users"("email");
PRAGMA foreign_keys=ON;
PRAGMA defer_foreign_keys=OFF;
-- CreateIndex
CREATE UNIQUE INDEX "user_sessions_token_key" ON "user_sessions"("token");
@@ -0,0 +1,34 @@
/*
Warnings:
- You are about to drop the column `messages` on the `chat_sessions` table. All the data in the column will be lost.
*/
-- CreateTable
CREATE TABLE "chat_messages" (
"id" TEXT NOT NULL PRIMARY KEY,
"conversationId" TEXT NOT NULL,
"role" TEXT NOT NULL,
"content" TEXT NOT NULL,
"universitySlug" TEXT,
"userContext" TEXT,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "chat_messages_conversationId_fkey" FOREIGN KEY ("conversationId") REFERENCES "chat_sessions" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
-- RedefineTables
PRAGMA defer_foreign_keys=ON;
PRAGMA foreign_keys=OFF;
CREATE TABLE "new_chat_sessions" (
"id" TEXT NOT NULL PRIMARY KEY,
"userId" TEXT,
"type" TEXT NOT NULL DEFAULT 'GENERAL',
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "chat_sessions_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users" ("id") ON DELETE SET NULL ON UPDATE CASCADE
);
INSERT INTO "new_chat_sessions" ("createdAt", "id", "type", "updatedAt", "userId") SELECT "createdAt", "id", "type", "updatedAt", "userId" FROM "chat_sessions";
DROP TABLE "chat_sessions";
ALTER TABLE "new_chat_sessions" RENAME TO "chat_sessions";
PRAGMA foreign_keys=ON;
PRAGMA defer_foreign_keys=OFF;
+3
View File
@@ -0,0 +1,3 @@
# Please do not edit this file manually
# It should be added in your version-control system (e.g., Git)
provider = "sqlite"
+479 -34
View File
@@ -7,45 +7,201 @@ datasource db {
url = "file:./dev.db"
}
model User {
// Multi-tenant University Configuration
model University {
id String @id @default(uuid())
email String @unique
slug String @unique
name String
role Role @default(STUDENT)
year Int?
faculty String?
balance Float?
shortName String?
domain String?
subdomain String?
// Configuration as JSON
branding Json // Branding configuration
contact Json // Contact information
features Json // Feature flags
ai Json // AI configuration
// Branch/Campus Management
isMultiBranch Boolean @default(false) // Whether this university has multiple branches
parentUniversityId String? // For branches, reference to parent university
branchType BranchType? // Type of branch (MAIN, CAMPUS, CENTER, etc.)
status UniversityStatus @default(SETUP)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// Relationships
enrollments Enrollment[]
surveys Survey[]
chatSessions ChatSession[]
advisorId String?
advisor User? @relation("AdvisorStudent", fields: [advisorId], references: [id])
students User[] @relation("AdvisorStudent")
users User[]
programs AcademicProgram[]
content UniversityContent[]
knowledgeBase AIKnowledgeBase[]
courses Course[]
faqs FAQ[]
assets Asset[]
domains DomainConfig[]
deployments DeploymentConfig[]
cdnConfig CDNConfig?
cdnAssets CDNAsset[]
// Branch relationships
parentUniversity University? @relation("UniversityBranches", fields: [parentUniversityId], references: [id])
branches University[] @relation("UniversityBranches")
@@map("users")
@@map("universities")
}
model Course {
// Academic Programs (Majors) - University-specific
model AcademicProgram {
id String @id @default(uuid())
code String @unique
name String
universityId String
title String
titleAr String?
description String?
credits Int
semester String
schedule String?
descriptionAr String?
level ProgramLevel
duration String?
fees String?
entryRequirements String?
campusLocations Json?
totalCredits Int @default(120)
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// Relationships
enrollments Enrollment[]
university University @relation(fields: [universityId], references: [id], onDelete: Cascade)
courses Course[]
@@map("academic_programs")
}
// University Content (Dynamic content)
model UniversityContent {
id String @id @default(uuid())
universityId String
contentType ContentType
title String
titleAr String?
content String?
contentAr String?
metadata Json?
isPublished Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// Relationships
university University @relation(fields: [universityId], references: [id], onDelete: Cascade)
@@map("university_content")
}
// AI Knowledge Base (University-specific)
model AIKnowledgeBase {
id String @id @default(uuid())
universityId String
category String?
question String
questionAr String?
answer String
answerAr String?
priority Int @default(1)
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// Relationships
university University @relation(fields: [universityId], references: [id], onDelete: Cascade)
@@map("ai_knowledge_base")
}
// Updated User model with university relationship and authentication
model User {
id String @id @default(uuid())
universityId String?
email String @unique
name String
password String // Hashed password
role Role @default(STUDENT)
year Int?
faculty String?
balance Float?
isActive Boolean @default(true)
lastLogin DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// Relationships
university University? @relation(fields: [universityId], references: [id])
enrollments Enrollment[]
surveys Survey[]
chatSessions ChatSession[]
advisorId String?
advisor User? @relation("AdvisorStudent", fields: [advisorId], references: [id])
students User[] @relation("AdvisorStudent")
sessions UserSession[]
@@map("users")
}
// User Session for authentication
model UserSession {
id String @id @default(uuid())
userId String
token String @unique
expiresAt DateTime
createdAt DateTime @default(now())
// Relationships
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@map("user_sessions")
}
// Updated Course model with university and program relationship
model Course {
id String @id @default(uuid())
universityId String?
programId String?
code String @unique
name String
description String?
credits Int
semester String
schedule String?
prerequisites String?
isRequired Boolean @default(true)
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// Relationships
university University? @relation(fields: [universityId], references: [id])
program AcademicProgram? @relation(fields: [programId], references: [id])
enrollments Enrollment[]
@@map("courses")
}
// Updated FAQ model with university relationship
model FAQ {
id String @id @default(uuid())
universityId String?
question String
answer String
category String
language String @default("en")
priority Int @default(1)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// Relationships
university University? @relation(fields: [universityId], references: [id])
@@map("faqs")
}
model Enrollment {
id String @id @default(uuid())
userId String
@@ -61,33 +217,36 @@ model Enrollment {
@@map("enrollments")
}
model FAQ {
id String @id @default(uuid())
question String
answer String
category String
language String @default("en")
priority Int @default(1)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@map("faqs")
}
model ChatSession {
id String @id @default(uuid())
userId String?
type ChatType @default(GENERAL)
messages Json
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// Relationships
user User? @relation(fields: [userId], references: [id])
messages ChatMessage[]
@@map("chat_sessions")
}
// Chat Message for conversation memory
model ChatMessage {
id String @id @default(uuid())
conversationId String
role String // 'user' | 'assistant' | 'system'
content String
universitySlug String?
userContext String? // JSON string of user context
createdAt DateTime @default(now())
// Relationships
session ChatSession @relation(fields: [conversationId], references: [id], onDelete: Cascade)
@@map("chat_messages")
}
model Survey {
id String @id @default(uuid())
userId String?
@@ -116,10 +275,34 @@ model AccessibilityAudit {
@@map("accessibility_audits")
}
// Enums
enum UniversityStatus {
SETUP
ACTIVE
INACTIVE
SUSPENDED
}
enum ProgramLevel {
UNDERGRADUATE
POSTGRADUATE
PHD
}
enum ContentType {
ABOUT
RANKINGS
RESEARCH
CAMPUS
NEWS
EVENTS
}
enum Role {
STUDENT
STAFF
ADMIN
SUPER_ADMIN
}
enum EnrollmentStatus {
@@ -135,3 +318,265 @@ enum ChatType {
ACADEMIC
TECHNICAL
}
// Asset model for university-specific assets
model Asset {
id String @id @default(uuid())
universityId String
type AssetType
filename String
originalName String
mimeType String
size Int
path String
url String
altText String?
altTextAr String?
metadata Json?
isPublic Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// Relationships
university University @relation(fields: [universityId], references: [id], onDelete: Cascade)
@@map("assets")
}
// Domain Configuration for multi-tenant domain management
model DomainConfig {
id String @id @default(uuid())
universityId String
type DomainType
domain String
subdomain String?
sslStatus SSLStatus @default(PENDING)
sslExpiryDate DateTime?
dnsStatus DNSStatus @default(PENDING)
isActive Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// Relationships
university University @relation(fields: [universityId], references: [id], onDelete: Cascade)
sslConfig SSLConfig?
dnsConfig DNSConfig?
analytics DomainAnalytics[]
@@map("domain_configs")
}
// SSL Configuration for domain certificates
model SSLConfig {
id String @id @default(uuid())
domainId String @unique
provider SSLProvider
certificatePath String?
privateKeyPath String?
autoRenewal Boolean @default(true)
renewalThreshold Int @default(30)
lastRenewalDate DateTime?
nextRenewalDate DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// Relationships
domainConfig DomainConfig @relation(fields: [domainId], references: [id], onDelete: Cascade)
@@map("ssl_configs")
}
// DNS Configuration for domain records
model DNSConfig {
id String @id @default(uuid())
domainId String @unique
provider DNSProvider
apiKey String?
zoneId String?
recordType DNSRecordType
recordValue String
ttl Int @default(300)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// Relationships
domainConfig DomainConfig @relation(fields: [domainId], references: [id], onDelete: Cascade)
@@map("dns_configs")
}
// Domain Analytics for monitoring
model DomainAnalytics {
id String @id @default(uuid())
domainId String
uptime Float
responseTime Int
sslStatus SSLStatus
dnsStatus DNSStatus
checkedAt DateTime @default(now())
// Relationships
domainConfig DomainConfig @relation(fields: [domainId], references: [id], onDelete: Cascade)
@@map("domain_analytics")
}
enum AssetType {
LOGO
FAVICON
HERO_IMAGE
NEWS_IMAGE
PROGRAM_IMAGE
GALLERY_IMAGE
DOCUMENT
VIDEO
AUDIO
}
enum DomainType {
SUBDOMAIN
CUSTOM_DOMAIN
}
enum SSLStatus {
PENDING
ACTIVE
EXPIRED
ERROR
}
enum DNSStatus {
PENDING
VERIFIED
ERROR
}
enum SSLProvider {
LETSENCRYPT
CLOUDFLARE
AWS
CUSTOM
}
enum DNSProvider {
CLOUDFLARE
AWS_ROUTE53
GOOGLE_CLOUD
CUSTOM
}
enum DNSRecordType {
A
CNAME
ALIAS
}
// Deployment Configuration for automation
model DeploymentConfig {
id String @id @default(uuid())
universityId String
environment DeploymentEnvironment
version String
status DeploymentStatus @default(PENDING)
deploymentType DeploymentType @default(FULL)
startTime DateTime @default(now())
endTime DateTime?
logs Json // Array of log messages
metadata Json // Additional deployment metadata
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// Relationships
university University @relation(fields: [universityId], references: [id], onDelete: Cascade)
@@map("deployment_configs")
}
// Environment Configuration for different deployment stages
model EnvironmentConfig {
id String @id @default(uuid())
name String
type DeploymentEnvironment
domain String
databaseUrl String
apiKeys Json // API keys for different services
features Json // Feature flags for the environment
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@map("environment_configs")
}
enum DeploymentEnvironment {
DEVELOPMENT
STAGING
PRODUCTION
}
enum DeploymentStatus {
PENDING
IN_PROGRESS
COMPLETED
FAILED
ROLLED_BACK
}
enum DeploymentType {
FULL
INCREMENTAL
ROLLBACK
}
// CDN Configuration for cloud storage
model CDNConfig {
id String @id @default(uuid())
universityId String @unique
provider CDNProvider
bucketName String?
region String?
accessKey String?
secretKey String?
domain String
isActive Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// Relationships
university University @relation(fields: [universityId], references: [id], onDelete: Cascade)
assets CDNAsset[]
@@map("cdn_configs")
}
// CDN Assets for optimized delivery
model CDNAsset {
id String @id @default(uuid())
universityId String
originalPath String
cdnUrl String
optimizedUrls Json // Record of optimized URLs
metadata Json // Asset metadata
uploadedAt DateTime @default(now())
// Relationships
university University @relation(fields: [universityId], references: [id], onDelete: Cascade)
cdnConfig CDNConfig? @relation(fields: [universityId], references: [universityId])
@@map("cdn_assets")
}
enum CDNProvider {
AWS_S3
CLOUDFLARE
CLOUDINARY
CUSTOM
}
enum BranchType {
MAIN
CAMPUS
CENTER
BRANCH
EXTENSION
PARTNER
}
+224 -446
View File
@@ -1,463 +1,241 @@
import { PrismaClient } from '@prisma/client'
import { PrismaClient } from '@prisma/client';
import { hashPassword } from '../src/lib/auth';
const prisma = new PrismaClient()
const prisma = new PrismaClient();
async function main() {
console.log('🌱 Starting comprehensive database seeding...')
// Clear existing data
await prisma.enrollment.deleteMany()
await prisma.fAQ.deleteMany()
await prisma.course.deleteMany()
await prisma.user.deleteMany()
// Create admin users
const admin = await prisma.user.create({
data: {
email: 'admin@university.edu',
name: 'Dr. Emily Chen',
console.log('🌱 Starting database seeding...');
// Create a test university
const university = await prisma.university.upsert({
where: { slug: 'test-university' },
update: {},
create: {
slug: 'test-university',
name: 'Test University',
shortName: 'TU',
domain: 'test-university.edu',
branding: {
primaryColor: '#3B82F6',
secondaryColor: '#1E40AF',
logo: '/logo.png'
},
contact: {
email: 'info@test-university.edu',
phone: '+1 (555) 123-4567',
address: '123 University Ave, City, State 12345'
},
features: {
aiChat: true,
multiLanguage: true,
cdn: false
},
ai: {
provider: 'ollama',
model: 'llama2',
enabled: true
},
status: 'ACTIVE'
}
});
console.log('✅ University created:', university.name);
// Create academic programs (majors)
const programs = [
{
title: 'Bachelor of Computer Science',
description: 'A comprehensive program covering software development, algorithms, and computer systems.',
level: 'UNDERGRADUATE',
duration: '4 years',
fees: '$12,000/year',
totalCredits: 120,
entryRequirements: 'High school diploma with strong mathematics background'
},
{
title: 'Master of Business Administration',
description: 'Advanced business management program with focus on leadership and strategy.',
level: 'POSTGRADUATE',
duration: '2 years',
fees: '$18,000/year',
totalCredits: 60,
entryRequirements: 'Bachelor\'s degree with 2+ years work experience'
},
{
title: 'PhD in Environmental Science',
description: 'Research-focused program in environmental studies and sustainability.',
level: 'PHD',
duration: '4-6 years',
fees: '$15,000/year',
totalCredits: 90,
entryRequirements: 'Master\'s degree in related field with research experience'
}
];
const createdPrograms = [];
for (const programData of programs) {
const program = await prisma.academicProgram.upsert({
where: {
id: `program-${programData.title.toLowerCase().replace(/\s+/g, '-')}`
},
update: {},
create: {
id: `program-${programData.title.toLowerCase().replace(/\s+/g, '-')}`,
...programData,
universityId: university.id,
level: programData.level as any
}
});
createdPrograms.push(program);
console.log('✅ Program created:', program.title);
}
// Create courses for each program
const coursesData = [
// Computer Science courses
{
programTitle: 'Bachelor of Computer Science',
courses: [
{ code: 'CS101', name: 'Introduction to Programming', description: 'Fundamentals of programming with Python', credits: 3, semester: '1', prerequisites: null },
{ code: 'CS201', name: 'Data Structures', description: 'Advanced data structures and algorithms', credits: 4, semester: '2', prerequisites: 'CS101' },
{ code: 'CS301', name: 'Database Systems', description: 'Database design and SQL programming', credits: 3, semester: '3', prerequisites: 'CS201' },
{ code: 'CS401', name: 'Software Engineering', description: 'Software development methodologies and practices', credits: 4, semester: '4', prerequisites: 'CS301' },
{ code: 'MATH101', name: 'Calculus I', description: 'Differential calculus and applications', credits: 4, semester: '1', prerequisites: null },
{ code: 'MATH201', name: 'Linear Algebra', description: 'Vector spaces and linear transformations', credits: 3, semester: '2', prerequisites: 'MATH101' }
]
},
// MBA courses
{
programTitle: 'Master of Business Administration',
courses: [
{ code: 'MBA501', name: 'Business Strategy', description: 'Strategic management and competitive analysis', credits: 3, semester: '1', prerequisites: null },
{ code: 'MBA502', name: 'Financial Management', description: 'Corporate finance and investment analysis', credits: 3, semester: '1', prerequisites: null },
{ code: 'MBA503', name: 'Marketing Management', description: 'Marketing strategy and consumer behavior', credits: 3, semester: '2', prerequisites: 'MBA501' },
{ code: 'MBA504', name: 'Operations Management', description: 'Supply chain and operations optimization', credits: 3, semester: '2', prerequisites: 'MBA502' }
]
},
// PhD courses
{
programTitle: 'PhD in Environmental Science',
courses: [
{ code: 'ENV601', name: 'Research Methods', description: 'Advanced research methodologies in environmental science', credits: 3, semester: '1', prerequisites: null },
{ code: 'ENV602', name: 'Environmental Policy', description: 'Environmental policy analysis and development', credits: 3, semester: '1', prerequisites: null },
{ code: 'ENV603', name: 'Climate Change Science', description: 'Advanced study of climate change mechanisms', credits: 3, semester: '2', prerequisites: 'ENV601' },
{ code: 'ENV604', name: 'Sustainability Systems', description: 'Systems thinking in sustainability', credits: 3, semester: '2', prerequisites: 'ENV602' }
]
}
];
for (const programCourses of coursesData) {
const program = createdPrograms.find(p => p.title === programCourses.programTitle);
if (program) {
for (const courseData of programCourses.courses) {
await prisma.course.upsert({
where: { code: courseData.code },
update: {},
create: {
code: courseData.code,
name: courseData.name,
description: courseData.description,
credits: courseData.credits,
semester: courseData.semester,
prerequisites: courseData.prerequisites,
universityId: university.id,
programId: program.id
}
});
console.log('✅ Course created:', courseData.code);
}
}
}
// Create sample users
const users = [
{
email: 'admin@test-university.edu',
name: 'Admin User',
password: 'admin123',
role: 'ADMIN',
universityId: university.id
},
})
{
email: 'student@test-university.edu',
name: 'John Student',
password: 'student123',
role: 'STUDENT',
universityId: university.id,
year: 2,
faculty: 'Computer Science'
},
{
email: 'staff@test-university.edu',
name: 'Jane Staff',
password: 'staff123',
role: 'STAFF',
universityId: university.id
}
];
const advisor1 = await prisma.user.create({
data: {
email: 'advisor.marine@university.edu',
name: 'Prof. Sarah Mitchell',
role: 'ADMIN',
},
})
for (const userData of users) {
const hashedPassword = await hashPassword(userData.password);
await prisma.user.upsert({
where: { email: userData.email },
update: {},
create: {
email: userData.email,
name: userData.name,
password: hashedPassword,
role: userData.role as any,
universityId: userData.universityId,
year: userData.year,
faculty: userData.faculty
}
});
console.log('✅ User created:', userData.email);
}
const advisor2 = await prisma.user.create({
data: {
email: 'advisor.engineering@university.edu',
name: 'Dr. James Rodriguez',
role: 'ADMIN',
// Create sample content
const content = [
{
contentType: 'ABOUT',
title: 'About Our University',
content: 'Test University is a leading institution dedicated to academic excellence and innovation.',
isPublished: true
},
})
{
contentType: 'RANKINGS',
title: 'University Rankings',
content: 'Our university consistently ranks among the top institutions nationally and internationally.',
isPublished: true
}
];
// Create diverse student users representing global UTAS community
const students = await Promise.all([
prisma.user.create({
data: {
email: 'student@university.edu',
name: 'Maya Patel',
role: 'STUDENT',
year: 2,
faculty: 'Marine and Antarctic Science',
balance: 2500.00,
advisorId: advisor1.id,
for (const contentData of content) {
await prisma.universityContent.upsert({
where: {
id: `content-${contentData.contentType.toLowerCase()}`
},
}),
prisma.user.create({
data: {
email: 'john.engineering@university.edu',
name: 'John Thompson',
role: 'STUDENT',
year: 3,
faculty: 'Engineering',
balance: 1800.00,
advisorId: advisor2.id,
},
}),
prisma.user.create({
data: {
email: 'amira.arts@university.edu',
name: 'Amira Al-Rashid',
role: 'STUDENT',
year: 1,
faculty: 'Creative Arts and Design',
balance: 3200.00,
advisorId: admin.id,
},
}),
prisma.user.create({
data: {
email: 'lucas.business@university.edu',
name: 'Lucas Chen',
role: 'STUDENT',
year: 4,
faculty: 'Business and Law',
balance: 950.00,
advisorId: admin.id,
},
}),
prisma.user.create({
data: {
email: 'sophia.health@university.edu',
name: 'Sophia Williams',
role: 'STUDENT',
year: 2,
faculty: 'Health and Medicine',
balance: 4100.00,
advisorId: advisor1.id,
},
}),
prisma.user.create({
data: {
email: 'ahmed.science@university.edu',
name: 'Ahmed Hassan',
role: 'STUDENT',
year: 3,
faculty: 'Science, Technology and Engineering',
balance: 2750.00,
advisorId: advisor2.id,
},
}),
])
update: {},
create: {
id: `content-${contentData.contentType.toLowerCase()}`,
contentType: contentData.contentType as any,
title: contentData.title,
content: contentData.content,
isPublished: contentData.isPublished,
universityId: university.id
}
});
console.log('✅ Content created:', contentData.title);
}
// Create comprehensive course catalog representing UTAS excellence
const courses = await Promise.all([
// Marine and Antarctic Science - UTAS's #1 Global Program
prisma.course.create({
data: {
code: 'MARS301',
name: 'Marine Ecosystem Dynamics',
description: 'Advanced study of marine ecosystems using IMAS research facilities. Field work in Southern Ocean.',
credits: 4,
semester: 'Spring 2025',
schedule: 'MWF 9:00-11:00 + Field Work',
},
}),
prisma.course.create({
data: {
code: 'ANTR401',
name: 'Antarctic Climate Science',
description: 'Climate change research methods using real Antarctic data from UTAS research stations.',
credits: 4,
semester: 'Fall 2025',
schedule: 'TTh 14:00-17:00',
},
}),
// Engineering Excellence
prisma.course.create({
data: {
code: 'ENGR201',
name: 'Sustainable Engineering Design',
description: 'Engineering principles focused on sustainability and carbon-neutral solutions.',
credits: 3,
semester: 'Spring 2025',
schedule: 'MWF 10:00-11:30',
},
}),
prisma.course.create({
data: {
code: 'SOFT301',
name: 'AI and Machine Learning',
description: 'Advanced AI applications in environmental monitoring and climate prediction.',
credits: 4,
semester: 'Fall 2025',
schedule: 'TTh 13:00-15:30',
},
}),
// Creative Arts Innovation
prisma.course.create({
data: {
code: 'ARTS205',
name: 'Digital Media and Sustainability',
description: 'Creating digital art that raises awareness about climate action and environmental issues.',
credits: 3,
semester: 'Spring 2025',
schedule: 'MW 14:00-17:00',
},
}),
// Business and Innovation
prisma.course.create({
data: {
code: 'BUSI350',
name: 'Sustainable Business Strategy',
description: 'Developing business models aligned with UN Sustainable Development Goals.',
credits: 3,
semester: 'Fall 2025',
schedule: 'TTh 9:00-10:30',
},
}),
// Health and Medicine
prisma.course.create({
data: {
code: 'HLTH250',
name: 'Climate Health and Medicine',
description: 'Understanding health impacts of climate change and developing adaptive healthcare strategies.',
credits: 3,
semester: 'Spring 2025',
schedule: 'MWF 11:00-12:00',
},
}),
// Core Requirements
prisma.course.create({
data: {
code: 'MATH201',
name: 'Statistics for Environmental Science',
description: 'Applied statistics with focus on environmental data analysis and climate modeling.',
credits: 4,
semester: 'Both Semesters',
schedule: 'MWF 8:00-9:00',
},
}),
// Interdisciplinary Innovation
prisma.course.create({
data: {
code: 'INTR401',
name: 'Climate Action Leadership',
description: 'Capstone course combining multiple disciplines to address real-world climate challenges.',
credits: 4,
semester: 'Spring 2025',
schedule: 'TTh 15:00-18:00',
},
}),
// International Focus
prisma.course.create({
data: {
code: 'INTL301',
name: 'Global Sustainability Partnerships',
description: 'Collaborative projects with international universities on sustainability initiatives.',
credits: 3,
semester: 'Fall 2025',
schedule: 'Online + Intensive Workshops',
},
}),
])
// Create realistic enrollments showcasing student diversity
const enrollments = await Promise.all([
// Maya Patel (Marine Science student)
prisma.enrollment.create({
data: {
userId: students[0].id,
courseId: courses[0].id, // Marine Ecosystem Dynamics
grade: 'A',
status: 'ENROLLED',
},
}),
prisma.enrollment.create({
data: {
userId: students[0].id,
courseId: courses[1].id, // Antarctic Climate Science
grade: 'A-',
status: 'ENROLLED',
},
}),
// John Thompson (Engineering student)
prisma.enrollment.create({
data: {
userId: students[1].id,
courseId: courses[2].id, // Sustainable Engineering
grade: 'B+',
status: 'ENROLLED',
},
}),
prisma.enrollment.create({
data: {
userId: students[1].id,
courseId: courses[3].id, // AI and ML
grade: 'A-',
status: 'ENROLLED',
},
}),
// Amira Al-Rashid (Arts student)
prisma.enrollment.create({
data: {
userId: students[2].id,
courseId: courses[4].id, // Digital Media
grade: 'A',
status: 'ENROLLED',
},
}),
// Lucas Chen (Business student)
prisma.enrollment.create({
data: {
userId: students[3].id,
courseId: courses[5].id, // Sustainable Business
grade: 'B+',
status: 'ENROLLED',
},
}),
// Cross-disciplinary enrollments showing UTAS integration
prisma.enrollment.create({
data: {
userId: students[4].id, // Sophia (Health)
courseId: courses[6].id, // Climate Health
grade: 'A',
status: 'ENROLLED',
},
}),
prisma.enrollment.create({
data: {
userId: students[5].id, // Ahmed (Science)
courseId: courses[7].id, // Statistics
grade: 'B+',
status: 'ENROLLED',
},
}),
])
// Create comprehensive FAQ database showcasing UTAS excellence and AI capabilities
const faqs = [
// Academic Excellence & Programs
{
question: 'Why is UTAS ranked #1 globally for climate action?',
answer: 'UTAS has been ranked #1 globally for climate action by THE Impact Rankings for four consecutive years (2022-2025) due to our: 100% renewable energy across all campuses, 50% reduction in carbon emissions since 2007, Climate Active Carbon Neutral certification, world-leading research at IMAS (Institute for Marine and Antarctic Studies), and comprehensive sustainability integration across all programs.',
category: 'Academic',
language: 'en',
priority: 1,
},
{
question: 'How do I access the AI Study Assistant?',
answer: 'Our 24/7 AI Study Assistant is available through: 1) The floating chat widget on any portal page, 2) Voice activation by saying "Hey UTAS", 3) Mobile app integration, 4) Smart study room kiosks on campus. The AI provides multilingual support in English and Arabic, personalized study plans, assignment help, and can even detect if you need mental health support.',
category: 'Technology',
language: 'en',
priority: 1,
},
{
question: 'What makes UTAS marine science programs unique?',
answer: 'UTAS marine science is globally recognized through IMAS with: Direct access to Antarctic research stations, World-class research vessels for hands-on learning, Partnerships with Australian Antarctic Division, Real-time Southern Ocean monitoring systems, Industry collaborations with fishing and aquaculture sectors, and Graduate employment rate of 95% within 6 months.',
category: 'Academic',
language: 'en',
priority: 1,
},
{
question: 'How does the predictive analytics system work?',
answer: 'Our AI-powered analytics track your: Academic performance patterns, Study habits and engagement levels, Assignment submission timing, Library and resource usage, Extracurricular participation. The system provides early intervention alerts, personalized study recommendations, career pathway suggestions, and can predict graduation success probability with 94% accuracy.',
category: 'Technology',
language: 'en',
priority: 2,
},
// International & Multilingual Support
{
question: 'كيف يمكنني الحصول على الدعم باللغة العربية؟',
answer: 'توفر جامعة تاسمانيا دعماً شاملاً باللغة العربية من خلال: مساعد ذكي متاح 24/7 باللغة العربية، مستشارين أكاديميين يتحدثون العربية، خدمات ترجمة فورية في الحرم الجامعي، مجتمع طلابي عربي نشط، وبرامج توجيه خاصة للطلاب الدوليين الناطقين بالعربية.',
category: 'International',
language: 'ar',
priority: 1,
},
{
question: 'What international opportunities are available?',
answer: 'UTAS offers extensive international experiences: Antarctic research expeditions, Student exchange with 200+ partner universities, International internship placements, Global sustainability project collaborations, Study abroad in 40+ countries, International conference presentations, and Global virtual classroom partnerships.',
category: 'International',
language: 'en',
priority: 2,
},
// Student Support & Mental Health
{
question: 'How does the AI mental health support work?',
answer: 'Our AI mental health system provides: 24/7 mood and stress level monitoring through voluntary check-ins, Early detection of crisis indicators in academic performance, Anonymous peer support matching, Immediate crisis intervention protocols, Integration with on-campus counseling services, and Predictive wellness recommendations. All data is encrypted and privacy-protected.',
category: 'Wellbeing',
language: 'en',
priority: 1,
},
{
question: 'What financial support is available?',
answer: 'UTAS offers comprehensive financial assistance: Merit Scholarships up to $15,000/year, Need-based grants for 40% of students, International student scholarships, Emergency financial hardship funds, Work-study programs on campus, Industry-sponsored research positions, and AI-powered budget planning tools in your portal.',
category: 'Financial',
language: 'en',
priority: 2,
},
// Campus Life & Sustainability
{
question: 'How is UTAS achieving carbon neutrality?',
answer: 'UTAS is already Climate Active Carbon Neutral certified through: 100% renewable energy from wind and solar, Campus-wide energy efficiency systems, Zero waste to landfill programs, Sustainable transport initiatives, Carbon offset research projects, Green building standards for all construction, and Student-led sustainability projects.',
category: 'Sustainability',
language: 'en',
priority: 1,
},
{
question: 'What accessibility features does the portal have?',
answer: 'Our AI-powered accessibility features include: Automatic alt-text generation for all images, Voice navigation and screen reader optimization, Real-time WCAG compliance checking, Customizable UI for visual impairments, Cognitive load adaptation based on user needs, Multi-language content translation, and Predictive accessibility recommendations.',
category: 'Accessibility',
language: 'en',
priority: 2,
},
// Research & Innovation
{
question: 'How can I get involved in climate research?',
answer: 'Students can participate in climate research through: IMAS undergraduate research programs, Antarctic field work opportunities, Climate modeling projects using supercomputing facilities, Industry partnership projects, International collaboration research, Paid research assistant positions, and Publication opportunities in peer-reviewed journals.',
category: 'Research',
language: 'en',
priority: 2,
},
{
question: 'What industry connections does UTAS have?',
answer: 'UTAS maintains strong industry partnerships with: Tasmanian salmon farming industry, Antarctic logistics companies, Renewable energy providers, Australian government agencies, International climate organizations, Technology startups, Mining and resources sector, and Creative industries. 89% of graduates secure employment within 6 months.',
category: 'Career',
language: 'en',
priority: 2,
},
// Technology & Innovation
{
question: 'How do I use the virtual campus tour?',
answer: 'Access our AI-powered virtual tours through: Portal homepage virtual tour button, Mobile app AR campus navigation, VR headsets in student lounges, Interactive campus maps with real-time information, 360° facility tours including research labs, Live streaming from research vessels, and Virtual reality Antarctic station tours.',
category: 'Technology',
language: 'en',
priority: 3,
},
{
question: 'What smart campus features are available?',
answer: 'UTAS smart campus includes: IoT-enabled study space booking, Real-time campus energy usage displays, Smart parking with availability alerts, Automated library services, Environmental monitoring stations, Smart building climate controls, Campus-wide WiFi 6 connectivity, and AI-powered resource optimization.',
category: 'Campus',
language: 'en',
priority: 3,
},
// Practical Information
{
question: 'How do I register for classes?',
answer: 'Class registration uses our AI-enhanced system: Login to student portal dashboard, Use the "Smart Schedule Builder" for optimal timetables, AI recommendations based on degree progress, Real-time seat availability updates, Waitlist management with priority notifications, Cross-campus course coordination, and Integration with academic advisor approval.',
category: 'Academic',
language: 'en',
priority: 2,
},
{
question: 'Where can I find study spaces?',
answer: 'UTAS provides diverse study environments: 24/7 smart study pods with climate control, Collaborative spaces with interactive whiteboards, Silent zones with noise-canceling technology, Outdoor study areas with device charging, Library spaces with real-time availability, Specialist research environments, and Bookable group project rooms through the portal.',
category: 'Campus',
language: 'en',
priority: 3,
},
// Advanced Features Demo
{
question: 'How does the portal learn my preferences?',
answer: 'Our adaptive AI system learns through: Your interaction patterns and click behavior, Study schedule optimization preferences, Content consumption habits, Accessibility needs and modifications, Language and communication preferences, Academic goal tracking, and Performance correlation analysis. All learning is opt-in and privacy-protected.',
category: 'Technology',
language: 'en',
priority: 3,
},
]
await Promise.all(
faqs.map(faq => prisma.fAQ.create({ data: faq }))
)
console.log('✅ Database seeded successfully with comprehensive UTAS data!')
console.log(`📊 Created:`)
console.log(` 👤 ${students.length} students + 3 staff members`)
console.log(` 📚 ${courses.length} courses across all UTAS faculties`)
console.log(` 📝 ${enrollments.length} student enrollments`)
console.log(`${faqs.length} comprehensive FAQs`)
console.log(`🎯 Portal ready for demo with realistic UTAS data!`)
console.log('🎉 Database seeding completed successfully!');
}
main()
.catch((e) => {
console.error(e)
process.exit(1)
console.error('❌ Error during seeding:', e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect()
})
await prisma.$disconnect();
});