NexStock
A production-ready MERN inventory & stock management platform with RBAC, server-side pagination, and a glassmorphic analytics dashboard.
The problem
Off-the-shelf inventory systems are either enterprise-priced or stripped to the point of uselessness for small-to-mid retail. Owners want role separation (the cashier shouldn't see margins), real metrics they can act on, and a UI that doesn't require training. I built NexStock to hit all three without an enterprise budget.
The solution
A full-stack web app with a glassmorphic React 19 frontend and an Express 5 + MongoDB backend. Three user roles cover the org chart; server-side pagination & debounced search keep large catalogues usable; and four dedicated Chart.js dashboards turn raw transactions into decisions.
Security defaults are non-negotiable: JWT in httpOnly cookies, Helmet security headers, bcrypt password hashing, strict CORS, and global rate limiting (300 req/15 min).
Architecture at a glance
Browser │ HTTPS, JWT in httpOnly cookie ▼ Vercel (React 19 + Vite frontend) │ fetch → CORS whitelist → Render API ▼ Render (Express 5 API) │ Mongoose models · express-validator · centralised error middleware │ ├── Auth middleware → role-based route guards ├── Cloudinary SDK → product image uploads └── MongoDB Atlas → aggregation pipelines for dashboards
Technical highlights
Role-based access control (RBAC)
Three roles (Admin, Store Manager, Employee) with granular permissions enforced twice — frontend route guards for UX, backend middleware for security. The middleware layer is the source of truth; the frontend guards just keep the UI honest.
Analytics dashboards
Four Chart.js visualisations: real-time stock levels, category distribution, transaction trends, and total inventory value. Each chart is backed by a dedicated aggregation pipeline rather than client-side number-crunching.
Split Vercel + Render deployment
Frontend on Vercel for fast edge delivery; API on Render for a long-running Node process and Mongo connection pooling. Cross-domain auth solved with JWT in httpOnly cookies, strict CORS whitelist, and a SameSite=None policy.
Lessons learned
- Cross-domain auth needs both ends in sync. Vercel + Render is great, but the SameSite=None cookie + CORS whitelist + strict origin checks had to be tested end-to-end — local dev hid every bug.
- Aggregation pipelines beat client-side math. Pushing dashboard maths to Mongo cut the "dashboard" route from hundreds of kB of JSON to a single rolled-up document.
- RBAC enforced twice ≠ duplicated logic. Frontend guards prevent UI confusion (no broken-link clicks); backend middleware is the actual security boundary. Both, never one.