A full-stack Inventory Management System for warehouse & retail stores with barcode/QR scanning across every symbology, real-time stocktake with a live feed, CSV upload/download of count data, and device connectivity settings (Wi-Fi, USB, Bluetooth).
Built with Next.js 15 (App Router) + TypeScript + Tailwind CSS, with a persistent JSON-file datastore (atomic writes, auto-seeded with realistic demo data on first run).
- Email/password sign-in with scrypt-hashed passwords, 7-day httpOnly session cookies, and middleware route protection.
- Three seeded roles: Admin (full access incl. deletes & data reset), Manager (manage inventory), Staff (scan & count).
| Role | Password | |
|---|---|---|
| Admin | admin@demo.com |
admin123 |
| Manager | manager@demo.com |
manager123 |
| Staff | staff@demo.com |
staff123 |
- KPI cards (SKUs, stock value, low/out-of-stock), 14-day in/out movement chart, stock-health donut, value-by-category bars, recent activity, low-stock alerts and a live stocktake progress banner.
- Camera scanner via
html5-qrcodesupporting EAN-13/8, UPC-A/E, Code 128/39/93, ITF, Codabar, QR, Data Matrix, Aztec, PDF-417. - Universal lookup endpoint: any barcode value, SKU, name, or QR payload (
IMS|SKU|BARCODE). - Instant item detail card: stock, price, margin, pick location, supplier, scannable barcode (JsBarcode) + QR art, movement history.
- Manual entry, scan history, optional beep-on-scan, and demo chips built from real catalog codes. Unknown codes offer one-click product creation with the barcode pre-filled.
- Push a scan straight into an active stocktake's live feed.
- Search/filter/sort/paginate; create & edit via modal forms; delete with confirmation and referential protection.
- Optimistic quick +/− stock steppers with rollback + toast on failure.
- Product drawer with rendered barcode/QR, location, and movement trail.
- Movements ledger (stock in / out / adjustments) with filters and audit details.
- Create sessions scoped to a warehouse zone (or all zones); expected quantities snapshotted at count time.
- Live feed over Server-Sent Events — every scan/manual count from any terminal streams in real time (with a 5s polling fallback). Includes a one-click "simulate handheld terminal" demo mode.
- Count sheet with expected vs counted vs variance highlighting, progress, net variance.
- Download the count sheet as CSV (expected/counted/variance/status) and a pre-filled template.
- Upload CSV counts (parsed client-side with PapaParse, previewed, then merged server-side) with skip reporting.
- Completing a session applies variances to stock as adjustment movements; sessions can also be voided.
- Profile: name, email, password change.
- Store & Preferences: store name/type, currency, language, low-stock threshold, default zone, alert + beep-on-scan toggles (optimistic saves).
- Devices & Connectivity: Wi-Fi networks (scan, join with password, signal strength, IP), USB peripherals (scanners, label printers), Bluetooth devices (discovery with RSSI/battery, pair, connect, forget) — all persisted.
- Data & Team: JSON backup export, team roster, admin-only demo-data reset.
- Responsive layout with collapsible mobile sidebar, global product search in the topbar, low-stock notification bell.
- Empty states everywhere, skeleton loading states, toasts, optimistic updates, animated live-feed entries.
- Seeded with 53 realistic products, 8 suppliers, 8 categories, ~150 movements over 30 days, 3 stocktake sessions (1 live), and 6 connected devices so the app feels alive on first load.
npm install
npm run dev # http://localhost:3000The database (data/db.json) is created and seeded automatically on the first request — no setup needed. Sign in with any demo account above.
Production:
npm run build
npm startReset to pristine demo data at any time from Settings → Data & Team → Reset demo data (Admin), or delete data/db.json and restart.
src/
├── app/
│ ├── (main)/ # authenticated shell (sidebar + topbar layout)
│ │ ├── dashboard/ products/ scan/ stocktake/ stocktake/[id]/
│ │ ├── movements/ categories/ suppliers/ reports/ settings/
│ ├── api/ # REST endpoints (auth, CRUD, lookup, stocktake SSE/export/import, devices…)
│ └── login/
├── components/ # UI kit, charts, scanner, barcode/QR art, forms
├── lib/ # db store, seed data, auth, event bus, csv, helpers
└── middleware.ts # session gate for pages & APIs
- Persistence: single JSON file with atomic temp-write + rename, in-process cache on
globalThis(HMR-safe). - Live feed: in-process pub/sub bus → SSE route handler; counts POST → broadcast to all subscribers.
- Auth: scrypt password hashing, token sessions stored in the DB, validated on every API request.
| Method | Endpoint | Purpose |
|---|---|---|
| POST | /api/auth/login · /api/auth/logout |
Session management |
| GET/POST · PUT/DELETE | /api/products · /api/products/[id] |
Product CRUD |
| POST | /api/products/[id]/adjust |
Quick stock adjustment |
| GET | /api/lookup?code= |
Universal barcode/QR/SKU lookup |
| GET/POST · PUT/DELETE | /api/categories, /api/suppliers, /api/movements |
Resource CRUD |
| GET/POST · PATCH | /api/stocktake · /api/stocktake/[id] |
Sessions (complete applies variances, void discards) |
| GET/POST | /api/stocktake/[id]/counts |
Record counts (broadcasts to live feed) |
| GET | /api/stocktake/[id]/events |
SSE live stream |
| GET · POST | /api/stocktake/[id]/export · /import |
CSV download / upload |
| GET/PATCH | /api/settings · /api/devices · /api/devices/discover |
Settings & connectivity |
| GET · POST | /api/data/export · /api/data/reset |
Backup & reseed |