A full-stack MERN (MongoDB, Express, React, Node.js) e-commerce platform with authentication, product management, shopping cart, and order processing capabilities.
- Features
- Tech Stack
- Project Structure
- Prerequisites
- Installation
- Environment Variables
- Running the Application
- Admin Login
- API Endpoints
- Models
- Authentication
- Middleware
- License
- User registration and login with JWT tokens
- Google OAuth 2.0 integration
- Role-based access control (User/Admin)
- Secure password hashing with bcrypt
- Cookie-based authentication
- Create, read, update, and delete products (CRUD)
- Product image upload with Cloudinary integration
- Product search and filtering
- Category-based organization
- Stock management
- Add/remove items from cart
- Update item quantities
- Persistent cart storage
- Cart management per user
- Place orders from cart
- Order status tracking (Pending, Processing, Shipped, Delivered, Cancelled)
- Order history for users
- Admin order management
- Rate limiting to prevent abuse
- Helmet.js for security headers
- Input validation with Zod
- Error handling middleware
- Request logging with Pino
- CORS configuration
- Runtime: Node.js with TypeScript
- Framework: Express.js
- Database: MongoDB with Mongoose ODM
- Authentication: Passport.js, JWT, bcryptjs
- File Upload: Multer, Cloudinary
- Validation: Zod
- Logging: Pino
- Security: Helmet, express-rate-limit, CORS
- Framework: React 18 with TypeScript
- Build Tool: Vite
- Routing: React Router DOM v7
- Styling: Tailwind CSS
- UI Components: Shadcn/ui, Lucide React
- HTTP Client: Axios
- Utilities: clsx, tailwind-merge, class-variance-authority
pavon-platform/
βββ backend/
β βββ src/
β β βββ config/
β β β βββ cloudinary.ts # Cloudinary configuration
β β β βββ passport.ts # Passport strategies
β β βββ controllers/
β β β βββ authController.ts
β β β βββ cartController.ts
β β β βββ orderController.ts
β β β βββ productController.ts
β β βββ middleware/
β β β βββ auth.ts # Authentication middleware
β β β βββ errorHandler.ts # Global error handler
β β β βββ rateLimiter.ts # Rate limiting
β β β βββ validate.ts # Validation middleware
β β βββ models/
β β β βββ Cart.ts
β β β βββ Order.ts
β β β βββ Product.ts
β β β βββ User.ts
β β βββ routes/
β β β βββ authRoutes.ts
β β β βββ cartRoutes.ts
β β β βββ orderRoutes.ts
β β β βββ productRoutes.ts
β β βββ utils/
β β β βββ AppError.ts # Custom error class
β β β βββ catchAsync.ts # Async error wrapper
β β β βββ isAdminEmail.ts # Admin role checker
β β β βββ jwt.ts # JWT utilities
β β βββ validators/
β β β βββ authValidator.ts
β β β βββ productValidator.ts
β β βββ server.ts # Application entry point
β β βββ types.ts # TypeScript types
β βββ uploads/ # Local file uploads
β βββ logs/ # Application logs
β βββ package.json
β βββ tsconfig.json
βββ frontend/
β βββ src/
β β βββ components/
β β β βββ Navbar.tsx
β β βββ context/
β β β βββ AuthContext.tsx # Authentication context
β β βββ pages/
β β β βββ Dashboard.tsx
β β β βββ LandingPage.tsx
β β β βββ LoginPage.tsx
β β β βββ SignupPage.tsx
β β βββ App.tsx
β β βββ main.tsx
β β βββ index.css
β βββ public/
β βββ package.json
β βββ vite.config.ts
β βββ tailwind.config.js
β βββ tsconfig.json
βββ package.json # Root package (concurrently scripts)
Before you begin, ensure you have the following installed:
- Node.js (v18 or higher)
- npm or yarn
- MongoDB (local installation or MongoDB Atlas account)
- Git
git clone <repository-url>
cd pavon-platformInstall root dependencies:
npm installInstall backend dependencies:
cd backend
npm installInstall frontend dependencies:
cd frontend
npm installCreate a .env file in the backend directory:
# Server
PORT=5001
NODE_ENV=development
# Database
MONGO_URI=mongodb://localhost:27017/pavon-platform
# Or use MongoDB Atlas:
# MONGO_URI=mongodb+srv://<username>:<password>@cluster.mongodb.net/pavon-platform
# JWT
JWT_SECRET=your_jwt_secret_key_here
JWT_EXPIRES_IN=7d
# Frontend URL
FRONTEND_URL=http://localhost:5173
# Google OAuth
GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret
GOOGLE_CALLBACK_URL=http://localhost:5001/api/auth/google/callback
# Cloudinary
CLOUDINARY_CLOUD_NAME=your_cloudinary_cloud_name
CLOUDINARY_API_KEY=your_cloudinary_api_key
CLOUDINARY_API_SECRET=your_cloudinary_api_secret
# Admin Emails (comma-separated)
ADMIN_EMAILS=admin@example.com,admin2@example.comCreate a .env file in the frontend directory:
VITE_API_BASE_URL=http://localhost:5001/apinpm run devcd backend
npm run devcd frontend
npm run dev# From root directory
npm run build
# Start production server
npm startThe application will be available at:
- Frontend: http://localhost:5173
- Backend: http://localhost:5001
After setting up the admin user, use these credentials to login:
Email: admin@example.com
Password: Admin123!
Before you can login as admin, you need to create the admin user in the database:
cd backend
npm run create-adminThis will create an admin user with the default credentials above.
If you forget the admin password or need to reset it:
cd backend
npm run reset-admin-passwordThis will reset the password back to Admin123!
- Admin Email Whitelist: Users who sign up with emails listed in the
ADMIN_EMAILSenvironment variable automatically receive admin role - Default Admin Emails:
admin@example.com,superadmin@example.com - Add More Admins: Edit the
ADMIN_EMAILSvariable inbackend/.env:ADMIN_EMAILS=admin@example.com,superadmin@example.com,newemail@example.com
- Login: Go to http://localhost:5173/login and use the admin credentials
| Feature | Regular User | Admin |
|---|---|---|
| Browse Products | β | β |
| Add to Cart | β | β |
| Place Orders | β | β |
| View Own Orders | β | β |
| Create Products | β | β |
| Update Products | β | β |
| Delete Products | β | β |
| Manage All Orders | β | β |
| Update Order Status | β | β |
Problem: "Invalid email or password"
- Run
npm run reset-admin-passwordin the backend directory - Ensure the backend server is running
- Check that MongoDB is connected
Problem: User exists but not admin
- Verify the email is listed in
ADMIN_EMAILSinbackend/.env - Restart the backend server after changing
.env - Emails are case-insensitive
Problem: Cannot create admin user
- Ensure MongoDB is running and connected
- Check
MONGO_URIinbackend/.env - Verify the backend dependencies are installed
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| POST | /signup |
Register new user | No |
| POST | /login |
Login user | No |
| POST | /logout |
Logout user | Yes |
| GET | /me |
Get current user | Yes |
| GET | /google |
Google OAuth login | No |
| GET | /google/callback |
Google OAuth callback | No |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| GET | / |
Get all products | No |
| GET | /:id |
Get product by ID | No |
| POST | / |
Create product | Admin |
| PUT | /:id |
Update product | Admin |
| DELETE | /:id |
Delete product | Admin |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| GET | / |
Get user cart | Yes |
| POST | / |
Add item to cart | Yes |
| PUT | /:itemId |
Update cart item | Yes |
| DELETE | /:itemId |
Remove item from cart | Yes |
| DELETE | / |
Clear cart | Yes |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| GET | / |
Get user orders | Yes |
| GET | /:id |
Get order by ID | Yes |
| POST | / |
Create order | Yes |
| PUT | /:id/status |
Update order status | Admin |
{
name: string
email: string (unique)
password: string (hashed)
role: 'user' | 'admin'
googleId?: string
avatar?: string
timestamps: true
}{
name: string
description: string
price: number
category: string
stock: number
images: string[]
seller: ObjectId (ref: User)
timestamps: true
}{
user: ObjectId (ref: User)
items: [{
product: ObjectId (ref: Product)
quantity: number
}]
timestamps: true
}{
user: ObjectId (ref: User)
items: [{
product: ObjectId (ref: Product)
quantity: number
price: number
}]
totalAmount: number
status: 'pending' | 'processing' | 'shipped' | 'delivered' | 'cancelled'
timestamps: true
}The application uses a hybrid authentication approach:
- Access tokens stored in HTTP-only cookies
- Token expiration: 7 days (configurable)
- Automatic token refresh on requests
- Sign in with Google account
- Automatic user creation on first login
- Profile data synchronization
- Frontend: AuthContext manages authentication state
- Backend:
authmiddleware verifies JWT tokens - Admin routes: Additional role check
- Verifies JWT tokens from cookies
- Attaches user to request object
- Handles token expiration
- Centralized error handling
- Consistent error response format
- Development vs production error details
- Prevents brute force attacks
- Configurable limits per endpoint
- IP-based tracking
- Request body validation with Zod schemas
- Type-safe validation
- Automatic error responses
cd backend
npm run dev # Runs with ts-node-dev (auto-reload)cd frontend
npm run dev # Runs with Vite (hot reload)# Backend
cd backend
npm run build
# Frontend
cd frontend
npm run buildcd frontend
npm run lintnpm run dev- Run both frontend and backend concurrentlynpm run build- Build both frontend and backendnpm start- Start production server
npm run dev- Development mode with auto-reloadnpm run build- Compile TypeScript to JavaScriptnpm start- Run production build
npm run dev- Development servernpm run build- Production buildnpm run preview- Preview production buildnpm run lint- Lint source files
tsconfig.json- TypeScript configuration.env- Environment variables
tsconfig.json- TypeScript configurationvite.config.ts- Vite configurationtailwind.config.js- Tailwind CSS configurationpostcss.config.js- PostCSS configurationeslint.config.js- ESLint configuration
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License.
- React team for the amazing framework
- Express.js community
- MongoDB team
- Tailwind CSS
- Shadcn/ui for beautiful components
- All open-source contributors
For support, email shachirurashmika35@gmail.com or open an issue in the repository.
Built with β€οΈ using the MERN stack