A production-grade, full-stack Procurement ERP that takes vendors from registration to paid invoice β fully automated, fully audited, fully yours.
Live Demo Β· Excalidraw Mockup Β· Report Bug Β· API Health
Most procurement in Indian SMEs and enterprises still runs on WhatsApp forwards, Excel tenders, and trust-based approvals. This leads to:
- π§ Zero audit trails β Who approved what? Nobody knows.
- π No bid comparison β Cheapest vendor? Just a gut feeling.
- π Manual bottlenecks β POs taking days to generate instead of seconds.
- πΈ No spend visibility β Finance teams flying blind.
VyaparSetu digitizes the entire procurement lifecycle on a single platform β structured, secure, and automated from the first RFQ to the final paid invoice.
One platform. Eight modules. Zero manual errors.
| # | Module | What It Does |
|---|---|---|
| π’ | Vendor Registry | Register suppliers with GST details, categories, and performance scores |
| π | Smart RFQ Engine | Draft multi-item tenders, attach files, set deadlines, dispatch to vendors |
| π¬ | Quotation Portal | Vendors submit itemized bids with delivery timelines via secure portal |
| βοΈ | Bid Comparison Matrix | Side-by-side price and delivery analysis β lowest bid auto-highlighted |
| β | Approval Workflows | Multi-step manager approval pipelines with full remark audit history |
| π¦ | Purchase Order Gen | Auto-number POs generated as Cloudinary-hosted PDFs in one click |
| π§Ύ | Invoice Engine | GST-aware tax invoices with subtotals, email delivery, and print support |
| π‘ | Live Notifications | Real-time Socket.io alerts for every procurement state change |
graph TB
subgraph Client["π₯οΈ Client β Vite + React 18"]
UI[Role-Based UI]
DM[Dark / Light Mode]
RT[Recharts Analytics]
end
subgraph Server["βοΈ API Server β Express.js + Node 22"]
Auth[JWT + RBAC Middleware]
Routes[8 Route Modules]
Services[Business Logic Services]
Sockets[Socket.io Engine]
end
subgraph Data["πΎ Data & Storage"]
DB[(PostgreSQL / Supabase)]
CDN[Cloudinary CDN]
SMTP[Gmail SMTP]
end
Client -->|REST + WebSocket| Server
Server -->|Sequelize ORM| DB
Services -->|Puppeteer β Buffer| CDN
Services -->|Nodemailer| SMTP
Sockets -.->|Push Events| Client
sequenceDiagram
autonumber
actor PO as π§βπΌ Procurement Officer
actor V as πͺ Vendor
actor M as π Manager
PO->>+API: Register & onboard vendor
PO->>API: Create RFQ (items + deadline + files)
API-->>V: π§ Email β RFQ invitation
V->>API: Submit itemized quotation
PO->>API: Pull bid comparison matrix
PO->>API: Initiate approval workflow
API-->>M: π§ Email β approval pending
M->>API: Approve with audit remarks
API-->>PO: π‘ Socket event β approved
PO->>+API: Generate Purchase Order
API->>Puppeteer: Render PDF
Puppeteer->>Cloudinary: Upload & get URL
API-->>V: π§ PO PDF emailed
V->>API: Generate Tax Invoice (18% GST)
API->>Puppeteer: Render Invoice PDF
Puppeteer-->>-API: Secure CDN URL
API-->>-PO: π§ Invoice PDF delivered
RBAC is enforced at the middleware level on every protected route β not just the UI.
ADMIN > PROCUREMENT_OFFICER > MANAGER > VENDOR
| Permission | Admin | Proc. Officer | Manager | Vendor |
|---|---|---|---|---|
| Manage users & roles | β | β | β | β |
| Register & approve vendors | β | β | β | β |
| Create & publish RFQs | β | β | β | β |
| Submit quotations | β | β | β | β |
| View bid comparison | β | β | β | β |
| Initiate approval pipeline | β | β | β | β |
| Approve / reject workflows | β | β | β | β |
| Generate Purchase Orders | β | β | β | β |
| Generate Tax Invoices | β | β | β | β |
| Full audit log access | β | β | β | β |
Additional security layers:
- π
bcryptjspassword hashing (salt rounds: 10) - πͺ HTTP-only JWT cookies + refresh token rotation
- π‘οΈ
helmetHTTP headers hardening - π¦
express-rate-limitβ 100 req / 15 min per IP - β
express-validatorschema validation on all inputs
VyaparSetu/
βββ backend/
β βββ src/
β β βββ app.js # Express setup, middleware stack
β β βββ server.js # DB connect + Socket.io + HTTP boot
β β βββ config/
β β β βββ database.js # Sequelize multi-env config (dev/test/prod)
β β β βββ cloudinary.js # Multer-Cloudinary storage engine
β β βββ models/ # 19 Sequelize models with associations
β β β βββ user.js # bcrypt hooks, scoped password exclusion
β β β βββ vendor.js # GST, performance score, status enum
β β β βββ rfq.js # DRAFTβPUBLISHEDβCLOSED state machine
β β β βββ quotation.js # Per-item pricing + delivery timeline
β β β βββ approvalWorkflow.js # Multi-step approver chain
β β β βββ purchaseOrder.js # Auto-numbered POs, PDF URL
β β β βββ invoice.js # Subtotal + tax + grand total + due date
β β βββ controllers/ # Thin HTTP handlers β delegate to services
β β βββ services/ # All business logic lives here
β β β βββ auth.service.js # JWT sign/verify, refresh rotation
β β β βββ approval.service.js # Workflow state machine
β β β βββ pdf.service.js # Puppeteer render β Cloudinary upload
β β β βββ email.service.js # Nodemailer template dispatch
β β βββ routes/ # 8 route modules mounted under /api
β β βββ middlewares/ # protect(), restrictTo(), errorMiddleware()
β β βββ validators/ # express-validator chains per route
β β βββ sockets/ # Socket.io event emitters
β β βββ templates/ # EJS email & PDF templates
β βββ integration-test.js # 7-phase E2E test (no test framework needed)
β βββ clear-db.js # Nuclear reset utility for dev
β
βββ frontend/
β βββ src/
β β βββ main.jsx # Vite entry point
β β βββ App.jsx # Global dark/light mode provider
β β βββ pages/
β β β βββ LandingPage.jsx # Interactive mockup + role previews
β β βββ styles/ # Glassmorphism CSS design system
β βββ vite.config.js
β
βββ db.js # Lightweight pg Pool helper (raw queries)
βββ README.md
19 tables, fully relational, with Sequelize association hooks:
erDiagram
roles ||--o{ users : "has"
users ||--o{ approval_steps : "approves"
users ||--o{ rfqs : "creates"
vendor_categories ||--o{ vendors : "classifies"
vendors ||--o{ vendor_users : "has"
vendors ||--o{ rfq_vendors : "invited to"
vendors ||--o{ quotations : "submits"
rfqs ||--o{ rfq_items : "contains"
rfqs ||--o{ rfq_vendors : "sent to"
rfqs ||--o{ quotations : "receives"
quotations ||--o{ quotation_items : "has"
quotations ||--o{ approval_workflows : "triggers"
approval_workflows ||--o{ approval_steps : "has"
quotations ||--o{ purchase_orders : "becomes"
purchase_orders ||--o{ invoices : "generates"
Get the full ERP running in under 5 minutes.
- Node.js β₯ 18
- PostgreSQL instance (Supabase free tier works great)
- Cloudinary account (free tier)
- Gmail account with App Password enabled
git clone https://github.com/harshit-kumar-dev/VyaparSetu.git
cd VyaparSetubackend/.env β copy and fill in your values:
PORT=5000
NODE_ENV=development
DATABASE_URL=postgresql://<user>:<password>@<host>:5432/<db>
JWT_SECRET=<generate with: node -e "console.log(require('crypto').randomBytes(64).toString('hex'))">
JWT_REFRESH_SECRET=<another long random string>
JWT_EXPIRES_IN=1h
JWT_REFRESH_EXPIRES_IN=7d
CLOUDINARY_CLOUD_NAME=your_cloud_name
CLOUDINARY_API_KEY=your_api_key
CLOUDINARY_API_SECRET=your_api_secret
SMTP_HOST=smtp.gmail.com
SMTP_PORT=465
SMTP_USER=your@gmail.com
SMTP_PASS=your_app_passwordfrontend/.env:
VITE_API_URL=http://localhost:5000/apicd backend
npm install --legacy-peer-deps # resolves multer-storage-cloudinary peer dep
npm run dev # nodemon + auto DB sync on first startSequelize auto-syncs all 19 models on first boot. No manual migration needed.
node -e "
const axios = require('axios');
axios.post('http://localhost:5000/api/auth/register', {
firstName: 'Admin', lastName: 'User',
email: 'admin@yourcompany.com',
password: 'changeme123',
roleName: 'ADMIN'
}).then(r => console.log('β
Admin ready:', r.data.data.user.email))
.catch(e => console.error(e.response?.data));
"cd ../frontend
npm install
npm run dev # http://localhost:5173curl http://localhost:5000/api/health
# {"success":true,"message":"Server is up and running"}A self-contained 7-phase integration test exercises the entire procurement lifecycle against a live server β no test framework, no mocks:
# Make sure backend is running on :5000 first
cd backend
node integration-test.js--- Phase 1: Auth ---
β
Login Successful
--- Phase 2: Vendor ---
β
Vendor Created: 5a144f02-c5ea-4cea-ac16-ae7717a4cd49
--- Phase 3: RFQ ---
β
RFQ Created: d483fa6a-c585-49a4-ac32-17ff8ccf78d8
--- Phase 4: Quotation ---
β
Quotation Submitted: cfccd191-8c75-403e-9a2e-0ef35b4ac3b4
--- Phase 5: Approval ---
β
Approval Workflow Initiated: 57a3887b-657d-42a0-bd1e-5c9d2f3bebbd
β
Quotation Approved (Workflow Step 1)
--- Phase 6: Purchase Order ---
β
PO Generated: 026020b6-5a0d-46b3-a3bb-b6b6b94c31d3
--- Phase 7: Invoice ---
β
Invoice Generated: d12b62e9-4ae3-4e8f-bff0-53cfce096795
--- TEST COMPLETE: SUCCESS ---
Reset between runs:
node clear-db.jsβ drops and recreates the public schema.
All routes under /api/* require Authorization: Bearer <token> except /api/auth/register and /api/auth/login.
| Prefix | Responsibility |
|---|---|
/api/auth |
Register, login, logout, refresh token, forgot/reset password |
/api/vendors |
Vendor CRUD, status management, category assignment |
/api/rfqs |
RFQ creation, file upload, vendor assignment, status updates |
/api/quotations |
Bid submission (Vendor), comparison fetch (Officer) |
/api/approvals |
Workflow initiation, step approve/reject with remarks |
/api/pos |
Purchase Order generation from approved quotations |
/api/invoices |
GST invoice generation from issued POs |
/api/notifications |
Real-time notification polling |
- Dashboard analytics β spending trends, vendor performance charts
- Vendor self-registration portal β vendors onboard themselves
- Multi-level approval thresholds β auto-route by PO value
- Bulk RFQ import β CSV/Excel line-item upload
- Mobile PWA β offline-ready for field procurement agents
- Webhook integrations β ERP connectors (SAP, Tally, Zoho)
# Fork, then:
git checkout -b feature/your-feature-name
git commit -m "feat: describe your change"
git push origin feature/your-feature-name
# Open a Pull RequestPlease follow Conventional Commits for commit messages.
MIT Β© 2026 VyaparSetu Team
Built with π₯ for the Hackathon
If this project helped you, drop a β β it means the world to us.
Deployed on Vercel and Render.