Files
Krikorios aa459f4bd6 🎉 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!
2025-07-20 08:26:25 +04:00

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
}