Modern RESTful API for restaurant management with cart, orders, payments, and reviews.
- Frontend: https://fullsnack-one.vercel.app/
- Backend API: https://fullsnack.up.railway.app/
- API Documentation: https://fullsnack.up.railway.app/api-docs/
- JWT Authentication - Access & refresh tokens with email verification
- Shopping Cart - Add single/multiple items with automatic discount application
- Order Management - Create orders with delivery info, multiple payment methods
- Stripe Payment - Secure checkout with webhook confirmation
- Auto Ratings - Menu items update average rating automatically with each review
- Special Offers - Percentage discounts auto-apply to eligible items
- TTL Orders - Pending orders auto-expire after 10 minutes
- Batch Operations - Add multiple cart items in one request
- Role-Based Access - Admin and Customer permissions
- Rate Limiting - Prevent brute force on auth endpoints
- Swagger Docs - Interactive API testing interface
- Backend: Node.js, Express v5
- Database: MongoDB + Mongoose
- Auth: JWT, bcrypt
- Payment: Stripe v19.2.0
- Validation: Joi
- Docs: Swagger UI
git clone https://github.com/AbdoAbdelfatah/Dishly_Backend.git
cd Dishly_Backend
npm installCreate .env:
PORT=5000
MONGO_URI=your_mongodb_uri
ACCESS_TOKEN_SECRET=your_secret
REFRESH_TOKEN_SECRET=your_secret
JWT_SECRET=your_secret
STRIPE_SECRET_KEY=your_stripe_key
STRIPE_WEBHOOK_SECRET=your_webhook_secret
EMAIL_SERVICE=gmail
EMAIL_USER=your_email
EMAIL_PASSWORD=your_password
FRONTEND_URL=https://fullsnack-one.vercel.appnpm start # Production
npm run dev # DevelopmentPOST /user/register - Register new user
GET /user/confirm-email/:id - Confirm email
POST /user/login - Login (returns JWT)
POST /user/refresh - Refresh access token
GET /user/me - Get current user
PATCH /user/update - Update profile
GET /menu-items - Get all items
GET /menu-items/category/:cat - Filter by category
POST /menu-items - Create (Admin only)
PUT /menu-items/:id - Update (Admin only)
DELETE /menu-items/:id - Delete (Admin only)
GET /cart - Get user cart
POST /cart/items - Add items (single or array)
PATCH /cart/items - Update quantity
DELETE /cart/items - Remove item
DELETE /cart - Clear cart
POST /orders/checkout - Create order from cart
GET /orders - Get user order history
GET /orders/:id - Get order details
GET /orders/all - Get all orders (Admin)
POST /comments - Create review (auto-updates rating)
GET /comments/menu-item/:id - Get item reviews
GET /offers - Get all offers
POST /offers - Create offer
PUT /offers/:id - Update offer
DELETE /offers/:id - Delete offer
Add JWT token to protected endpoints:
Authorization: Bearer <your-access-token>
When adding items to cart, system checks for active offers and applies best discount automatically. Stores both original and discounted prices.
When customer submits review (1-5 stars), system aggregates all ratings for that menu item using MongoDB aggregation and updates the menu item's average rating instantly.
- Customer creates order β 2. Stripe checkout session β 3. Payment on Stripe β 4. Webhook confirms β 5. Order marked confirmed β 6. Cart cleared
Pending orders have TTL of 10 minutes using MongoDB TTL index. Once confirmed, they persist indefinitely.
src/
βββ config/ # DB & Swagger config
βββ middlewares/ # Auth, validation, error handling
βββ models/ # Mongoose schemas
βββ modules/ # Feature modules (user, cart, order, etc)
β βββ */
β βββ *.controller.js
β βββ *.service.js
β βββ *.routes.js
β βββ *.validation.js
βββ utils/ # Helper functions
- Bcrypt password hashing (10 rounds)
- JWT access & refresh tokens
- HTTP-only cookies for refresh tokens
- Rate limiting (5 req/10min on auth)
- Joi input validation
- Stripe webhook signature verification
- CORS configuration
Backend: Railway
Frontend: Vercel
Database: MongoDB Atlas
- Go to Stripe Dashboard β Webhooks
- Add endpoint:
https://fullsnack.up.railway.app/payment/webhook - Select event:
checkout.session.completed - Copy secret to
STRIPE_WEBHOOK_SECRET
Visit https://fullsnack.up.railway.app/api-docs/ for full interactive API documentation with request/response examples.
Try it live: https://fullsnack-one.vercel.app/