A production-grade, full-stack on-demand home services marketplace — inspired by Urban Company / Housejoy.
Customers discover and book local services. Providers manage orders, earnings, and subscriptions.
Admins oversee the entire platform through a powerful analytics dashboard.
- Overview
- Key Features
- Tech Stack
- Architecture
- Project Structure
- Database Schema
- API Endpoints
- Getting Started
- Environment Variables
- Deployment
- Security
- License
ServeFlow is a full-featured service marketplace platform that connects customers looking for home services (plumbing, cleaning, AC repair, electrical work, gardening, etc.) with vetted service providers — all managed through an admin panel with real-time analytics.
The system is split into two independently deployable units:
| Layer | Stack | Port |
|---|---|---|
| Frontend | React 19 + Vite 6 + TailwindCSS 4 | 3000 |
| Backend | Express 4 + MongoDB + Socket.IO | 5000 |
- JWT-based authentication with HTTP-only cookie support
- Bearer token fallback for API clients
- Role-based access control — Admin, Customer, Provider
- OTP-based password reset via email
- Account lockout after failed login attempts
- Suspended/pending account enforcement at middleware level
- Multi-role registration (customer & provider flows)
- Avatar upload via Multer → Cloudinary pipeline
- Multiple saved addresses with geolocation validation (lat/lng/accuracy)
- Provider-specific fields: bio, category, availability, service images, live location
- Admin can edit, suspend, or delete any user
- Admin CRUD for service categories (name, description, icon)
- Providers create/edit services with pricing, duration, images, and status
- Multi-image uploads (primary + extra gallery images)
- Service-level ratings aggregated from reviews
Full workflow-driven booking system with granular status tracking:
Pending → Accepted → Confirmed → In Progress → Awaiting OTP → Completed
↓
Cancelled
Disputed → Resolved
- Address validation with geolocation on booking
- OTP verification for service completion (start OTP + completion OTP)
- Before/after photo evidence for service documentation
- Start location tracking for provider arrival verification
- Dispute system with reason, description, image evidence, provider replies, and admin resolution
- Razorpay payment integration for online payments
- PDF invoice generation via PDFKit
- Five-star overall rating + category breakdowns (professionalism, communication, punctuality)
- Image attachments on reviews
- Provider reply capability
- Helpful vote system with user tracking
- Verified review badges
- Automatic provider rating recalculation via cron jobs
- In-app wallet for customers and providers
- Razorpay integration for wallet top-ups and booking payments
- Transaction history with full audit trail (balance before/after)
- Transaction types: credit, debit, refund
- Payment methods: Razorpay, wallet, admin credit, refund
- Admin-controlled promotional discounts (configurable %)
- Wallet lock/unlock by admin
- Tiered plans: Starter → Growth → Pro → Infinity I/II/III
- Monthly, yearly, and lifetime billing cycles
- Commission rate varies by plan (default 18%)
- Scheduled plan upgrades (activate after current plan expires)
- Auto-expiry via cron jobs
- Admin override with notes
- Socket.IO powered real-time messaging
- Text, image, video, audio, and document attachments
- Message editing and deletion (delete for me / delete for all)
- Reply-to-message threading
- Read receipts with real-time notification
- Available across all three portals (Customer, Provider, Admin)
- Baileys (WhatsApp Web API) integration for automated notifications
- Booking confirmations, status updates, and OTP delivery via WhatsApp
- QR code-based authentication page at
/qr.html
- Nodemailer powered transactional emails
- OTP delivery for password reset
- Booking confirmations and status updates
- Providers can set leave by specific dates or recurring days
- Time-slot-level granularity (block specific hours)
- Prevents booking conflicts automatically
| Role | Metrics |
|---|---|
| Admin | Total users, bookings, earnings, monthly revenue charts, booking trends |
| Provider | Pending/completed requests, active services, net revenue, commission |
- Admin report generation with date-range filters
- Booking and revenue analytics
- CSV export capability
- In-app notification inbox with read/unread status
- Real-time push via Socket.IO
- Notification center in both customer and provider portals
- Dark/Light theme toggle with persistence
- Framer Motion page transitions and micro-animations
- Ant Design + Material UI component libraries
- Recharts powered analytics charts
- Loading skeletons for better perceived performance
- Error boundary for graceful failure handling
- Fully responsive design
| Technology | Purpose |
|---|---|
| React 19 | UI framework |
| Vite 6 | Build tool & dev server |
| TailwindCSS 4 + DaisyUI | Utility-first styling |
| Framer Motion | Animations & transitions |
| Ant Design + MUI | UI component libraries |
| React Hook Form + Zod | Form handling & validation |
| TanStack React Query | Server state management |
| Redux Toolkit | Client state management |
| Recharts | Data visualization |
| Axios | HTTP client |
| Socket.IO Client | Real-time communication |
| Lucide / Heroicons / React Icons | Iconography |
| jsPDF + html2canvas | Client-side PDF generation |
| Google GenAI SDK | AI-powered features |
| Technology | Purpose |
|---|---|
| Express 4 | REST API framework |
| Mongoose 8 | MongoDB ODM |
| Socket.IO 4 | WebSocket server |
| JWT + bcryptjs | Authentication & hashing |
| Razorpay SDK | Payment gateway |
| Cloudinary | Cloud image storage |
| Multer | File upload handling |
| Nodemailer | Email service |
| Baileys | WhatsApp Web API |
| PDFKit | Server-side PDF generation |
| node-cron | Scheduled tasks |
| Helmet + XSS-Clean + HPP | Security headers & sanitization |
| express-rate-limit | API rate limiting |
| express-mongo-sanitize | NoSQL injection prevention |
| Morgan + Winston + Pino | Logging |
| BullMQ + Redis | Job queue (available) |
┌────────────────────────────┐ ┌────────────────────────────────┐
│ FRONTEND (Vite) │ │ BACKEND (Express) │
│ │ HTTP │ │
│ React 19 SPA │◄───────►│ REST API (/api/*) │
│ TailwindCSS + DaisyUI │ Proxy │ Socket.IO (real-time chat) │
│ Framer Motion Animations │ │ Cron Jobs (reviews, subs) │
│ Recharts Dashboards │ │ │
└────────────────────────────┘ └───────────┬────────────────────┘
│
┌─────────────────────┼──────────────────────┐
│ │ │
┌─────▼─────┐ ┌──────▼──────┐ ┌──────▼──────┐
│ MongoDB │ │ Cloudinary │ │ Razorpay │
│ Atlas │ │ (Media CDN) │ │ (Payments) │
└───────────┘ └─────────────┘ └─────────────┘
│
┌────────┴────────┐
│ WhatsApp │
│ (Baileys) │
└─────────────────┘
serveflow/
├── backend/
│ ├── controllers/ # Business logic layer
│ │ ├── authController.js # Login, register, OTP, password reset
│ │ ├── bookingController.js # Booking CRUD, status transitions, disputes, OTP
│ │ ├── categoryController.js # Category CRUD (admin)
│ │ ├── chatController.js # Message CRUD, conversations
│ │ ├── leaveController.js # Provider leave/availability management
│ │ ├── notificationController.js # Notification CRUD, mark read
│ │ ├── reportController.js # Admin reports & analytics
│ │ ├── reviewController.js # Review CRUD, votes, provider replies
│ │ ├── serviceController.js # Service CRUD for providers
│ │ ├── settingController.js # Admin global settings (promo config)
│ │ ├── subscriptionController.js # Subscription plans, activation, scheduling
│ │ ├── userController.js # User profile updates, admin user management
│ │ └── walletController.js # Wallet operations, Razorpay integration
│ │
│ ├── middleware/
│ │ ├── authMiddleware.js # JWT verification, role guards (protect, adminOnly, providerOnly)
│ │ ├── errorMiddleware.js # Global error handler & 404 handler
│ │ ├── roleMiddleware.js # Additional role-based checks
│ │ ├── uploadMiddleware.js # Multer configuration for file uploads
│ │ └── walletMiddleware.js # Wallet balance validation
│ │
│ ├── models/ # Mongoose schemas (13 collections)
│ │ ├── AdminSetting.js # Global config (promo settings)
│ │ ├── AuditLog.js # Action tracking for admin oversight
│ │ ├── Booking.js # Booking with dispute, OTP, evidence fields
│ │ ├── Category.js # Service categories
│ │ ├── Message.js # Chat messages (text, media, replies)
│ │ ├── Notification.js # In-app notifications
│ │ ├── Otp.js # OTP records for verification
│ │ ├── ProviderLeave.js # Provider leave/unavailability
│ │ ├── Review.js # Reviews with category ratings & votes
│ │ ├── Service.js # Provider services
│ │ ├── Subscription.js # Provider subscription plans
│ │ ├── User.js # Users (customer, provider, admin)
│ │ └── WalletTransaction.js # Wallet transaction ledger
│ │
│ ├── routes/ # Express route definitions (14 route files)
│ │ ├── authRoutes.js # /api/auth/*
│ │ ├── bookingRoutes.js # /api/bookings/*
│ │ ├── categoryRoutes.js # /api/categories/*
│ │ ├── chatRoutes.js # /api/chat/*
│ │ ├── leaveRoutes.js # /api/leaves/*
│ │ ├── notificationRoutes.js # /api/notifications/*
│ │ ├── reportRoutes.js # /api/reports/*
│ │ ├── reviewRoutes.js # /api/reviews/*
│ │ ├── serviceRoutes.js # /api/services/*
│ │ ├── settingRoutes.js # /api/settings/*
│ │ ├── subscriptionRoutes.js # /api/subscriptions/*
│ │ ├── uploadRoutes.js # /api/upload/*
│ │ ├── userRoutes.js # /api/users/*
│ │ └── walletRoutes.js # /api/wallet/*
│ │
│ ├── utils/ # Utility services
│ │ ├── cloudinaryUploader.js # Cloudinary SDK wrapper
│ │ ├── emailService.js # Nodemailer transactional emails
│ │ ├── pdfService.js # PDFKit invoice generation
│ │ ├── reviewCronJobs.js # Scheduled review rating recalculation
│ │ ├── subscriptionCron.js # Subscription auto-expiry & plan rotation
│ │ └── whatsappService.js # Baileys WhatsApp integration
│ │
│ ├── uploads/ # Local file uploads (gitignored)
│ ├── baileys_auth_info/ # WhatsApp session data (gitignored)
│ ├── server.js # App entry point, middleware, Socket.IO setup
│ ├── syncWallets.js # One-time wallet sync migration script
│ ├── qr.html # WhatsApp QR code scan page
│ ├── package.json
│ ├── nodemon.json
│ └── vercel.json # Vercel serverless deployment config
│
├── frontend/
│ ├── src/
│ │ ├── api/ # API client layer (16 modules)
│ │ │ ├── apiClient.js # Axios instance with base config
│ │ │ ├── config.js # API URL configuration
│ │ │ ├── db.js # Client-side DB initialization
│ │ │ ├── authApi.js # Auth endpoints (login, register, OTP)
│ │ │ ├── bookingApi.js # Booking CRUD & status operations
│ │ │ ├── categoryApi.js # Category fetch
│ │ │ ├── chatApi.js # Chat message operations
│ │ │ ├── leaveApi.js # Provider leave management
│ │ │ ├── notificationApi.js # Notification endpoints
│ │ │ ├── providerApi.js # Provider-specific queries
│ │ │ ├── reportApi.js # Admin report endpoints
│ │ │ ├── reviewApi.js # Review CRUD & votes
│ │ │ ├── serviceApi.js # Service CRUD
│ │ │ ├── settingApi.js # Admin settings
│ │ │ ├── subscriptionApi.js # Subscription endpoints
│ │ │ └── userApi.js # User profile operations
│ │ │
│ │ ├── components/ # Shared UI components
│ │ │ ├── ErrorBoundary.jsx # React error boundary
│ │ │ └── Skeleton.jsx # Loading skeleton placeholders
│ │ │
│ │ ├── layouts/ # Shell layouts per role
│ │ │ ├── MainLayout.jsx # Customer navigation shell
│ │ │ ├── MainLayout.css
│ │ │ ├── AdminLayout.jsx # Admin sidebar + topbar shell
│ │ │ ├── ProviderLayout.jsx # Provider sidebar + topbar shell
│ │ │ └── ProviderLayout.css
│ │ │
│ │ ├── pages/
│ │ │ ├── auth/ # Authentication pages
│ │ │ │ ├── Login.jsx
│ │ │ │ ├── Registration.jsx
│ │ │ │ ├── ForgotPassword.jsx
│ │ │ │ └── ResetPassword.jsx
│ │ │ │
│ │ │ ├── customer/ # Customer-facing pages (14 files)
│ │ │ │ ├── Home.jsx # Landing page with featured services
│ │ │ │ ├── HowItWorks.jsx # Onboarding guide
│ │ │ │ ├── OurServices.jsx # Service catalog with search & filters
│ │ │ │ ├── Services.jsx # Service detail & booking flow
│ │ │ │ ├── Bookings.jsx # Booking history & management
│ │ │ │ ├── Profile.jsx # Profile & address management
│ │ │ │ ├── Wallet.jsx # Wallet balance & transactions
│ │ │ │ ├── Chat.jsx # In-app messaging
│ │ │ │ ├── Notifications.jsx
│ │ │ │ ├── Support.jsx # Help & support center
│ │ │ │ ├── Terms.jsx # Terms of service
│ │ │ │ └── Privacy.jsx # Privacy policy
│ │ │ │
│ │ │ ├── provider/ # Provider dashboard pages (10 pages)
│ │ │ │ ├── Dashboard.jsx # Analytics overview with charts
│ │ │ │ ├── Requests.jsx # Incoming booking requests
│ │ │ │ ├── Bookings.jsx # Active bookings management
│ │ │ │ ├── ServiceOrders.jsx # Order lifecycle management
│ │ │ │ ├── ServiceProfile.jsx # Service portfolio editor
│ │ │ │ ├── Reviews.jsx # Review management & replies
│ │ │ │ ├── Wallet.jsx # Earnings & payouts
│ │ │ │ ├── Chat.jsx # Customer communication
│ │ │ │ ├── Notifications.jsx
│ │ │ │ └── SubscriptionPlans.jsx # Plan selection & management
│ │ │ │
│ │ │ └── admin/ # Admin panel pages (8 pages)
│ │ │ ├── Dashboard.jsx # Platform-wide analytics
│ │ │ ├── Users.jsx # User management (CRUD, suspend, block)
│ │ │ ├── Bookings.jsx # All bookings oversight & disputes
│ │ │ ├── Services.jsx # Service catalog management
│ │ │ ├── Reports.jsx # Revenue & performance reports
│ │ │ ├── Wallet.jsx # Platform wallet & transactions
│ │ │ ├── Chat.jsx # Admin messaging
│ │ │ └── Settings.jsx # Global platform settings
│ │ │
│ │ ├── utils/
│ │ │ └── timeUtils.js # Date/time formatting helpers
│ │ │
│ │ ├── App.jsx # Root component, routing, auth state
│ │ ├── main.jsx # React DOM entry point
│ │ └── index.css # Global styles
│ │
│ ├── index.html # HTML template
│ ├── tailwind.config.cjs # Tailwind configuration
│ ├── vite.config.js # Vite config with API proxy
│ ├── package.json
│ └── vercel.json # Frontend deployment rewrites
│
├── .gitignore
└── README.md
The application uses 13 MongoDB collections via Mongoose:
| Field | Type | Description |
|---|---|---|
id |
String (unique) | Custom unique identifier |
name |
String | Full name |
email |
String (unique) | Email address |
mobile |
String (unique) | Phone number |
password |
String | Bcrypt hashed password |
role |
Enum | customer | provider | admin |
status |
Enum | active | suspended | pending |
avatar |
String | Cloudinary image URL |
category |
String | Provider's service category |
rating |
Number | Provider's average rating (default: 5.0) |
walletBalance |
Number | In-app wallet balance |
savedAddresses |
Array | Multiple addresses with geolocation |
isAvailable |
Boolean | Provider availability toggle |
availableTimeSlots |
[String] | Provider working hours |
location |
Object | { lat, lng, address } for live tracking |
| Field | Type | Description |
|---|---|---|
id |
String (unique) | Booking identifier |
customerId / providerId |
String | Linked user IDs |
serviceId / serviceName |
String | Booked service reference |
date / time |
String | Scheduled date and time slot |
status |
Enum | pending → accepted → confirmed → in progress → awaiting_otp → completed / cancelled / disputed / resolved |
totalPrice |
Number | Booking amount |
razorpayOrderId |
String | Payment reference |
startOtp / completionOtp |
String | OTP codes for verification |
beforeImages / afterImages |
[String] | Service evidence photos |
dispute |
Object | Full dispute lifecycle (reason, images, replies, admin decision) |
| Field | Type | Description |
|---|---|---|
id |
String (unique) | Service identifier |
providerId |
String | Owner provider |
idCategory |
String | Category reference |
name / description |
String | Service details |
price |
Number | Service price |
duration |
Number | Duration in minutes |
image / extraImages |
String / [String] | Media gallery |
rating / reviewsCount |
Number | Aggregated review data |
| Field | Type | Description |
|---|---|---|
providerId |
String (unique) | Provider reference |
plan |
Enum | starter | growth | pro | infinity_i/ii/iii | none |
billingCycle |
Enum | monthly | yearly | lifetime | none |
commissionRate |
Number | Platform fee % (default: 18%) |
status |
Enum | active | expired | cancelled | none |
scheduledPlan |
String | Queued next plan |
| Field | Type | Description |
|---|---|---|
userId |
String | Transaction owner |
bookingId |
String | Related booking (optional) |
amount |
Number | Transaction amount |
transactionType |
Enum | credit | debit | refund |
paymentMethod |
Enum | razorpay | wallet | admin | refund |
balanceBefore / balanceAfter |
Number | Audit trail |
| Collection | Purpose |
|---|---|
| Categories | Service categories (name, description, icon, status) |
| Reviews | Ratings with category breakdowns, images, provider replies, helpful votes |
| Messages | Chat messages (text + media), edit history, delete tracking, read receipts |
| Notifications | In-app notification inbox (userId, message, type, isRead) |
| Otp | OTP records for password reset & verification |
| ProviderLeave | Leave management (by date or day, with time slot granularity) |
| AdminSetting | Global platform config (promo toggle, discount %, max bookings) |
| AuditLog | Admin action tracking (userId, action, resource, details, IP) |
All endpoints are prefixed with /api and protected by rate limiting (2000 requests / 15 minutes per IP).
| Prefix | Description | Auth Required |
|---|---|---|
/api/auth |
Login, register, logout, OTP, password reset | Partial |
/api/users |
Profile CRUD, admin user management | ✅ |
/api/categories |
Category listing, admin CRUD | Partial |
/api/services |
Service CRUD, search, filtering | Partial |
/api/bookings |
Booking lifecycle, disputes, OTP verification | ✅ |
/api/reviews |
Review CRUD, votes, provider replies | ✅ |
/api/notifications |
Notification inbox, mark read/all-read | ✅ |
/api/reports |
Admin analytics & export | ✅ Admin |
/api/upload |
File upload (images, documents) | ✅ |
/api/chat |
Message CRUD, conversations | ✅ |
/api/wallet |
Wallet operations, Razorpay orders, transactions | ✅ |
/api/subscriptions |
Plan management, activation, scheduling | ✅ |
/api/settings |
Admin global settings | ✅ Admin |
/api/leaves |
Provider leave/availability management | ✅ Provider |
| Event | Direction | Description |
|---|---|---|
register_user |
Client → Server | Map user ID to socket connection |
send_message |
Client → Server | Send chat message to a user |
receive_message |
Server → Client | Deliver incoming message |
delete_message |
Client → Server | Delete message notification |
message_deleted |
Server → Client | Message deletion broadcast |
mark_read |
Client → Server | Mark messages as read |
messages_read |
Server → Client | Read receipt notification |
| Requirement | Version |
|---|---|
| Node.js | v18+ |
| MongoDB | Local instance or Atlas URI |
| npm | v9+ |
# 1. Clone the repository
git clone https://github.com/your-username/serveflow.git
cd serveflow
# 2. Install backend dependencies
cd backend
npm install
# 3. Install frontend dependencies
cd ../frontend
npm installTerminal 1 — Backend:
cd backend
npm run dev # Starts Express + Socket.IO on http://localhost:5000Terminal 2 — Frontend:
cd frontend
npm run dev # Starts Vite dev server on http://localhost:3000The Vite dev server automatically proxies
/api/*and/uploads/*requests to the backend.
# Sync wallet balances (one-time migration)
cd backend
npm run sync# Server
PORT=5000
APP_URL=http://localhost:3000
# Database
MONGODB_URI=mongodb://localhost:27017/serveflow
# Authentication
JWT_SECRET=your_jwt_secret_here
# Razorpay Payment Gateway
RAZORPAY_KEY_ID=rzp_test_xxxxxxxxxxxxx
RAZORPAY_KEY_SECRET=your_razorpay_secret
# Email (Nodemailer)
EMAIL_USER=your_email@gmail.com
EMAIL_PASS=your_app_password
# Cloudinary (Image Storage)
CLOUDINARY_CLOUD_NAME=your_cloud_name
CLOUDINARY_API_KEY=your_api_key
CLOUDINARY_API_SECRET=your_api_secret
# WhatsApp (Baileys)
WHATSAPP_PHONE_NUMBER=919876543210
WHATSAPP_AUTH_DIR=baileys_auth_info
# CORS
ALLOWED_ORIGINS=http://localhost:3000,http://localhost:5173VITE_RAZORPAY_KEY_ID=rzp_test_xxxxxxxxxxxxx
BACKEND_URL=http://localhost:5000Both services are configured for Vercel deployment:
- Configured via
backend/vercel.jsonusing@vercel/node - All routes directed to
server.js - Set all environment variables in Vercel dashboard
- Configured via
frontend/vercel.jsonwith API rewrites /api/*and/uploads/*proxied to backend URL (e.g., Render)- SPA fallback to
index.htmlfor client-side routing
The frontend's vercel.json already includes rewrite rules pointing to a Render deployment URL. Update the destination URLs to match your backend host.
The application implements multiple security layers:
| Measure | Implementation |
|---|---|
| Helmet | Secure HTTP headers |
| CORS | Configurable allowed origins |
| Rate Limiting | 2000 req/15min per IP |
| XSS Protection | xss-clean middleware |
| NoSQL Injection | express-mongo-sanitize |
| HPP | HTTP Parameter Pollution protection |
| Password Hashing | bcryptjs with salt rounds (10) |
| JWT | 30-day expiry, cookie + bearer support |
| Account Lockout | Failed login attempt tracking |
| Input Validation | express-validator on routes |
| Audit Logging | Admin actions tracked with IP |
| OTP Verification | Service start/completion verification |
This project is proprietary. All rights reserved.
Built with ❤️ by Prit Gadhiya
FOR PR AND CONTRIBUTORS: PROBLEM: RENDER BLOCK NODE MAILER SERVICE TRANSFER RENDER TO RAILWAY {Render (free tier) Block All Port From SMTP :465,587)
also if need use resent or mailersend
AND MAKE UI/UX BETTER (responsiveness)