inventory-pro / README.md
MetiMiester's picture
Update README.md
96e840a verified
metadata
title: Inventory Pro (Monolith)
emoji: πŸ“¦
colorFrom: gray
colorTo: indigo
sdk: docker
app_port: 7860
pinned: false

Inventory Pro

Single-domain deployment of a MERN inventory app on a Hugging Face Docker Space.


Inventory Pro β€” MERN (Assignment)

A full-stack inventory app that hits the assignment spec end-to-end:

  • πŸ”Ž Search & filter, πŸ“₯ Import / πŸ“€ Export CSV, ✏️ inline row editing, 🧾 inventory history
  • πŸ’Ž Clean, responsive UI (table on desktop, cards on mobile)
  • 🧰 Robust CSV parser (BOM, comma/semicolon/tab),optimistic updates
  • πŸ” Production-friendly CORS, Express v5 compatible preflight
  • ☁️ Ready to deploy: Backend β†’ Render, Frontend β†’ Netlify

Tech Stack

  • Backend: Node.js, Express v5, Mongoose, Multer, csv-parse, json2csv, express-validator, Helmet, Morgan, CORS
  • Frontend: React + TypeScript + Vite, Tailwind CSS, @tanstack/react-query v5, axios, lucide-react
  • Database: MongoDB (Atlas or local)

Project Structure

inventory-pro/
  backend/
    src/
      config/
      controllers/
      middleware/
      models/
      routes/
      utils/
      server.js
    .env
    package.json
  frontend/
    src/
      components/
      lib/
      App.tsx
      main.tsx
      index.css
    .env
    index.html
    netlify.toml        # (optional, for Netlify)
    package.json
  README.md

Prerequisites

  • Node.js 18+ (recommended 20+)
  • MongoDB: Atlas connection string OR local mongod

1) Run Locally

A) Backend

  1. Create backend/.env:
PORT=4000
# Choose ONE:
# MONGODB_URI=mongodb+srv://<username>:<password>@cluster0.no4gl81.mongodb.net/inventorydb?retryWrites=true&w=majority&appName=Cluster0
MONGODB_URI=mongodb://127.0.0.1:27017/inventorydb

# Allow both common dev origins
CORS_ORIGIN=http://localhost:5173,http://127.0.0.1:5173

If your password has special characters (@, #, !, etc.), URL-encode them (@ β†’ %40).

  1. Install & run:
cd backend
npm i
npm run dev

Expected log:

βœ… MongoDB connected
πŸš€ API running on http://localhost:4000

Health checks in browser:

Express v5 note: Preflight is handled safely (no wildcard * route needed).


B) Frontend

  1. Create frontend/.env:
VITE_API_BASE=http://localhost:4000
  1. Install & run:
cd frontend
npm i
npm run dev

Open the app (Vite prints the URL, usually http://localhost:5173).

  • Top-right API / DB pills should be green βœ… when backend is running.
  • Hover them to see the API base URL in use.

2) CSV Format (Import/Export)

Headers (required): name,unit,category,brand,stock,status,image

  • status is optional; if omitted, it’s derived from stock (0 β†’ OUT_OF_STOCK, >0 β†’ IN_STOCK)
  • Parser accepts comma, semicolon, or tab delimited CSV
  • BOM/Excel CSVs are handled

Example:

name,unit,category,brand,stock,status,image
Coffee Beans,kg,Beverages,Acme,50,IN_STOCK,https://picsum.photos/seed/coffee/200
Tea Bags,box,Beverages,Acme,0,OUT_OF_STOCK,https://picsum.photos/seed/tea/200

3) Quick Tests (curl / PowerShell)

Create a CSV quickly (PowerShell):

@'
name,unit,category,brand,stock,status,image
Coffee Beans,kg,Beverages,Acme,50,IN_STOCK,https://picsum.photos/seed/coffee/200
Tea Bags,box,Beverages,Acme,0,OUT_OF_STOCK,https://picsum.photos/seed/tea/200
Sugar,kg,Grocery,SweetCo,100,IN_STOCK,https://picsum.photos/seed/sugar/200
Milk,litre,Dairy,DairyBest,20,IN_STOCK,https://picsum.photos/seed/milk/200
'@ | Set-Content -Encoding UTF8 ".\products.csv"

Import:

