Orgivafood API

A single REST backend serving both the Orgivafood storefront and the admin panel โ€” products, categories, orders, customers, reviews, coupons, banners, blog, newsletter, contact messages and authentication. Not yet wired into either frontend; this API is complete and independently testable.

Base URL  http://localhost:5000/api Auth  JWT Bearer token Format  application/json

Getting Started

Three steps to a running, seeded API.

# 1. install dependencies
npm install

# 2. copy the env file and set your MongoDB connection string
cp .env.example .env

# 3. seed demo data, then start the server
npm run seed
npm run dev

The seed script creates one admin account (admin@orgivafood.pk / Admin@123) and 8 demo customers (any seeded email, password Customer@123), plus products, categories, orders, reviews, coupons, banners, blog posts, testimonials, FAQs and site settings.

Every response follows the same JSON envelope:

{ "success": true, "message": "Success", "data": { ... }, "meta": { "total": 40, "page": 1, "limit": 20, "totalPages": 2 } }

Errors follow the same shape with success: false:

{ "success": false, "message": "Product not found" }

Protected routes require an Authorization: Bearer <token> header, obtained from /api/auth/login, /api/auth/admin/login, or the OTP flow. Routes tagged Admin additionally require the token's user to have role: "admin".

๐Ÿ” Auth

Base path: /api/auth โ€” registration, login and phone OTP for customers, plus a dedicated admin login.

POST/registerPublic

Create a customer account with email + password.

{ "name": "Ayesha Malik", "email": "ayesha@example.com", "phone": "+92 300 1234567", "password": "secret123" }
POST/loginPublic

Log in with email + password. Returns { user, token }.

{ "email": "ayesha@example.com", "password": "secret123" }
POST/admin/loginPublic

Dedicated login for the admin panel โ€” only succeeds for accounts with role: "admin".

{ "email": "admin@orgivafood.pk", "password": "Admin@123" }
POST/otp/sendPublic

Request a 4-digit OTP for a phone number, valid for OTP_EXPIRES_MINUTES. Demo backend โ€” no SMS gateway is wired up, so the response includes devOtp for testing.

{ "phone": "+92 300 1234567" }
POST/otp/verifyPublic

Verify the OTP and log in, auto-creating a bare customer account on first login. Returns { user, token }.

{ "phone": "+92 300 1234567", "code": "4821" }
GET/meCustomer/Admin

Return the currently authenticated user's profile.

๐Ÿ‘ฅ Users (Customers)

Base path: /api/users โ€” admin-only management of customer accounts.

GET/Admin

List customers.

Query params: search, status, page, limit
GET/:idAdmin

Get one customer plus their order history.

PUT/:idAdmin

Update a customer's name, phone, status, or address.

{ "status": "Blocked" }
DELETE/:idAdmin

Delete a customer account.

๐Ÿ›’ Products

Base path: /api/products โ€” the storefront catalog and its admin management.

GET/Public

List products with filtering, search, sorting and pagination.

Query params: search, category, tag, minPrice, maxPrice, status, inStock (true/false), sort (price-asc | price-desc | newest | rating), page, limit
GET/:idOrSlugPublic

Get one product by its Mongo id or its slug (e.g. turmeric-powder).

POST/Admin

Create a product. slug is auto-generated from name if omitted.

{
  "name": "Turmeric Powder", "sku": "ORG-TUR-200", "category": "Spices",
  "price": 149, "mrp": 199, "unit": "200g", "stock": 84,
  "image": "https://images.unsplash.com/photo-...", "tags": ["Best Sellers", "Spices"]
}
PUT/:idAdmin

Update any product fields.

PATCH/:id/statusAdmin

Quick status toggle: Active, Draft, Out of Stock, Low Stock.

{ "status": "Out of Stock" }
DELETE/:idAdmin

Delete a product.

๐Ÿ—‚ Categories

Base path: /api/categories โ€” product categories, with a live product count.

GET/Public

List categories (optionally ?status=Active). Each includes productCount.

GET/:idOrSlugPublic

Get one category by id or slug.

POST/Admin

Create a category.

{ "name": "Organic Oil", "image": "https://...", "description": "Cold-pressed cooking oils." }
PUT/:idAdmin

Update a category.

DELETE/:idAdmin

Delete a category.

โญ Reviews

Base path: /api/reviews โ€” product reviews, moderated before going live.

GET/Public / Admin

Guests see only Published reviews. An authenticated admin can filter by any status.

Query params: product, status (admin only), page, limit
POST/Public / Customer

Submit a review โ€” works for guests (pass name) or logged-in customers. Always starts as Pending.

{ "product": "<productId>", "rating": 5, "title": "Great quality", "text": "Loved it!", "name": "Ayesha" }
PUT/:id/statusAdmin

Moderate a review โ€” approving or rejecting it also recalculates the product's average rating.

{ "status": "Published" }
DELETE/:idAdmin

Delete a review.

๐Ÿงบ Cart

Base path: /api/cart โ€” server-side cart for a logged-in customer, or a guest identified by an x-session-id header.

Guest requests must send a client-generated x-session-id header (e.g. a UUID stored in localStorage). Logged-in requests use the Bearer token instead.
GET/Public/Customer

Get (or lazily create) the current cart.

POST/itemsPublic/Customer

Add a product, or increase its quantity (capped at 10).

{ "productId": "<productId>", "quantity": 2 }
PUT/items/:productIdPublic/Customer

