π Live Demo Β· π Admin Portal Β· π Security Portal Β· π€ Visitor Portal
A production-ready, full-stack Visitor Management System featuring AI-powered assistance, multi-role access control, automated QR visitor passes, real-time analytics, and enterprise-grade security β deployed on Render cloud.
- Overview
- Live Demo
- Portal Architecture
- Key Features
- Tech Stack
- Project Structure
- API Reference
- Database Schema
- AI Assistant
- Security Model
- Environment Variables
- Local Setup
- Deployment
- Screenshots
- Author
VMS Ultra Pro is a comprehensive, enterprise-grade Visitor Management System built with Node.js and Express, featuring five independent role-based portals, an AI-powered assistant backed by Google Gemini, automated visitor pass generation with QR codes, real-time organizational analytics, and a multi-layer security architecture.
The system replaces paper-based visitor registers with a fully digital, auditable, and intelligent platform β deployed live on Render at https://vms-ultimator.onrender.com.
| Portal | URL | Role |
|---|---|---|
| π Homepage | vms-ultimator.onrender.com | Public |
| π΄ Admin | /admin | System Administrator |
| π DeptAdmin | /deptadmin | Department Head |
| π‘ Employee | /employee | Staff Member |
| π΅ Security | /security | Gate Officer |
| π’ Visitor | /visitor | External Guest |
Note: The Render free-tier server may take ~30 seconds to wake up on first request. A keep-alive ping mechanism is built-in (
public/js/vms-backend-wakeup.js) to minimize cold starts.
βββββββββββββββββββββββββββββββββββββββ
β VMS Ultra Pro β Render Cloud β
β https://vms-ultimator.onrender.com β
βββββββββββββββββββ¬ββββββββββββββββββββ
β Express.js REST API
βββββββββββββββββββββββββββββΌββββββββββββββββββββββββββββ
β β β β β
ββββββΌβββββ ββββββΌβββββ βββββββΌβββββ ββββββΌβββββ ββββββΌβββββ
β Admin β βDeptAdminβ β Employee β βSecurity β β Visitor β
β Portal β β Portal β β Portal β β Portal β β Portal β
ββββββ¬βββββ ββββββ¬βββββ βββββββ¬βββββ ββββββ¬βββββ ββββββ¬βββββ
β β β β β
βββββββββββββ΄ββββββββββββββββ΄ββββββββββββββββ΄βββββββββββββ
β
βββββββββββββΌββββββββββββ
β MySQL SQL Database β
β + Gemini AI Engine β
β + Cloudinary CDN β
β + Nodemailer SMTP β
βββββββββββββββββββββββββ
| Role | Access Level | Key Capabilities |
|---|---|---|
| Admin | Full System | Analytics, department management, DeptAdmin CRUD, visitor oversight, security alerts |
| DeptAdmin | Department Scope | Employee management, pass approval/rejection, schedules, password requests |
| Employee | Personal + Department | View assigned visits, flag visitor departure, department info, AI assistant |
| Security | Operational | QR code scanner, gate entry/exit logging, active pass management |
| Visitor | Self Only | Register (OTP + ID), request visits, download passes, track status |
- Multi-model fallback chain:
gemini-2.5-flashβgemini-2.0-flashβgemini-1.5-flashβgemini-flash-lite - ReAct SQL agent loop: AI autonomously queries the database (up to 3 round-trips) to answer live data questions
- Role-based data access: Each portal user only sees data scoped to their role (Visitor cannot see staff tables, Employee cannot see credential tables, etc.)
- 3000β4500 word deep responses for analytical queries; 70β120 words for quick questions
- Inline rendering: AI responses support
[IMG:url:alt],[NAV:label:url],[ACTION:label:event],[COPY:label:text]interactive tokens - Advanced Markdown β HTML parser with syntax-highlighted code blocks, tables, blockquotes, and nested lists
- JWT authentication with role-specific token keys (
adminToken,employeeToken, etc.) - Single-session enforcement: One active session per browser across all roles; cross-role login triggers an admin email alert
- Session expiry: 48-hour maximum lifetime + 18-hour inactivity auto-logout (
vms-session.js) - Password hashing: bcrypt with salt rounds
- 3-stage password recovery: Identity verification β Webcam face-scan simulation (OpenCV-style UI) β Request submission
- 6-digit OTP email verification for visitor registration and password reset
- Security lockout logging: Failed login attempts logged with device type, IP, and timestamp
- Auto-generated unique pass numbers
- QR code embedded on each pass (scannable by Security portal)
- PDF pass generated with PDFKit and attached to email
- Dynamic email links resolve correctly between localhost and Render production environments
- Pass lifecycle:
pendingβapprovedβchecked_inβchecked_out/rejected
- Total visitors, departments, employees, DeptAdmins
- Active pass count and visitor trends
- Department-wise statistics
- Security alert monitoring and resolution
- ID Proof OCR via Tesseract.js β auto-fills identity type and number during visitor registration
- Webcam face-match UI (retina scan β face contour β nose profile animation) for password recovery
- Mathematical responsive layout engine (
smart-media-responsive.js) - Dark / Light mode toggle with
data-themeCSS variables - Mobile-optimized sidebar navigation with swipe gesture support
- Canonical meta tags on all pages
robots.txtandsitemap.xmlpublished- Structured Open Graph tags
| Technology | Purpose |
|---|---|
| Node.js 18+ | Runtime environment |
| Express.js 5.x | REST API framework |
| MySQL 2 | Relational database driver |
| jsonwebtoken | JWT authentication |
| bcrypt | Password hashing |
| Nodemailer | Email delivery (Gmail SMTP) |
| Multer | File and image upload handling |
| PDFKit | Visitor pass PDF generation |
| QRCode | QR code PNG generation |
| Tesseract.js | OCR for identity document scanning |
| Cloudinary | Profile photo CDN storage |
| Axios | HTTP client for Gemini AI API |
| Helmet | Security headers middleware |
| express-rate-limit | API rate limiting |
| dotenvx | Encrypted environment variable management |
| Technology | Purpose |
|---|---|
| HTML5 + CSS3 | Markup and styling |
| Vanilla JavaScript | Client-side interactivity |
| Bootstrap Icons | Icon library |
| IndexedDB | Client-side session cache |
| HTML5 Canvas | Webcam capture for face verification |
| html5-qrcode | In-browser QR code scanning |
| Service | Role |
|---|---|
| Render.com | Cloud hosting + auto-deploy from GitHub |
| GitHub | Version control + CI/CD trigger |
| Cloudinary | Image CDN |
| Gmail SMTP | Transactional email |
VMS-Ultimator/
βββ server.js # Express app entry point, route mounting, static serving
βββ package.json
βββ render.yaml # Render deployment configuration
β
βββ config/
β βββ db.js # MySQL connection pool + utility methods
β
βββ controllers/
β βββ aiController.js # Gemini AI ReAct agent, RBAC SQL execution
β βββ adminAuthController.js # Admin login, OTP, password reveal
β βββ adminVisitorController.js # Dept/employee/visitor CRUD, analytics, pass management
β βββ deptAdminAuthController.js
β βββ deptAdminVisitorController.js
β βββ employeeAuthController.js
β βββ employeeVisitorController.js
β βββ securityAuthController.js
β βββ securityVisitorEmployeeController.js
β βββ visitorAuthController.js
β βββ visitorController.js
β βββ passwordRequestController.js
β
βββ routes/
β βββ adminRoutes.js # /api/admin/*
β βββ adminAuthRoutes.js # /api/admin/auth/*
β βββ adminVisitorRoutes.js # /api/admin/visitor/*
β βββ deptAdminRoutes.js # /api/deptadmin/*
β βββ employeeAuthRoutes.js # /api/employee/*
β βββ employeeVisitorRoutes.js # /api/employee/passes, /api/employee/departments
β βββ securityAuthRoutes.js # /api/security/*
β βββ securityRoutes.js # /api/security/passes
β βββ visitorAuthRoutes.js # /api/visitor/auth
β βββ visitorRoutes.js # /api/visitor/*
β βββ aiRoutes.js # /api/ai/generate
β βββ passwordRequestRoutes.js # /api/password-reset/*
β βββ publicRoutes.js # /api/public/visitor-pass/:passNumber
β
βββ middlewares/
β βββ validateAdminSession.js
β βββ validateDeptAdminSession.js
β βββ validateEmployeeSession.js
β βββ validateSecuritySession.js
β βββ validateVisitorSession.js
β
βββ services/
β βββ emailService.js # Nodemailer transport
β βββ cloudinaryService.js # Image upload to Cloudinary
β βββ pdfService.js # PDFKit visitor pass generation
β
βββ utils/
β βββ baseUrl.js # Dynamic base URL (localhost β Render)
β
βββ templates/
β βββ newRequestTemplate.js # HTML email template
β
βββ scripts/
β βββ vms-qrcode.png # Generated QR code β vms-ultimator.onrender.com
β
βββ public/
βββ index.html # Public homepage / portal dispatcher
βββ visitor-pass.html # Public visitor pass viewer (QR scan landing)
βββ robots.txt
βββ sitemap.xml
βββ vms.svg # VMS logo
β
βββ js/
β βββ vms-session.js # Centralized session manager (48h/18h rules)
β βββ ai-response-renderer.js # Markdown + HTML AI response parser
β βββ ai-widget.js # Floating AI chat widget
β βββ vms-backend-wakeup.js # Render keep-alive ping
β βββ custom-dialogs.js # Custom alert/confirm/prompt modals
β
βββ Admins/
β βββ index.html # Admin login
β βββ dashboard.html # Admin dashboard (analytics, depts, visitors, alerts)
β βββ department-info.html # Shared department detail view (Admin/DeptAdmin/Employee)
β
βββ DeptAdmin/
β βββ index.html # DeptAdmin login + 3-stage face-scan recovery
β βββ dashbaord.html # DeptAdmin dashboard
β
βββ Employee/
β βββ index.html # Employee login + face-scan recovery
β βββ dashbaord.html # Employee dashboard
β
βββ Security/
β βββ index.html # Security login
β βββ dashboard.html # Security dashboard + QR scanner
β βββ pass-visitor-detail.html # Pass detail view
β
βββ Visitor/
βββ index.html # Visitor register (4-step wizard) + login
βββ dashbaord.html # Visitor dashboard
| Method | Endpoint | Role | Description |
|---|---|---|---|
POST |
/api/admin/auth/login |
Admin | Admin login |
POST |
/api/deptadmin/login |
DeptAdmin | DeptAdmin login |
POST |
/api/employee/login |
Employee | Employee login |
POST |
/api/security/login |
Security | Security login |
POST |
/api/visitor/register-otp |
Public | Send registration OTP |
POST |
/api/visitor/register |
Public | Complete visitor registration |
POST |
/api/visitor/login |
Public | Visitor login |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/admin/analytics |
System analytics data |
GET |
/api/admin/departments |
List all departments |
GET |
/api/admin/departments/:dept_code/overview |
Department detail + staff |
POST |
/api/admin/departments |
Create department |
PUT |
/api/admin/departments/:dept_code |
Update department |
DELETE |
/api/admin/departments/:dept_code |
Delete department |
POST |
/api/admin/deptadmins |
Create DeptAdmin |
GET |
/api/admin/deptadmins |
List DeptAdmins |
GET |
/api/admin/visitors |
List all visitors |
POST |
/api/admin/visitors/:id/block |
Block/unblock visitor |
GET |
/api/admin/alerts |
Wrong-password alerts |
POST |
/api/admin/alerts/:id/resolve |
Resolve security alert |
GET |
/api/admin/departments-stats |
Dept-wise statistics |
GET |
/api/admin/visitor-logs |
Visitor activity logs |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/deptadmin/passes |
Pending visitor passes |
POST |
/api/deptadmin/passes/:id/approve |
Approve visitor pass |
POST |
/api/deptadmin/passes/:id/reject |
Reject visitor pass |
GET |
/api/deptadmin/employees |
List department employees |
POST |
/api/deptadmin/employees |
Create employee |
GET |
/api/deptadmin/schedules |
Department schedules |
GET |
/api/deptadmin/departments/:dept_code/overview |
Department overview |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/employee/departments |
All departments list |
GET |
/api/employee/departments/:dept_code/overview |
Department detail |
GET |
/api/employee/assigned-passes |
Passes assigned to employee |
POST |
/api/employee/pass/:passId/arrived |
Mark visitor arrived |
POST |
/api/employee/pass/:passId/flag-left |
Flag visitor as departed |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/security/passes/active |
All active passes |
POST |
/api/security/passes/:passNumber/checkin |
Check in visitor |
POST |
/api/security/passes/:passNumber/checkout |
Check out visitor |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/visitor/profile |
My profile |
POST |
/api/visitor/request-visit |
Request a visit |
GET |
/api/visitor/passes |
My passes |
GET |
/api/visitor/ocr |
OCR identity scan |
POST |
/api/visitor/forgot-password-otp |
Forgot password OTP |
POST |
/api/visitor/reset-password |
Reset password |
DELETE |
/api/visitor/delete-account |
Delete account |
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/ai/generate |
AI content generation (all actions + chat) |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/public/visitor-pass/:passNumber |
View pass publicly (QR scan) |
-- Core tables
CREATE TABLE departments (
dept_code VARCHAR(50) PRIMARY KEY,
dept_name VARCHAR(255) NOT NULL,
dept_location VARCHAR(255),
dept_profile TEXT
);
CREATE TABLE users (
PortalId VARCHAR(100) PRIMARY KEY,
EmpId VARCHAR(100) UNIQUE,
Name VARCHAR(255),
Email VARCHAR(255),
Contact VARCHAR(50),
dept VARCHAR(100),
Role VARCHAR(50), -- 'Employee' | 'Security'
is_first_login TINYINT DEFAULT 1,
is_blocked TINYINT DEFAULT 0,
blocked_reason VARCHAR(255),
photo_url VARCHAR(500)
);
CREATE TABLE deptAdmin (
PortalId VARCHAR(100) PRIMARY KEY,
EmpId VARCHAR(100) UNIQUE,
Name VARCHAR(255),
Email VARCHAR(255),
Contact VARCHAR(100),
dept VARCHAR(100),
is_first_login TINYINT DEFAULT 1,
is_blocked TINYINT DEFAULT 0,
blocked_reason VARCHAR(255),
photo_url VARCHAR(500)
);
CREATE TABLE visitors (
id INT AUTO_INCREMENT PRIMARY KEY,
visitor_id VARCHAR(50) UNIQUE, -- 8-digit public ID
full_name VARCHAR(255),
email VARCHAR(255),
contact_number VARCHAR(50),
purpose VARCHAR(255),
company_name VARCHAR(255),
designation VARCHAR(255),
is_blocked TINYINT DEFAULT 0,
blocked_reason VARCHAR(255),
photo_url VARCHAR(500)
);
CREATE TABLE visitor_passes (
id INT AUTO_INCREMENT PRIMARY KEY,
visitor_id INT, -- FK β visitors.id
pass_number VARCHAR(100) UNIQUE,
host_employee_name VARCHAR(255),
host_department VARCHAR(50),
status VARCHAR(50), -- pending|approved|rejected|checked_in|checked_out
check_in_time DATETIME,
check_out_time DATETIME,
pass_pdf_url VARCHAR(500),
host_flagged_left_time DATETIME
);
CREATE TABLE schedules (
id INT AUTO_INCREMENT PRIMARY KEY,
portal_id VARCHAR(100),
title VARCHAR(255),
date VARCHAR(100),
time VARCHAR(100),
description TEXT,
status VARCHAR(50),
remarks TEXT
);
CREATE TABLE wrong_password_attempt (
alert_id INT AUTO_INCREMENT PRIMARY KEY,
portal_id VARCHAR(100),
role VARCHAR(50),
timestampt DATETIME,
device_type VARCHAR(100),
ip_address VARCHAR(100),
action_trigger VARCHAR(255),
investigated_by VARCHAR(100)
);
CREATE TABLE password_requests (
id INT AUTO_INCREMENT PRIMARY KEY,
portal_id VARCHAR(100),
role VARCHAR(50),
status VARCHAR(50),
reason VARCHAR(255)
);
CREATE TABLE otps (
id INT AUTO_INCREMENT PRIMARY KEY,
email VARCHAR(255),
otp_code VARCHAR(10),
expires_at DATETIME,
purpose VARCHAR(100)
);
CREATE TABLE visitor_profile_updates (
id INT AUTO_INCREMENT PRIMARY KEY,
visitor_id INT,
old_details TEXT,
new_details TEXT
);
CREATE TABLE department_view_logs (
id INT AUTO_INCREMENT PRIMARY KEY,
viewer_id VARCHAR(100),
viewer_role VARCHAR(50),
dept_code VARCHAR(50),
viewed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);VMS Ultra Pro embeds a Google Gemini AI assistant inside every portal dashboard.
User Query (Chat)
β
THINK: Parse intent + role context
β
ACT: Generate SQL query [SQL: SELECT ...]
β
OBSERVE: Backend executes + returns JSON result
β
RESPOND: Compose comprehensive formatted response
β
(loops up to 3x for complex multi-step queries)
| Role | Tables Accessible | Write Access |
|---|---|---|
| Admin | All tables | Full CRUD |
| DeptAdmin | Department scope (no OTP table) | Department data only |
| Employee | Own passes + departments (no credentials) | Own schedules only |
| Security | Visitor passes + visitors (no staff tables) | Update pass status only |
| Visitor | Own visitor + pass records only | Read-only |
AI can embed interactive elements using tokens:
[IMG:https://cloudinary.com/.../photo.jpg:John's Profile Photo]
β Renders a circular profile photo with caption
[NAV:Go to Dashboard:/employee/dashboard]
β Renders a navigation button (relative paths supported)
[NAV:Visit Portal:https://vms-ultimator.onrender.com/admin]
β Renders an external link button
[ACTION:Approve Pass:approvePass]
β Renders a button that triggers a VMS frontend event
[COPY:Copy Portal ID:EMP-2024-001]
β Renders a copy-to-clipboard button
Layer 1: Infrastructure
βββ HTTPS enforced by Render
βββ Helmet.js security headers
βββ CORS policy with allowed origins
Layer 2: Database
βββ Parameterized queries (no SQL injection)
βββ bcrypt password hashing
Layer 3: Authentication
βββ Role-specific JWT tokens
βββ Middleware guards on every protected route
βββ Token expiry validation
Layer 4: Session Management (vms-session.js)
βββ Single active session per browser across all roles
βββ 48-hour maximum session lifetime
βββ 18-hour inactivity auto-logout
βββ Cross-role login β admin alert email
Layer 5: AI Security
βββ Role-scoped database access (RBAC)
βββ DDL commands blocked (no DROP/ALTER/TRUNCATE)
βββ Visitor write operations blocked entirely
Layer 6: OTP & Identity
βββ 6-digit time-limited OTP for registration and password reset
βββ Face-match UI for password recovery (3-stage)
Create a .env file in the project root with the following variables:
# Database
DB_HOST=your_mysql_host
DB_PORT=3306
DB_USER=your_db_user
DB_PASSWORD=your_db_password
DB_NAME=your_db_name
# Authentication
JWT_SECRET=your_super_secret_jwt_key_min_32_chars
# Email (Gmail SMTP)
EMAIL_USER=your_gmail@gmail.com
EMAIL_PASS=your_gmail_app_password
# Google Gemini AI
GEMINI_API_KEY=your_gemini_api_key
# Cloudinary (image storage)
CLOUDINARY_CLOUD_NAME=your_cloud_name
CLOUDINARY_API_KEY=your_cloudinary_api_key
CLOUDINARY_API_SECRET=your_cloudinary_api_secret
# Render deployment (auto-set by Render)
RENDER_EXTERNAL_URL=https://vms-ultimator.onrender.com
# App URL (for email links)
APP_URL=https://vms-ultimator.onrender.comSecurity Note: Never commit
.envto version control. Use.gitignore(already configured). For production, set these as environment variables directly in the Render dashboard.
- Node.js 18+
- MySQL 8.0+
- A Gmail account with App Password enabled
- A Cloudinary account (free tier works)
- A Google Gemini API key (get one here)
# 1. Clone the repository
git clone https://github.com/Aman-Kashyap-310304/VMS-Ultimator.git
cd VMS-Ultimator
# 2. Install dependencies
npm install
# 3. Set up environment variables
cp .env.example .env
# Fill in your values in .env
# 4. Set up the database
# Create a MySQL database and run the schema SQL from the Database Schema section above
# 5. Start the development server
npm run dev # uses nodemon for hot reload
# OR
npm start # production mode
# 6. Open in browser
# Homepage: http://localhost:3000
# Admin Portal: http://localhost:3000/admin
# DeptAdmin: http://localhost:3000/deptadmin
# Employee: http://localhost:3000/employee
# Security: http://localhost:3000/security
# Visitor: http://localhost:3000/visitorVMS Ultra Pro is deployed on Render.com with automatic deployments triggered on every push to main.
services:
- type: web
name: vms-ultimator
env: node
buildCommand: npm install
startCommand: node server.js
envVars:
- key: NODE_ENV
value: production- Fork this repository
- Create a new Web Service on Render
- Connect your forked GitHub repo
- Add all environment variables from the Environment Variables section
- Deploy β Render auto-installs dependencies and starts the server
Render free-tier instances sleep after 15 minutes of inactivity. The built-in vms-backend-wakeup.js script pings the server every 5 minutes from the browser client to prevent cold starts during active sessions.
Scan to open the live VMS Ultra Pro portal:
Scans to: https://vms-ultimator.onrender.com
| Commit | Description |
|---|---|
6310895 |
fix: logout clears all tokens + session meta; AI 3000β4500 word responses + RBAC + IMG token |
d446f61 |
fix: stabilize homepage, single session enforcement with 48h/18h rules & responsive mobile layout |
416ab7d |
feat: professional internal navigation bar, canonical SEO & Render keep-alive |
cda15d7 |
fix: remove GitHub Pages logic & optimize Render portal session auto-redirections |
This project is licensed under the ISC License β see the LICENSE file for details.
Made with β€οΈ by Aman Kashyap
β Star this repo if you found it useful!