curl.exe -s -X POST "http://localhost:4000/api/products/import" -F "file=@products.csv"
# β†’ {"addedCount":4,"skipped":[...if duplicates...]}

List:

curl.exe -s "http://localhost:4000/api/products?page=1&limit=10"

Search (assignment alias):

curl.exe -s "http://localhost:4000/api/products/search?name=Tea"

Update stock (PUT):

# get first id
$resp = Invoke-RestMethod -Uri "http://localhost:4000/api/products?limit=1" -Method GET
$id = $resp.data[0]._id
Invoke-RestMethod -Uri "http://localhost:4000/api/products/$id" -Method PUT -ContentType "application/json" -Body '{"stock":75}'

History:

curl.exe -s "http://localhost:4000/api/products/<id>/history"

Export:

curl.exe -L "http://localhost:4000/api/products/export" -o exported.csv

4) API Reference

Base URL (dev): http://localhost:4000/api

Method Path Description
GET /products List (pagination, sorting; filters name, category)
GET /products/search Alias of list supporting ?name=
POST /products/import Import CSV (multipart: file)
GET /products/export Export all products as CSV
PUT /products/:id Update editable fields (validates)
GET /products/:id/history Inventory change logs (sorted desc)

5) Assignment Mapping (Scoring)

Frontend (50 pts)

  • Search bar (/api/products/search?name= alias) + category filter βœ…
  • β€œAdd New Product” button (CSV one-row import) βœ…
  • Import/Export buttons aligned right (Export downloads; Import uploads & refreshes) βœ…
  • Products table columns: Image, Name, Unit, Category, Brand, Stock, Status, Actions βœ…
  • Stock labels: green β€œIn Stock” when >0, red β€œOut of Stock” when 0 βœ…
  • Actions: Edit/Delete; inline editing with Save β†’ PUT /api/products/:id βœ…
  • Table updates without full page refresh (optimistic) βœ…
  • Inventory history sidebar (fetch logs desc by date) βœ…
  • Responsive/mobile layout βœ…

Backend (50 pts)

  • Import CSV: accept file, parse columns, insert only new, return addedCount + skipped (duplicate info for editing) βœ…
  • Export CSV: returns all products βœ…
  • Products list: JSON with pagination & sorting βœ…
  • Update product: validation (unique name, numeric stock, status enum), updates only editable fields βœ…
  • Inventory history: logs stock changes; fetch API returns desc βœ…

6) Deployment

A) Backend β†’ Render

  1. Push repo to GitHub.

  2. Render: New β†’ Web Service β†’ connect backend/

  3. Build Command: npm install Start Command: node src/server.js

  4. Environment variables:

    • MONGODB_URI β†’ your Atlas URI (e.g., mongodb+srv://.../inventorydb?...)

    • CORS_ORIGIN β†’ https://<your-netlify>.netlify.app

      • (Optionally add dev: http://localhost:5173,http://127.0.0.1:5173)
  5. Deploy. Verify: https://<render-app>.onrender.com/health β†’ { "ok": true, "db": "connected" }.

Express reads process.env.PORT automatically on Render.

B) Frontend β†’ Netlify

  1. In frontend/.env set:
VITE_API_BASE=https://<render-app>.onrender.com
  1. (Optional) Add frontend/netlify.toml:
[build]
  command = "npm run build"
  publish = "dist"

[[redirects]]
  from = "/*"
  to = "/index.html"
  status = 200
  1. Netlify β†’ New site from Git

    • Base directory: frontend
    • Build command: npm run build
    • Publish directory: dist
    • Env var: VITE_API_BASE=https://<render-app>.onrender.com

7) Troubleshooting

  • Frontend β€œfailed to fetch” / red API pill

    • Backend not running or URL mismatch. Check frontend/.env and restart npm run dev.
    • CORS: ensure your frontend origin is in CORS_ORIGIN.
  • Import says β€œNo valid rows found in CSV”

    • Headers must match exactly: name,unit,category,brand,stock,status,image.
    • At least name, unit, category must be non-empty for a row to import.
    • Excel CSVs with semicolons are supported.
  • History not updating

    • Only changes to stock create history entries.

8) Scripts

Backend

npm run dev     # nodemon dev server
npm start       # node src/server.js

Frontend

npm run dev     # Vite dev server
npm run build   # production build
npm run preview # serve built app locally

License

MIT