🎉 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
+818
View File
@@ -0,0 +1,818 @@
# White-Label University Portal - Developer Guide
## 📚 Table of Contents
1. [Architecture Overview](#architecture-overview)
2. [Getting Started](#getting-started)
3. [API Documentation](#api-documentation)
4. [Database Schema](#database-schema)
5. [Multi-Tenant Architecture](#multi-tenant-architecture)
6. [Performance Optimization](#performance-optimization)
7. [Deployment Guide](#deployment-guide)
8. [Testing](#testing)
9. [Contributing](#contributing)
10. [Troubleshooting](#troubleshooting)
---
## 🏗️ Architecture Overview
### Technology Stack
- **Frontend**: Next.js 14, React 19, TypeScript, Tailwind CSS
- **Backend**: Next.js API Routes, Prisma ORM
- **Database**: PostgreSQL (primary), Redis (caching)
- **AI**: OpenRouter AI integration
- **CDN**: Multi-provider support (AWS S3, Cloudflare, Cloudinary)
- **Deployment**: Vercel, Docker, Kubernetes
### System Architecture
```
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Frontend │ │ API Layer │ │ Database │
│ (Next.js) │◄──►│ (Next.js) │◄──►│ (PostgreSQL) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ CDN Layer │ │ Cache Layer │ │ AI Services │
│ (Multi-CDN) │ │ (Redis) │ │ (OpenRouter) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
```
### Multi-Tenant Design
The platform uses a **database-per-tenant** approach with shared application code:
- **Data Isolation**: Each university's data is completely isolated
- **Shared Infrastructure**: Common codebase and infrastructure
- **Dynamic Configuration**: University-specific settings and branding
- **Scalable Architecture**: Horizontal scaling support
---
## 🚀 Getting Started
### Prerequisites
- **Node.js**: 18.x or higher
- **PostgreSQL**: 14.x or higher
- **Redis**: 6.x or higher
- **Git**: Latest version
- **Docker**: (optional, for containerized development)
### Installation
1. **Clone the Repository**
```bash
git clone https://github.com/your-org/university-portal.git
cd university-portal
```
2. **Install Dependencies**
```bash
npm install
```
3. **Environment Setup**
```bash
cp .env.example .env.local
# Edit .env.local with your configuration
```
4. **Database Setup**
```bash
npx prisma generate
npx prisma db push
npx prisma db seed
```
5. **Start Development Server**
```bash
npm run dev
```
### Environment Variables
```env
# Database
DATABASE_URL="postgresql://user:password@localhost:5432/university_portal"
# Redis
REDIS_HOST="localhost"
REDIS_PORT="6379"
REDIS_PASSWORD=""
REDIS_DB="0"
# AI Services
OPENROUTER_API_KEY="your-api-key"
OPENROUTER_BASE_URL="https://openrouter.ai/api/v1"
# CDN Configuration
AWS_ACCESS_KEY_ID="your-access-key"
AWS_SECRET_ACCESS_KEY="your-secret-key"
AWS_REGION="us-east-1"
AWS_S3_BUCKET="your-bucket"
# Application
NEXT_PUBLIC_APP_URL="http://localhost:3000"
NEXTAUTH_SECRET="your-secret"
NEXTAUTH_URL="http://localhost:3000"
```
---
## 📡 API Documentation
### Authentication
All API endpoints require university context via headers:
```http
X-University-Id: university-id
X-University-Slug: university-slug
```
### Core Endpoints
#### Universities
```http
GET /api/universities
POST /api/universities
GET /api/universities/[slug]
PUT /api/universities/[slug]
DELETE /api/universities/[slug]
```
#### Content Management
```http
GET /api/content
POST /api/content
GET /api/content/[id]
PUT /api/content/[id]
DELETE /api/content/[id]
```
#### Programs
```http
GET /api/programs
POST /api/programs
GET /api/programs/[id]
PUT /api/programs/[id]
DELETE /api/programs/[id]
```
#### Domains
```http
GET /api/domains
POST /api/domains
GET /api/domains/[id]
PUT /api/domains/[id]
DELETE /api/domains/[id]
POST /api/domains/[id]/validate
POST /api/domains/[id]/renew-ssl
```
#### Deployments
```http
GET /api/deployments
POST /api/deployments
GET /api/deployments/[id]
POST /api/deployments/[id]/execute
POST /api/deployments/[id]/rollback
```
### Response Format
All API responses follow a consistent format:
```json
{
"success": true,
"data": {
// Response data
},
"message": "Operation completed successfully",
"timestamp": "2025-01-01T00:00:00.000Z"
}
```
### Error Handling
```json
{
"success": false,
"error": "Error message",
"code": "ERROR_CODE",
"timestamp": "2025-01-01T00:00:00.000Z"
}
```
---
## 🗄️ Database Schema
### Core Models
#### University
```prisma
model University {
id String @id @default(uuid())
slug String @unique
name String
shortName String?
domain String?
subdomain String?
branding Json
contact Json
features Json
ai Json
status UniversityStatus @default(ACTIVE)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// Relations
assets UniversityAsset[]
content UniversityContent[]
programs AcademicProgram[]
knowledge AIKnowledgeBase[]
domains DomainConfig[]
deployments DeploymentConfig[]
cdnConfig CDNConfig?
cdnAssets CDNAsset[]
}
```
#### UniversityContent
```prisma
model UniversityContent {
id String @id @default(uuid())
universityId String
title String
content String
contentType ContentType
language Language @default(ENGLISH)
isPublished Boolean @default(false)
metadata Json?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
university University @relation(fields: [universityId], references: [id], onDelete: Cascade)
}
```
#### AcademicProgram
```prisma
model AcademicProgram {
id String @id @default(uuid())
universityId String
title String
description String
level ProgramLevel
duration String
fees Json?
requirements Json?
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
university University @relation(fields: [universityId], references: [id], onDelete: Cascade)
}
```
### Domain Management
#### DomainConfig
```prisma
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
university University @relation(fields: [universityId], references: [id], onDelete: Cascade)
sslConfig SSLConfig?
dnsConfig DNSConfig?
analytics DomainAnalytics[]
}
```
### Enums
```prisma
enum UniversityStatus {
ACTIVE
INACTIVE
SUSPENDED
}
enum ContentType {
ABOUT
NEWS
EVENTS
RESEARCH
CAMPUS
}
enum Language {
ENGLISH
ARABIC
}
enum ProgramLevel {
UNDERGRADUATE
POSTGRADUATE
PHD
}
enum DomainType {
SUBDOMAIN
CUSTOM_DOMAIN
}
enum SSLStatus {
PENDING
ACTIVE
EXPIRED
ERROR
}
```
---
## 🏢 Multi-Tenant Architecture
### Data Isolation
The platform ensures complete data isolation between universities:
```typescript
// Data isolation middleware
export async function validateUniversityAccess(request: NextRequest): Promise<UniversityContext> {
const university = getUniversityFromHeaders(request);
if (!university) {
throw new Error('University context required');
}
// Verify university exists and is active
const dbUniversity = await prisma.university.findUnique({
where: { id: university.id, status: 'ACTIVE' },
});
if (!dbUniversity) {
throw new Error('University not found or inactive');
}
return university;
}
```
### University Context
```typescript
// University provider for React components
export function UniversityProvider({ children, initialUniversity }: UniversityProviderProps) {
const [university, setUniversity] = useState<University | null>(initialUniversity);
// Load university data based on cookies or headers
const loadUniversity = async () => {
const response = await fetch('/api/universities/current');
const data = await response.json();
setUniversity(data);
};
return (
<UniversityContext.Provider value={{ university, setUniversity }}>
{children}
</UniversityContext.Provider>
);
}
```
### Dynamic Branding
```typescript
// Dynamic branding component
export function DynamicBranding() {
const { university } = useUniversity();
if (!university) return null;
const { branding } = university;
return (
<div style={{
'--primary-color': branding.primaryColor,
'--secondary-color': branding.secondaryColor,
} as React.CSSProperties}>
<img src={branding.logo} alt={university.name} />
<h1>{university.name}</h1>
</div>
);
}
```
---
## ⚡ Performance Optimization
### Caching Strategy
```typescript
// Redis caching implementation
export class CacheManager {
async getUniversity(slug: string): Promise<any> {
const cacheKey = `university:${slug}`;
// Try cache first
const cached = await this.client.get(cacheKey);
if (cached) {
return JSON.parse(cached);
}
// Query database
const university = await prisma.university.findUnique({
where: { slug },
include: { assets: true, programs: true }
});
// Cache result
if (university) {
await this.client.setEx(cacheKey, 1800, JSON.stringify(university));
}
return university;
}
}
```
### Query Optimization
```typescript
// Optimized database queries
export class QueryOptimizer {
async getPrograms(universityId: string, options: any) {
const { page = 1, limit = 10, search } = options;
const skip = (page - 1) * limit;
const where = {
universityId,
isActive: true,
...(search && {
OR: [
{ title: { contains: search, mode: 'insensitive' } },
{ description: { contains: search, mode: 'insensitive' } },
],
}),
};
// Parallel queries for better performance
const [programs, total] = await Promise.all([
prisma.academicProgram.findMany({ where, skip, take: limit }),
prisma.academicProgram.count({ where }),
]);
return { programs, total, page, totalPages: Math.ceil(total / limit) };
}
}
```
### CDN Integration
```typescript
// Multi-provider CDN support
export class CDNManager {
async uploadAsset(file: File, path: string): Promise<CDNAsset> {
const config = await this.getCDNConfig();
let cdnUrl: string;
switch (config.provider) {
case 'AWS_S3':
cdnUrl = await this.uploadToS3(file, path, config);
break;
case 'CLOUDFLARE':
cdnUrl = await this.uploadToCloudflare(file, path, config);
break;
case 'CLOUDINARY':
cdnUrl = await this.uploadToCloudinary(file, path, config);
break;
default:
throw new Error('Unsupported CDN provider');
}
return { originalPath: path, cdnUrl, optimizedUrls: {} };
}
}
```
---
## 🚀 Deployment Guide
### Environment Setup
1. **Production Environment**
```bash
# Set production environment variables
export NODE_ENV=production
export DATABASE_URL="postgresql://..."
export REDIS_URL="redis://..."
```
2. **Database Migration**
```bash
npx prisma migrate deploy
npx prisma generate
```
3. **Build Application**
```bash
npm run build
```
### Docker Deployment
```dockerfile
# Dockerfile
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["npm", "start"]
```
```yaml
# docker-compose.yml
version: '3.8'
services:
app:
build: .
ports:
- "3000:3000"
environment:
- DATABASE_URL=${DATABASE_URL}
- REDIS_URL=${REDIS_URL}
depends_on:
- postgres
- redis
postgres:
image: postgres:14
environment:
POSTGRES_DB: university_portal
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASSWORD}
redis:
image: redis:6-alpine
```
### Vercel Deployment
1. **Connect Repository**
- Link your GitHub repository to Vercel
- Configure environment variables
2. **Deploy**
```bash
vercel --prod
```
3. **Custom Domain**
- Add custom domain in Vercel dashboard
- Configure DNS records
---
## 🧪 Testing
### Unit Tests
```typescript
// Example unit test
import { describe, it, expect } from 'vitest';
import { CacheManager } from '../lib/cache';
describe('CacheManager', () => {
it('should cache and retrieve university data', async () => {
const cache = new CacheManager(config);
const university = { id: '1', name: 'Test University' };
await cache.set('university:test', university);
const retrieved = await cache.get('university:test');
expect(retrieved).toEqual(university);
});
});
```
### Integration Tests
```typescript
// Example integration test
import { describe, it, expect } from 'vitest';
import { createMocks } from 'node-mocks-http';
import handler from '../pages/api/universities';
describe('/api/universities', () => {
it('should return universities list', async () => {
const { req, res } = createMocks({
method: 'GET',
headers: { 'x-university-id': 'test-university' },
});
await handler(req, res);
expect(res._getStatusCode()).toBe(200);
expect(JSON.parse(res._getData())).toHaveProperty('data');
});
});
```
### Load Testing
```typescript
// Example load test
import { LoadTester } from '../lib/loadTesting';
const config = {
name: 'API Load Test',
duration: 300,
users: 50,
targetRPS: 10,
scenarios: [
{
name: 'Get Universities',
weight: 100,
requests: [
{
method: 'GET',
url: '/api/universities',
expectedStatus: 200,
},
],
},
],
};
const tester = new LoadTester(config);
const results = await tester.run();
```
---
## 🤝 Contributing
### Development Workflow
1. **Fork the Repository**
```bash
git clone https://github.com/your-username/university-portal.git
cd university-portal
```
2. **Create Feature Branch**
```bash
git checkout -b feature/your-feature-name
```
3. **Make Changes**
- Follow the coding standards
- Add tests for new features
- Update documentation
4. **Submit Pull Request**
```bash
git push origin feature/your-feature-name
# Create PR on GitHub
```
### Coding Standards
- **TypeScript**: Strict mode enabled
- **ESLint**: Airbnb configuration
- **Prettier**: Consistent formatting
- **Conventional Commits**: Standard commit messages
### Code Review Process
1. **Automated Checks**
- Linting and formatting
- Type checking
- Unit tests
- Integration tests
2. **Manual Review**
- Code quality review
- Security review
- Performance review
3. **Approval**
- At least 2 approvals required
- All checks must pass
---
## 🔧 Troubleshooting
### Common Issues
1. **Database Connection**
```bash
# Check database connection
npx prisma db push
# Reset database
npx prisma migrate reset
```
2. **Redis Connection**
```bash
# Check Redis connection
redis-cli ping
# Clear cache
redis-cli flushall
```
3. **Build Issues**
```bash
# Clear Next.js cache
rm -rf .next
npm run build
```
### Debug Mode
```bash
# Enable debug logging
DEBUG=* npm run dev
# Database queries
DEBUG=prisma:query npm run dev
# Redis operations
DEBUG=redis npm run dev
```
### Performance Monitoring
```typescript
// Monitor query performance
const queryOptimizer = getQueryOptimizer();
const stats = queryOptimizer.getQueryStats();
console.log('Query Statistics:', stats);
// Monitor cache performance
const cache = getCacheInstance();
const cacheStats = await cache.getStats();
console.log('Cache Statistics:', cacheStats);
```
---
## 📞 Support
### Getting Help
- **Documentation**: This developer guide
- **Issues**: GitHub Issues
- **Discussions**: GitHub Discussions
- **Email**: dev-support@your-domain.com
### Resources
- **API Reference**: `/api/docs`
- **Database Schema**: `prisma/schema.prisma`
- **Component Library**: Storybook documentation
- **Performance Dashboard**: `/admin/performance`
---
**Last Updated**: January 2025
**Version**: 1.0
**Platform**: White-Label University Portal