Set an item's exact quantity.

{ "quantity": 3 }
DELETE/items/:productIdPublic/Customer

Remove one item from the cart.

DELETE/Public/Customer

Clear the cart.

๐Ÿ“ฆ Orders

Base path: /api/orders โ€” checkout and order management.

POST/Public/Customer

Place an order (checkout). Works for guests or logged-in customers; applies a coupon if given, decrements product stock, and computes shipping (free โ‰ฅ Rs 499, otherwise Rs 49).

{
  "contactInfo": { "firstName": "Ahmed", "lastName": "Khan", "email": "ahmed@example.com", "phone": "+92 300 1234567" },
  "shippingAddress": { "street": "House 12, Street 4", "city": "Lahore", "province": "Punjab", "postalCode": "54000" },
  "items": [{ "product": "<productId>", "name": "Turmeric Powder", "price": 149, "quantity": 2 }],
  "paymentMethod": "COD",
  "couponCode": "FLAT50"
}
GET/Customer/Admin

Admins see every order; customers see only their own.

Query params: status, paymentStatus, search, page, limit
GET/:idCustomer/Admin

Get one order (customers can only fetch their own).

PUT/:id/statusAdmin

Update order and/or payment status.

{ "orderStatus": "Shipped", "paymentStatus": "Paid" }
DELETE/:idAdmin

Delete an order.

๐Ÿท Coupons

Base path: /api/coupons

GET/validate/:code?subtotal=NNNPublic

Validate a coupon at checkout before it's applied โ€” checks status, expiry, usage limit and minimum order.

GET/Admin

List all coupons.

POST/Admin

Create a coupon.

{ "code": "FLAT50", "type": "Fixed", "value": 50, "minOrder": 499, "usageLimit": 2000, "expiryDate": "2026-12-31" }
PUT/:idAdmin

Update a coupon.

DELETE/:idAdmin

Delete a coupon.

๐Ÿ–ผ Banners

Base path: /api/banners โ€” hero slider, promo row and brand banners.

GET/Public

List banners โ€” only Active ones by default.

Query params: placement (Hero Slider | Promo Row | Brand Banner), all=true (admin: include every status)
POST/Admin

Create a banner.

{ "title": "Everything You Love in One Place", "placement": "Hero Slider", "image": "https://...", "linkTo": "/collections/all" }
PUT/:idAdmin

Update a banner.

DELETE/:idAdmin

Delete a banner.

๐Ÿ“ Blog

Base path: /api/blog

GET/Public

List posts โ€” only Published by default.

Query params: category, all=true (admin: include drafts), page, limit
GET/:slugPublic

Get one post by slug โ€” increments its view counter.

POST/Admin

Create a post. slug auto-generates from title if omitted.

{ "title": "5 Reasons to Switch to Cold-Pressed Oils", "excerpt": "...", "image": "https://...", "body": ["Paragraph one.", "Paragraph two."], "status": "Published" }
PUT/:idAdmin

Update a post.

DELETE/:idAdmin

Delete a post.

๐Ÿ’ฌ Testimonials

Base path: /api/testimonials

GET/Public

List testimonials (?all=true for admin to include hidden ones).

POST/Admin

Create a testimonial.

{ "name": "Ayesha Malik", "location": "Karachi", "rating": 5, "text": "..." }
PUT/:idAdmin

Update a testimonial.

DELETE/:idAdmin

Delete a testimonial.

โ“ FAQs

Base path: /api/faqs

GET/Public

List FAQs, ordered by order. Optional ?category= filter.

POST/Admin

Create an FAQ.

{ "question": "Do you deliver across Pakistan?", "answer": "Yes, nationwide in 3โ€“7 business days.", "category": "Shipping" }
PUT/:idAdmin

Update an FAQ.

DELETE/:idAdmin

Delete an FAQ.

๐Ÿ“ง Subscribers

Base path: /api/subscribers โ€” newsletter sign-ups from the footer, coupon popup, or checkout opt-in.

POST/Public

Subscribe an email (re-subscribes if it already exists).

{ "email": "ahmed@example.com", "source": "Footer Newsletter" }
GET/Admin

List subscribers (?status=, page, limit).

PUT/:idAdmin

Update a subscriber's status.

DELETE/:idAdmin

Delete a subscriber.

โœ‰๏ธ Contact

Base path: /api/contact โ€” the storefront's contact form.

POST/Public

Submit a contact message.

{ "name": "Ahmed Khan", "email": "ahmed@example.com", "phone": "+92 300 1234567", "subject": "Bulk order", "message": "..." }
GET/Admin

List messages (?status=, page, limit).

PUT/:id/statusAdmin

Mark a message Read or Responded.

DELETE/:idAdmin

Delete a message.

โš™๏ธ Settings

Base path: /api/settings โ€” a single site-wide settings document (currency, shipping thresholds, contact details, certifications).

GET/Public

Get site settings (auto-created with sensible defaults on first request).

PUT/Admin

Update site settings.

{ "freeShippingThreshold": 599, "standardShippingFee": 60 }

๐Ÿ“Š Dashboard

Base path: /api/dashboard โ€” aggregate analytics for the admin panel's home screen.

GET/statsAdmin

Headline totals: revenue (from paid orders), order count, customer count, product count.

GET/weekly-salesAdmin

Revenue grouped by day for the last 7 days.

GET/order-status-breakdownAdmin

Order counts grouped by orderStatus, for a pie/bar chart.