All Projects
Confidential context: Operations companyWorkflow systemLiveConfidential-safe

ERP System

Scattered spreadsheets became one production ERP across job orders, quotations, inventory, and sales.

ERP System cover screenshot

How the project is put together

Architecture map

6 layers / 5 directed links

100%

callsorchestratespersistsprotected byships through
  1. 01
    Interface

    Role-aware ERP screens for jobs, inventory, quotations, sales, warranties, and administration.

    Angular 21 / PrimeNG / Tailwind CSS / FullCalendar
  2. 02
    Application

    Typed frontend services and access guards coordinate module state and API boundaries.

    Angular services / Guards / Interceptors / RxJS
  3. 03
    Services/API

    REST controllers, realtime events, uploads, validation, and quotation PDF generation.

    Node.js / Express / Socket.IO / PDFKit
  4. 04
    Data

    Flexible business documents, inventory movements, users, products, and persistent uploaded files.

    MongoDB 7 / Mongoose / Uploads volume
  5. 05
    Auth/Permissions

    Module/action-level access control across admin, manager, and staff workflows.

    JWT / bcrypt / Roles / Granular permissions
  6. 06
    Runtime

    Containerized frontend, API, database, volumes, and deploy path for single-VPS operations.

    Docker Compose / Nginx / GHCR / Dokploy

From broken workflow to operating system

Manual tracking across spreadsheets and disconnected documents.

A role-based production system with real-time dashboards, backups, and VPS deployment.

The workflow constraint

The client relied on scattered spreadsheets and manual workflows for job tracking, quotations, and inventory. They needed a unified system with real-time dashboards, access control, and automated workflows.

What changed

Unified 6 business modules into single platform
Real-time dashboard with WebSocket updates
Automated weekly backups with one-command restore
Running in production on single VPS with Docker

Decisions and trade-offs

MongoDB over SQL for this use case

ERP data (job orders, quotations, products) has variable schemas across clients and flexible document structures.

Decision: Chose MongoDB with Mongoose ODM for flexible schemas and fast iteration on changing business requirements.

Trade-off: Lost relational integrity guarantees, mitigated with application-level validation and Mongoose schema enforcement.

Socket.IO for real-time updates

Job order status changes need to reflect immediately across multiple users viewing the dashboard.

Decision: Added Socket.IO for real-time event broadcasting when job orders, quotations, or inventory items are modified.

Trade-off: Added WebSocket server complexity, but eliminated manual refresh patterns and improved team coordination.

Single VPS with Docker Compose over cloud-managed services

Client has a fixed budget and wants predictable costs without pay-per-use cloud pricing.

Decision: Dockerized everything (frontend, backend, database) on a single VPS with automated backup scripts and Cloudflare for SSL/CDN.

Trade-off: Manual infrastructure management vs managed cloud, but predictable $20-40/mo cost with full control.

Constraints, architecture, and proof

Angular 21 SPA served via Nginx (port 80) reverse-proxying to Node.js/Express API (port 5555), MongoDB with auth enabled. Docker Compose orchestrates all three services with persistent volumes for uploads and database. Cloudflare handles SSL termination, CDN, and DDoS protection.

Must run on a single VPS (4-8GB RAM) with Docker Compose
Real-time updates for job order status changes across users (WebSocket)
Role-based access: admin, manager, staff with granular permissions
Automated weekly database backups with restore capability
Rate limiting: 100 req/min general, 5 login attempts per 15 min

Deployment, security, and maintenance

Helmet.js for HTTP security headers, bcrypt password hashing, JWT authentication with refresh tokens, express-rate-limit on all endpoints (strict on auth routes), CORS whitelist, input validation via express-validator, Winston structured logging, MongoDB authentication enabled.

What I would improve next

Add automated reporting and PDF generation for quotations
Implement notification system for overdue job orders
Add multi-tenant support for managing multiple client companies

Screenshots from the build