✨ 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!
583 lines
13 KiB
Plaintext
583 lines
13 KiB
Plaintext
generator client {
|
|
provider = "prisma-client-js"
|
|
}
|
|
|
|
datasource db {
|
|
provider = "sqlite"
|
|
url = "file:./dev.db"
|
|
}
|
|
|
|
// Multi-tenant University Configuration
|
|
model University {
|
|
id String @id @default(uuid())
|
|
slug String @unique
|
|
name String
|
|
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
|
|
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("universities")
|
|
}
|
|
|
|
// Academic Programs (Majors) - University-specific
|
|
model AcademicProgram {
|
|
id String @id @default(uuid())
|
|
universityId String
|
|
title String
|
|
titleAr String?
|
|
description 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
|
|
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
|
|
courseId String
|
|
grade String?
|
|
status EnrollmentStatus @default(ENROLLED)
|
|
|
|
// Relationships
|
|
user User @relation(fields: [userId], references: [id])
|
|
course Course @relation(fields: [courseId], references: [id])
|
|
|
|
@@unique([userId, courseId])
|
|
@@map("enrollments")
|
|
}
|
|
|
|
model ChatSession {
|
|
id String @id @default(uuid())
|
|
userId String?
|
|
type ChatType @default(GENERAL)
|
|
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?
|
|
type String
|
|
rating Int
|
|
feedback String?
|
|
sessionId String?
|
|
createdAt DateTime @default(now())
|
|
|
|
// Relationships
|
|
user User? @relation(fields: [userId], references: [id])
|
|
|
|
@@map("surveys")
|
|
}
|
|
|
|
model AccessibilityAudit {
|
|
id String @id @default(uuid())
|
|
url String
|
|
imagePath String?
|
|
altText String?
|
|
wcagScore Float?
|
|
issues Json?
|
|
suggestions Json?
|
|
createdAt DateTime @default(now())
|
|
|
|
@@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 {
|
|
ENROLLED
|
|
COMPLETED
|
|
DROPPED
|
|
PENDING
|
|
}
|
|
|
|
enum ChatType {
|
|
GENERAL
|
|
MENTAL_HEALTH
|
|
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
|
|
}
|