An Express 5 + PostgreSQL inventory manager for tracking product categories, raw materials, and finished goods. The UI is rendered with EJS templates and enhanced with lightweight client-side scripts to prevent stock operations that would push quantities below zero.
- Create, edit, protect, and delete category records with server-side validation and optional password protection.
- Manage raw materials with category tags, stock tracking, protected entries, and a purchase flow for replenishment.
- Build products with bill of materials definitions, produce finished goods when sufficient stock of components exists, and deduct stock on sales.
- Filter listings by category and get instant feedback on production/sales availability thanks to front-end checks.
- Centralized error handling, consistent validation feedback, and graceful handling of protected records.
- Node.js with Express 5 (server, routing, middleware)
- PostgreSQL via
pg(database + connection pooling) - EJS templates and vanilla CSS/JS (presentation layer)
express-validator(input validation)dotenv(environment management)
- Node.js 18+ (tested with Node 20)
- PostgreSQL 14+ with a database dedicated to this app
npm installCreate a .env file in the project root with at least:
DB_URL=postgres://USER:PASSWORD@HOST:PORT/DATABASE
APP_PASSWORD=super-secret-password
# Optional
PORT=3000
DB_URLis the connection string used by the server and seeding script.APP_PASSWORDgates changes to protected records (setis_protectedin forms). Leave blank to disable password checks.PORTdefaults to 3000 if omitted.
The project ships with a seed script that creates tables and injects sample data (categories, materials, products, and bill of materials). Run it once after configuring your database:
node seeds/seedDB.js
# or override the connection string for one-off runs
node seeds/seedDB.js postgres://USER:PASSWORD@HOST:PORT/DATABASE- Development (auto-restarts on change):
npm run dev - Production mode:
npm start
Visit http://localhost:PORT once the server starts. The landing page links to category, material, and product dashboards.
app.js– Express bootstrap, middleware, and router wiring.router/– Route definitions for index, category, material, and product flows.controllers/– Request handlers for CRUD operations, production/sales flows, and error rendering.db/– PostgreSQL queries and transactional helpers, including bill-of-materials logic.validators/–express-validatorrule sets plus utilities to surface errors back into forms.views/– EJS templates (with partials) powering the UI.public/– Static assets (global styles plus scripts for production/sales availability checks).seeds/– Table creation and sample data loader.
- Protected Records – When
is_protectedis checked in a form, updates/deletes require the sharedAPP_PASSWORD. Attempts without the password re-render the form with inline feedback. - Material Purchase – The “Buy” action increments stock; client-side checks ensure the quantity entered is valid.
- Product Production – The “Produce” action multiplies bill-of-material requirements against desired output, verifies stock for every component, and only deducts inventory when all materials are available.
- Product Sales – The “Sell” flow prevents overselling by comparing requested quantity to the current stock in hand.
npm run dev– Start the server with file watching (node --watch).npm start– Launch the server without watching.npm test– Placeholder script; no automated tests are defined yet.
User interface icons are provided by lucide-react (MIT License). Thank you to the Lucide contributors for the beautiful icon set.
This project is released under the MIT License. See LICENSE for details.