A full-stack web application for managing timber mill operations — from raw log intake to sawn-size production and outgoing dispatch, with real-time inventory tracking, role-based access control, and rich reporting.
- 📦 Inventory Management — Track incoming log batches and sawn-size stock in real time, with per-unit detail (log number, girth, length, volume).
- 🚛 Operations Tracking — Record outgoing batches with vehicle number, permit number, party details, and associated log/sawn-size usage.
- 📊 Reports & Registers — Generate stock statements for round logs and sawn sizes by date range or grouped by month. Export to Excel or PDF instantly.
- 🧑💼 Role-Based Access Control — Four distinct roles (
superadmin,admin,data_entry,report_viewer) each with precisely scoped permissions. - 🏭 Multi-Mill Support — A superadmin can create and manage multiple mills, freeze/unfreeze accounts, and reset admin passwords.
- 📋 Audit Logs — Every create and delete action is logged with the acting user and timestamp.
- 🌲 Master Data — Manage timber types (with scientific names), parties, sources, and source types per mill.
- 🔐 JWT Authentication — Stateless Bearer-token auth with per-request user & mill validation.
| Layer | Technology |
|---|---|
| Frontend | React 18, Vite, Tailwind CSS, Zustand, React Router v6 |
| UI Icons | Lucide React |
| Exports | ExcelJS, jsPDF + jsPDF-AutoTable |
| Date Picker | react-datepicker |
| Backend | Node.js, Express 5 |
| ORM | Prisma 5 |
| Database | PostgreSQL |
| Auth | JWT (jsonwebtoken), bcrypt |
| Dev Tools | Nodemon, ESLint |
MillX-V1/
├── backend/
│ ├── prisma/
│ │ ├── schema.prisma # Database schema & models
│ │ └── seed.js # Superadmin seeder
│ ├── src/
│ │ ├── controllers/
│ │ │ ├── authController.js
│ │ │ ├── dashboardController.js
│ │ │ ├── incomingController.js
│ │ │ ├── masterController.js
│ │ │ ├── outgoingController.js
│ │ │ ├── recordsController.js
│ │ │ ├── reportController.js
│ │ │ ├── superadminController.js
│ │ │ └── userController.js
│ │ ├── middlewares/
│ │ │ ├── auth.js # JWT verification
│ │ │ └── rbac.js # Role-based authorization
│ │ ├── routes/
│ │ │ ├── api.js # All API routes
│ │ │ └── records.js
│ │ └── index.js # Express entry point
│ └── package.json
│
└── frontend/
├── public/
│ └── logo.png
├── src/
│ ├── components/
│ │ └── Layout.jsx # App shell with sidebar nav
│ ├── pages/
│ │ ├── Dashboard.jsx
│ │ ├── DataEntry.jsx
│ │ ├── Login.jsx
│ │ ├── Masters.jsx
│ │ ├── Records.jsx
│ │ ├── Registers.jsx
│ │ ├── Reports.jsx
│ │ ├── SuperAdminDashboard.jsx
│ │ └── UserManagement.jsx
│ ├── store/
│ │ └── useAuth.js # Zustand auth store
│ └── utils/
│ ├── api.js # Axios instance
│ └── dateFormatter.js
└── package.json
- Node.js v18 or higher
- PostgreSQL database (local or hosted)
- npm (comes with Node.js)
git clone https://github.com/sid-rudani/MillX-V1.git
cd MillX-V1cd backend
npm installCreate a .env file in the backend/ directory:
DATABASE_URL="postgresql://USER:PASSWORD@localhost:5432/millx_db"
JWT_SECRET="your-super-secret-jwt-key"
PORT=5000Run database migrations and seed the superadmin account:
npx prisma migrate dev --name init
node prisma/seed.jsStart the backend server:
# Development (with auto-reload)
npm run dev
# Production
npm startThe API will be available at http://localhost:5000.
cd ../frontend
npm installCreate a .env file in the frontend/ directory:
VITE_API_BASE_URL=http://localhost:5000/apiStart the development server:
npm run devThe app will be available at http://localhost:5173.
⚠️ Change these immediately after first login.
| Role | Password | |
|---|---|---|
| Superadmin | superadmin@millx.com |
SuperAdmin@123 |
| Admin (auto-seeded on first boot) | admin@millx.com |
Admin@1234 |
| Permission | superadmin |
admin |
data_entry |
report_viewer |
|---|---|---|---|---|
| Manage mills | ✅ | — | — | — |
| Manage users | — | ✅ | — | — |
| View dashboard | ✅ | ✅ | ✅ | ✅ |
| Manage masters | — | ✅ | — | — |
| Create incoming batch | — | ✅ | ✅ | — |
| Create outgoing batch | — | ✅ | ✅ | — |
| View in-stock inventory | — | ✅ | ✅ | ✅ |
| View & edit records | — | ✅ | — | — |
| View audit logs | — | ✅ | — | — |
| View reports & registers | — | ✅ | — | ✅ |
Mill ──< User
──< TimberType
──< Party
──< Source / SourceType
──< IncomingBatch ──< LogInventory ──< LogUsage ──> OutgoingBatch
──< SawnSizeInventory ──< SawnSizeUsage ──> OutgoingBatch
──< OutgoingBatch ──< OutgoingSawnSize
──< AuditLog
Key models:
LogInventory— Individual round logs with log number, length, girth, and calculated volume. Status:IN_STOCK→UTILIZED.SawnSizeInventory— Sawn timber items with thickness, width, length, quantity, and volume. Supports reeperboard classification.OutgoingBatch— A dispatch event that consumes logs/sawn sizes and records newly produced sawn sizes.AuditLog— Immutable record of all create/delete operations with actor, entity, and details.
All routes are prefixed with /api.
| Method | Route | Role Required | Description |
|---|---|---|---|
POST |
/auth/login |
Public | Authenticate and receive JWT |
GET |
/auth/me |
Any | Get current user profile |
GET |
/dashboard |
Any | Aggregated mill stats |
GET/POST/PUT/DELETE |
/timberType |
Any / Admin | Timber type CRUD |
GET/POST/PUT/DELETE |
/party |
Any / Admin | Party CRUD |
GET/POST/PUT/DELETE |
/source |
Any / Admin | Source CRUD |
GET/POST/PUT/DELETE |
/sourceType |
Any / Admin | Source type CRUD |
POST |
/incoming |
Admin, Data Entry | Create incoming batch |
GET |
/inventory/in-stock |
Admin, Data Entry, Viewer | Get current stock |
POST |
/outgoing |
Admin, Data Entry | Create outgoing batch |
GET |
/records/incoming |
Admin | List all incoming records |
GET |
/records/outgoing |
Admin | List all outgoing records |
DELETE |
/records/incoming/:id |
Admin | Delete incoming batch |
DELETE |
/records/outgoing/:id |
Admin | Delete outgoing batch |
GET |
/records/audit-logs |
Admin | View audit trail |
GET |
/reports |
Admin, Viewer | Stock statement report |
GET |
/reports/registers |
Admin, Viewer | Movement register |
GET |
/superadmin/mills |
Superadmin | List all mills |
POST |
/superadmin/mills |
Superadmin | Create a mill |
PUT |
/superadmin/mills/:id/status |
Superadmin | Freeze / unfreeze mill |
Reports and registers can be exported directly from the browser:
- Excel (
.xlsx) — via ExcelJS, formatted with mill header and column totals. - PDF (
.pdf) — via jsPDF + AutoTable, print-ready with tabular layout.
Backend:
npm run dev # Start with nodemon (hot-reload)
npm start # Start production server
npx prisma studio # Open Prisma GUI for database inspectionFrontend:
npm run dev # Vite dev server with HMR
npm run build # Production build to dist/
npm run preview # Preview the production build locally
npm run lint # ESLint check- Fork the repository
- Create your feature branch:
git checkout -b feature/your-feature - Commit your changes:
git commit -m 'Add some feature' - Push to the branch:
git push origin feature/your-feature - Open a Pull Request
This project is licensed under the ISC License.
Built with 🌲 for the timber industry


