UniSync is a premium, cross-platform appointment scheduling system purpose-built for university communities. It transitions the informal, email-heavy booking of student–lecturer meetings into a structured, timetable-aware, role-based scheduling ecosystem.
UniSync is built on a decoupled, modern multi-tier architecture designed for scalability, real-time synchronization, and low-latency interaction.
graph TD
subgraph Clients ["Client Applications"]
MobileApp["React Native Expo Mobile App"]
WebApp["React Vite Web App"]
end
subgraph ServerLayer ["Backend API Layer"]
ExpressServer["Node.js / Express Server"]
SocketServer["Socket.io Server (Real-time updates)"]
end
subgraph StorageLayer ["Data & Queuing Layer"]
MongoDB[("MongoDB Database\n(Mongoose ORM)")]
RedisDB[("Redis DB\n(BullMQ Cache/Queue)")]
end
%% Client to Server Connections
MobileApp -->|HTTP / REST API| ExpressServer
MobileApp <-->|WebSocket| SocketServer
WebApp -->|HTTP / REST API| ExpressServer
WebApp <-->|WebSocket| SocketServer
%% Server to Storage Connections
ExpressServer -->|Read/Write| MongoDB
ExpressServer <-->|Jobs / Cache| RedisDB
SocketServer <-->|Event Coordination| RedisDB
- Client Applications: Multi-platform clients share a common REST and WebSocket API. The web application serves administrators and desktop users, while the mobile application provides native capabilities (such as push notifications and cross-platform secure storage) for students and lecturers on the go.
- Backend API Layer: Powered by Express.js and TypeScript, handling business logic, authentication (JWT), file parsing (PDF/CSV/XLSX), and notification triggers.
- Real-time Synchronization: Socket.io coordinates instant booking state updates and live messages between students and lecturers.
- Data & Caching: MongoDB Atlas acts as the persistent document database. Redis sits alongside as a caching layer for availability calculations and powers the BullMQ background worker system for booking reminders.
The system enforces relational integrity at the application level using Mongoose schemas. The database structure is mapped below:
erDiagram
USER {
ObjectId id PK
string name
string email
string role "student | lecturer | admin"
string regNumber "unique (students)"
string department
string degreeProgram
string passwordHash
boolean isActive
string[] pushTokens
}
APPOINTMENT {
ObjectId id PK
ObjectId studentId FK
ObjectId lecturerId FK
date requestedStart
date requestedEnd
string status "pending | approved | rejected | cancelled"
string priority "normal | academic_urgent | emergency"
int priorityWeight
string reason
string description
array statusHistory
}
AVAILABILITY_RULE {
ObjectId id PK
ObjectId lecturerId FK
string type "office_hours | blackout | lectures | buffer"
int dayOfWeek "0-6"
string startTime "HH:MM"
string endTime "HH:MM"
int bufferMins
date date
}
TIMETABLE_BLOCK {
ObjectId id PK
ObjectId lecturerId FK
int dayOfWeek "0-6"
string startTime "HH:MM"
string endTime "HH:MM"
string courseName
string room
string semester
boolean isActive
}
MESSAGE {
ObjectId id PK
ObjectId appointmentId FK
ObjectId senderId FK
string body
date readAt
date createdAt
}
NOTIFICATION {
ObjectId id PK
ObjectId userId FK
string title
string message
string type "info | success | error"
boolean read
ObjectId relatedId
}
USER ||--o{ APPOINTMENT : "makes/receives"
USER ||--o{ AVAILABILITY_RULE : "configures"
USER ||--o{ TIMETABLE_BLOCK : "teaches"
USER ||--o{ MESSAGE : "sends"
USER ||--o{ NOTIFICATION : "receives"
APPOINTMENT ||--o{ MESSAGE : "contains"
- Smart Availability Engine: Evaluates a lecturer's recurring office hours, subtracts fixed teaching blocks (imported from Excel/CSV/PDF timetables), subtracts blackout periods, and returns verified, free booking blocks.
- Priority Override System: Resolves schedule conflicts by evaluating the priority level of a booking (
Normal = 1,Academic Urgent = 2,Emergency = 3). Higher-priority bookings override existing requests. - Automated Reminders: Redis-backed background queues send notifications to participants 24 hours and 1 hour before an upcoming meeting.
- Chat and File Sharing: Every appointment establishes a secure direct chat room. Students can upload support documentation (such as medical certificates) directly from their device.
Uni Sync/
├── backend/ # Node.js/Express Backend Server
│ ├── src/
│ │ ├── models/ # Mongoose schemas (User, Appointment, etc.)
│ │ ├── db.ts # Database connection & memory fallbacks
│ │ ├── seed.ts # Sample database seeder
│ │ └── index.ts # Core Express API and Socket.io endpoints
│ ├── tests/ # Jest integration tests
│ └── package.json
├── frontend/ # React Web Application (Vite)
│ ├── src/
│ │ ├── components/ # Shared UI components
│ │ ├── pages/ # Web layouts (Admin, Student, Lecturer Dashboards)
│ │ └── App.tsx # Navigation & client routing
│ └── package.json
├── mobile/ # React Native Expo Mobile App
│ ├── app/ # Expo Router directory (File-based navigation)
│ ├── components/ # Screen UI modules
│ ├── hooks/ # Custom React hooks (auth, socket, toast)
│ └── package.json
└── login_credentials.md # Development credential reference
- Node.js (v18 or higher)
- npm (v9 or higher)
- MongoDB (Local instance or Atlas connection)
- Redis (Optional: for reminders/queues)
-
Clone and Install Dependencies:
# Install backend dependencies cd backend npm install # Install frontend dependencies cd ../frontend npm install # Install mobile app dependencies cd ../mobile npm install
-
Configure Environment Variables: Create a
.envfile in thebackend/andmobile/directories matching the templates below:backend/.envPORT=3001 MONGODB_URI=mongodb://localhost:27017/unisync JWT_SECRET=your_jwt_secret_key REDIS_URL=redis://localhost:6379 FRONTEND_URL=http://localhost:5173
mobile/.envEXPO_PUBLIC_API_URL=http://localhost:3001
-
Seed Database: Seed initial development users, courses, and schedules:
cd backend npm run seedNote: For testing credentials, refer to login_credentials.md in the project root.
-
Run the Applications:
- Backend:
cd backend npm run dev - Frontend:
cd frontend npm run dev - Mobile:
cd mobile npx expo start
- Backend:
For campus deployment, the system can be run completely containerized using Docker and Docker Compose. This packages the backend, frontend, database, and caching servers into a seamless, unified ecosystem.
-
Build and Run the Containers:
docker-compose up --build -d
This will build the custom
frontendandbackendimages, pull the official MongoDB and Redis images, and launch the entire application on port80. -
Accessing the App:
- Web Frontend: Navigate to
http://localhost(or your campus server's domain/IP on port 80). - Backend API:
http://localhost/api(proxied by Nginx). - WebSockets:
http://localhost/socket.io(proxied by Nginx).
- Web Frontend: Navigate to
-
Automatic Seeding: On the very first launch, the backend detects that the MongoDB database is empty and automatically triggers the seeding script. This populates the system with demo lecturers, students, timetables, and rules.
- Frontend Container: Uses a multi-stage build starting with Node.js to compile static assets and uses an Nginx alpine container to serve the web files and reverse-proxy the API/WS calls.
- Backend Container: Built on Node.js 22 alpine, serving REST APIs and handling WebSockets.
- Database Container: Powered by MongoDB 6.0 with volume persistence on the host machine.
- Cache Container: Powered by Redis 7 alpine for handling real-time task queuing and slot calculation caching.