An intelligent support ticket management system powered by AI that streamlines customer support workflows with smart ticket routing, automated analysis, and role-based access control.
- Intelligent Ticket Management: Create, track, and resolve support tickets efficiently
- AI-Powered Analysis: Automatic ticket categorization and suggested responses
- Role-Based Access Control: Support for Users, Moderators, and Admins
- Skills-Based Assignment: Match tickets with moderators based on expertise
- Real-time Updates: Live ticket status updates and notifications
- Responsive Design: Works seamlessly on desktop and mobile devices
- Users: Submit tickets, track progress, communicate with support
- Moderators: Handle tickets, provide support, manage resolutions (with skill-based matching)
- Admins: Full system access, user management, analytics
- Homepage Landing Page: Public homepage with clear signup/signin buttons for new users
- Role Selection During Signup: Users can choose to become regular users or moderators
- Skills Management: Moderators can add their expertise areas during signup
- Self-Service Profile Management: Moderators can update their skills anytime after account creation
- Post-Signup Profile Setup: New moderators are guided to set up their profile after registration
- Enhanced Navigation: Improved navbar with better button visibility and user experience
- About Page: Comprehensive information about the platform and its features
- Mobile-Optimized Interface: Enhanced mobile navigation and responsive design
- Intelligent Skills-Based Assignment: Tickets automatically matched to moderators based on skills
- API Retry Logic: Frontend automatically retries failed requests for better reliability
- Framework: React 18+ with Vite
- Styling: Tailwind CSS with custom components
- State Management: React Hooks
- Routing: React Router DOM v6
- Build Tool: Vite with hot reload
- React 18+ with functional components and hooks
- Vite for fast development and optimized builds
- Tailwind CSS for utility-first styling
- DaisyUI for pre-built component themes
- React Router DOM v6 for client-side routing
- Custom API client with automatic retry logic and error handling
- Safe storage utilities with localStorage fallbacks for reliability
- Node.js with Express.js framework
- MongoDB with Mongoose ODM for data modeling
- JWT (jsonwebtoken) for secure authentication
- Bcrypt for password hashing and security
- CORS middleware for cross-origin request handling
- Inngest for event-driven architecture and background jobs
- Custom AI integration for ticket analysis and suggestions
- ESLint for code quality and consistency
- Vite HMR for instant development feedback
- Git for version control
- Render for backend deployment
- Netlify for frontend deployment and CDN
- Node.js 18+ and npm
- MongoDB database
- Git
cd ai-ticket-assistant
npm install
cp .env.example .env # Configure your environment variables
npm start # Runs on http://localhost:4000cd ai-ticket-frontend
npm install
npm run dev # Runs on http://localhost:5173# Backend (.env)
MONGODB_URI=your_mongodb_connection_string
ACCESS_TOKEN_SECRET=your_jwt_secret
INNGEST_EVENT_KEY=your_inngest_key
OPENAI_API_KEY=your_openai_key # For AI features
# Frontend (automatically detected)
VITE_API_URL=http://localhost:4000/api # For development- Frontend: https://aiagentticket.netlify.app
- Backend API: https://ticketmate-ai.onrender.com/api
- Health Check: https://ticketmate-ai.onrender.com/health
# Frontend (.env.production or Netlify Environment)
VITE_API_URL=https://ticketmate-ai.onrender.com/api
VITE_SERVER_URL=https://ticketmate-ai.onrender.com/api
# Backend (Render Environment Variables)
MONGO_URL=your_production_mongodb_uri
ACCESS_TOKEN_SECRET=your_production_jwt_secret
CLIENT_URL=https://aiagentticket.netlify.app
SERVER_PORT=4000
NODE_ENV=productionThe backend is configured to accept requests from:
- Local development:
http://localhost:5173,http://localhost:3000 - Production:
https://aiagentticket.netlify.app,https://ticketmate-ai.netlify.app
- Backend (Render): Auto-deploys from main branch
- Frontend (Netlify): Auto-deploys from main branch with build command
npm run build
- Visit homepage → Click "Get Started" or "Sign Up"
- Choose role (User/Moderator) during signup
- If Moderator: Automatically redirected to profile page to add skills
- If User: Redirected to tickets dashboard to create first ticket
- Login → Navigate to "Profile" in navbar
- Add Skills: Type skill name and press Enter or click "Add Skill"
- Remove Skills: Click × on any skill tag to remove
- Save Changes: Skills are automatically saved and persist across sessions
- Skills Usage: Added skills are used for intelligent ticket assignment
- User creates ticket → AI automatically analyzes and generates helpful notes
- Auto-assignment to moderator based on skills match and availability
- Moderator handles ticket → Can use AI-suggested replies for faster responses
- Resolution tracking → Status updates, user notifications, resolution time tracking
- Development:
http://localhost:4000/api - Production:
https://ticketmate-ai.onrender.com/api
All protected endpoints require a Bearer token in the Authorization header:
Authorization: Bearer <token>
{
_id: string
email: string
password: string (hashed)
role: "user" | "moderator" | "admin"
skills?: string[]
createdAt: Date
updatedAt: Date
}{
_id: string
title: string
description: string
status: "TODO" | "open" | "in-progress" | "resolved" | "closed" | "cancelled"
priority?: "low" | "medium" | "high"
createdBy: User | string
assignedTo?: User | string
assignedAt?: Date
resolvedAt?: Date
helpfulNotes?: string // AI-generated analysis
replyCanbeGiven?: string[] // AI-suggested replies
relatedSkills?: string[]
tags?: string[]
replies: Reply[]
createdAt: Date
updatedAt: Date
}{
message: string;
author: User | string;
createdAt: Date;
}Create a new user account with role selection and optional skills.
Request Body:
{
"email": "user@example.com",
"password": "password123",
"role": "user", // "user" or "moderator" (default: "user")
"skills": ["JavaScript", "Customer Support", "Network Administration"] // optional, for moderators
}Response:
{
"token": "jwt_token_here",
"user": {
"_id": "user_id",
"email": "user@example.com",
"role": "user",
"skills": [],
"createdAt": "2024-01-01T00:00:00.000Z"
},
"message": "User created successfully"
}Status Codes:
201- User created successfully400- Invalid input data (invalid email, weak password, invalid role, invalid skills format)409- User already exists
Validation Rules:
- Email must be valid format
- Password must be at least 6 characters
- Role must be "user" or "moderator"
- Skills must be an array of non-empty strings (optional)
Authenticate user and get access token.
Request Body:
{
"email": "user@example.com",
"password": "password123"
}Response:
{
"token": "jwt_token_here",
"user": {
"_id": "user_id",
"email": "user@example.com",
"role": "user"
}
}Status Codes:
200- Login successful401- Invalid credentials400- Invalid input data
Update current user's profile (skills). New Feature: Self-Service Profile Management
Headers:
Authorization: Bearer <token>
Request Body:
{
"skills": ["JavaScript", "React", "Customer Support", "Database Management"]
}Response:
{
"message": "Profile updated successfully",
"user": {
"_id": "user_id",
"email": "user@example.com",
"role": "moderator",
"skills": ["JavaScript", "React", "Customer Support", "Database Management"],
"updatedAt": "2024-01-01T00:00:00.000Z"
}
}Status Codes:
200- Profile updated successfully400- Invalid skills format (must be array)401- Unauthorized (token required)500- Server error
Notes:
- Only authenticated users can update their own profile
- Skills array will completely replace existing skills
- Empty array is allowed to remove all skills
- Moderators can use this for self-service skills management
Get all users (Admin only).
Headers:
Authorization: Bearer <admin_token>
Response:
{
"users": [
{
"_id": "user_id",
"email": "user@example.com",
"role": "user",
"skills": ["JavaScript", "React"],
"createdAt": "2024-01-01T00:00:00.000Z"
}
]
}Status Codes:
200- Success401- Unauthorized403- Forbidden (non-admin)
Update user role and skills (Admin only).
Headers:
Authorization: Bearer <admin_token>
Request Body:
{
"email": "user@example.com",
"role": "moderator",
"skills": ["JavaScript", "React", "Node.js"]
}Response:
{
"message": "User updated successfully",
"user": {
"_id": "user_id",
"email": "user@example.com",
"role": "moderator",
"skills": ["JavaScript", "React", "Node.js"]
}
}Status Codes:
200- User updated successfully401- Unauthorized403- Forbidden (non-admin)404- User not found
Get all tickets for the authenticated user.
Headers:
Authorization: Bearer <token>
Response:
[
{
"_id": "ticket_id",
"title": "Login issue",
"description": "Cannot login to the application",
"status": "open",
"priority": "high",
"createdBy": {
"_id": "user_id",
"email": "user@example.com"
},
"assignedTo": null,
"helpfulNotes": "AI analysis of the issue...",
"replyCanbeGiven": [
"Have you tried clearing your browser cache?",
"Please check if your account is locked."
],
"relatedSkills": ["Authentication", "Frontend"],
"replies": [],
"createdAt": "2024-01-01T00:00:00.000Z",
"updatedAt": "2024-01-01T00:00:00.000Z"
}
]Status Codes:
200- Success401- Unauthorized
Create a new ticket.
Headers:
Authorization: Bearer <token>
Request Body:
{
"title": "Login issue",
"description": "I cannot login to the application. Getting error message."
}Response:
{
"_id": "ticket_id",
"title": "Login issue",
"description": "I cannot login to the application. Getting error message.",
"status": "open",
"createdBy": "user_id",
"helpfulNotes": "AI-generated analysis...",
"replyCanbeGiven": ["Suggested reply 1", "Suggested reply 2"],
"relatedSkills": ["Authentication"],
"createdAt": "2024-01-01T00:00:00.000Z"
}Status Codes:
201- Ticket created successfully400- Invalid input data401- Unauthorized
Get a specific ticket by ID.
Headers:
Authorization: Bearer <token>
Response:
{
"ticket": {
"_id": "ticket_id",
"title": "Login issue",
"description": "Cannot login to the application",
"status": "open",
"createdBy": {
"_id": "user_id",
"email": "user@example.com"
},
"assignedTo": {
"_id": "moderator_id",
"email": "mod@example.com",
"role": "moderator"
},
"helpfulNotes": "AI analysis...",
"replyCanbeGiven": ["Suggested replies..."],
"replies": [
{
"message": "We're looking into this issue.",
"author": {
"_id": "moderator_id",
"email": "mod@example.com",
"role": "moderator"
},
"createdAt": "2024-01-01T01:00:00.000Z"
}
],
"createdAt": "2024-01-01T00:00:00.000Z"
}
}Status Codes:
200- Success401- Unauthorized403- Forbidden (not authorized to view)404- Ticket not found
Update ticket assignment (Moderators/Admins only).
Headers:
Authorization: Bearer <moderator_token>
Request Body:
{
"assignedTo": "moderator_user_id"
}Response:
{
"message": "Ticket updated successfully",
"ticket": {
"_id": "ticket_id",
"assignedTo": "moderator_user_id",
"assignedAt": "2024-01-01T02:00:00.000Z"
}
}Status Codes:
200- Ticket updated successfully401- Unauthorized403- Forbidden (not a moderator/admin)404- Ticket not found
Add a reply to a ticket.
Headers:
Authorization: Bearer <token>
Request Body:
{
"message": "Thank you for the help! The issue is resolved.",
"status": "resolved" // Optional: Update ticket status
}Response:
{
"message": "Reply added successfully",
"reply": {
"message": "Thank you for the help! The issue is resolved.",
"author": "user_id",
"createdAt": "2024-01-01T03:00:00.000Z"
},
"ticket": {
"_id": "ticket_id",
"status": "resolved" // If status was updated
}
}Status Codes:
201- Reply added successfully400- Invalid input data401- Unauthorized403- Forbidden (not authorized to reply)404- Ticket not found
Update ticket status (Moderators/Admins only).
Headers:
Authorization: Bearer <moderator_token>
Request Body:
{
"status": "resolved"
}Response:
{
"message": "Ticket status updated successfully",
"ticket": {
"_id": "ticket_id",
"status": "resolved",
"resolvedAt": "2024-01-01T04:00:00.000Z"
}
}Status Codes:
200- Status updated successfully401- Unauthorized403- Forbidden (not a moderator/admin)404- Ticket not found
All error responses follow this format:
{
"error": "Error message",
"message": "Detailed error description"
}200- OK201- Created400- Bad Request401- Unauthorized403- Forbidden404- Not Found409- Conflict500- Internal Server Error
Frontend expects these environment variables:
VITE_SERVER_URL- Backend API URLVITE_API_URL- Alternative API URL
The system includes AI-powered features:
- AI Analysis (
helpfulNotes): Automatically generated insights about the ticket - AI Suggested Replies (
replyCanbeGiven): Pre-written response suggestions for moderators - Skill Detection (
relatedSkills): Automatically detected skills related to the ticket
These AI features are populated when creating tickets and help moderators provide better support.
- All dates are in ISO 8601 format
- User roles:
user(default),moderator,admin - Ticket statuses:
TODO,open,in-progress,resolved,closed,cancelled - The frontend uses React with Tailwind CSS and DaisyUI
- Authentication uses JWT tokens
- Storage uses safe localStorage with fallbacks
- Check browser console for JavaScript errors
- Verify API URL in environment variables (should point to backend)
- Ensure backend server is running and accessible
- Clear browser cache and cookies to remove stale data
- Check network tab for failed API requests
Access to fetch at '...' has been blocked by CORS policy
Solutions:
- Verify
CLIENT_URLenvironment variable is set correctly on backend - Check if backend server is awake (Render free tier sleeps after 15 minutes)
- Test backend health endpoint:
https://ticketmate-ai.onrender.com/health - Ensure frontend domain is in CORS origins list
- Check network tab for failed requests (401, 500 errors)
- Verify backend deployment status in Render dashboard
- Test with development environment first (
localhost:4000) - Check if MongoDB is connected via health endpoint
- Validate JWT secret is set in production environment
- Skills not saving: Check browser console for API errors
- Profile page not loading: Verify user is authenticated and has valid token
- Skills not appearing: Check if API response includes skills array
- Server sleeping: Visit health endpoint to wake up server
- Deployment failed: Check Render logs for build/runtime errors
- Database connection: Verify
MONGO_URLenvironment variable - Environment variables missing: Ensure all required vars are set in Render
- Use
npm run dev -- --hostto test frontend on mobile devices - Backend logs are available in Render dashboard under "Logs" tab
- Frontend build logs available in Netlify deployment section
- Use browser dev tools Network tab to debug API calls
- Test API endpoints directly with tools like Postman or curl
- Frontend bundle analysis: Run
npm run buildand check dist folder size - API response times: Monitor slow endpoints in production
- Database queries: Use MongoDB indexes for frequently queried fields
- Image optimization: Compress and serve images in modern formats
- JWT tokens stored securely in localStorage with fallback handling
- Password hashing with bcrypt (salt rounds: 12)
- Role-based access control (RBAC) for API endpoints
- Protected routes prevent unauthorized access
- Input validation and sanitization on all endpoints
- CORS configuration prevents unauthorized cross-origin requests
- Environment variables for sensitive configuration
- MongoDB connection with authentication enabled
- All environment variables set securely
- CORS origins restricted to known domains
- JWT secret is strong and unique
- Database connection uses authentication
- HTTPS enabled for all production traffic
- Error messages don't expose sensitive information
- MongoDB connection pooling for efficient database access
- JWT token validation caching
- CORS preflight optimization
- Request retry logic with exponential backoff (frontend)
- API response compression
- Vite hot module replacement (HMR) for fast development
- Code splitting and tree shaking for optimized bundles
- Lazy loading of non-critical components
- Responsive images and modern image formats
- Tailwind CSS purging for minimal CSS bundle size
- Backend health endpoint for uptime monitoring
- Error logging and performance tracking
- User activity and engagement metrics
- API response time monitoring
- Database query performance analysis