A full-stack web application for mapping and analyzing supply chain networks β interactive geospatial maps, live inventory and shipment tracking, and analytics computed from real operational data. Businesses can visualize their entire network on a map, monitor stock levels and deliveries in real time, and surface bottlenecks through KPIs, forecasts, and a live alerts feed.
Built end-to-end with a React 18 frontend and a Spring Boot 3.5 / Java 17 REST API, secured with stateless JWT authentication, backed by PostgreSQL with versioned Flyway migrations, covered by CI-run test suites on both tiers, and deployed with Docker on Render via Infrastructure as Code.
Live Demo: supply-chain-visualizer.onrender.com
Hosted on Render's free tier β the backend may take 1β2 minutes to wake on first visit.
- Features
- Engineering Highlights
- Tech Stack
- Quick Start
- Architecture
- Testing
- Deployment
- Contributing
- Contact
- Interactive Supply Chain Map β facility nodes and transport connections on Leaflet with performance overlays
- Inventory Dashboard β stock levels by location with critical/low/optimal/excess thresholds
- Shipment Tracker β status transitions with automatic inventory adjustment on delivery
- Analytics Workspace β on-time rate, average lead time, exception rate, SLA by lane, and lead-time variance computed from live shipment data
- Forecasting Suite β demand forecasts, seasonality signals, and safety stock guidance from real inventory levels
- Live Alerts Feed β auto-refreshing feed of delayed shipments and low-stock alerts
- Orders Hub & Network Connections β order lifecycle visibility and transport link management
- Suppliers Directory β supplier nodes with status, capacity, route coverage, and active shipment counts
- Reports β one-click CSV export of shipments, inventory, low-stock, and product data
- Audit Log β searchable, filterable history of shipment and inventory activity
- Settings β per-browser notification and display preferences
- Guest Mode β one-click, read-only demo backed by an in-memory dataset; changes reset on refresh
- Polished dark UI β custom dark theme across dashboards, modals, and map tiles, designed for long-session readability
- Layered backend architecture β controllers, DTOs, service interfaces with implementations, and JPA repositories, plus a global exception handler for consistent API errors
- Stateless security β Spring Security + JWT with token generation, validation, and role-based access; secrets injected via environment variables, never committed
- Guest mode without a backend β the frontend service layer transparently falls back to a static in-memory dataset, so the demo works instantly even while the free-tier server cold-starts
- Database as code β Flyway versioned migrations create the schema and idempotent seed data automatically on startup, across three runtime profiles (local PostgreSQL, embedded H2 demo, managed Postgres in production)
- Modernized, not greenfield β migrated the stack from Java 11 / Spring Boot 2.7 / Create React App to Java 17 / Spring Boot 3.5 / Vite, adding Flyway, OpenAPI docs, and security hardening along the way
- Automated quality gates β 93 automated tests (74 backend + 19 frontend) plus ESLint run in GitHub Actions on every push, including web-layer security tests and a Testcontainers integration test against real PostgreSQL
- Reproducible deployment β multi-stage Docker builds, a one-command local stack via Docker Compose, and a Render Blueprint that provisions the entire cloud environment in one click
| Layer | Technologies |
|---|---|
| Frontend | React 18 + Vite, Chart.js, Leaflet, Bootstrap, Axios |
| Backend | Java 17, Spring Boot 3.5, Spring Data JPA, Spring Security + JWT, springdoc-openapi |
| Database | PostgreSQL with Flyway migrations (embedded H2 profile for the free-tier demo) |
| DevOps | Docker multi-stage builds, GitHub Actions CI, Render Blueprint (IaC) |
With Docker, one command runs the full stack (PostgreSQL + API + frontend):
git clone https://github.com/mariarodr1136/SupplyChainVisualizer.git
cd SupplyChainVisualizer
docker-compose up -d
# Frontend: http://localhost:3000 | API: http://localhost:8080 | Swagger: http://localhost:8080/swagger-ui.htmlManual setup (without Docker)
Prerequisites: Node.js 18+, Java 17+ with Maven, PostgreSQL
# Backend β Flyway creates the schema and seed data automatically
createdb supply_chain_db
cd backend/supply-chain-visualizer
mvn spring-boot:run # http://localhost:8080
# Frontend (in a second terminal)
cd frontend
npm install
npm start # http://localhost:3000Database credentials are configured in backend/supply-chain-visualizer/src/main/resources/application.properties.
frontend/ # React SPA (Vite) β components, pages, services with guest-mode fallback
backend/supply-chain-visualizer/
βββ src/main/java/ # Controllers β Services β JPA Repositories, JWT security, OpenAPI config
βββ src/main/resources/ # Profile-based config + Flyway migrations (schema + seed)
.github/workflows/ci.yml # Backend + frontend test suites on every push
docker-compose.yml # Local full stack
render.yaml # Render Blueprint (Infrastructure as Code)
- REST API with resource-first endpoints for nodes, connections, inventory, shipments, products, and analytics
- Stateless JWT authentication via Spring Security; no secrets in source β all sensitive config comes from environment variables
- Interactive API docs: Swagger UI at
/swagger-ui.htmlwith JWT bearer auth support (raw OpenAPI spec at/v3/api-docs)
Full project structure
supply-chain-visualizer/
βββ frontend/ # React frontend (Vite)
β βββ index.html # Vite entry HTML
β βββ vite.config.js # Dev server, proxy, build, and test config
β βββ Dockerfile # Multi-stage build served by nginx
β βββ src/
β βββ components/ # Reusable components
β βββ pages/ # Page components
β βββ services/ # API services (with guest-mode fallback)
β βββ context/ # React context providers
β βββ data/ # Static in-memory dataset for guest mode
β βββ App.jsx # Main App component
β βββ main.jsx # Entry point
β
βββ backend/
β βββ supply-chain-visualizer/ # Java Spring Boot backend
β βββ Dockerfile # Multi-stage Docker build
β βββ entrypoint.sh # Container startup script
β βββ src/
β β βββ main/
β β β βββ java/
β β β β βββ config/ # OpenAPI (Swagger) config
β β β β βββ controller/ # API controllers
β β β β βββ dto/ # Data Transfer Objects
β β β β βββ exception/ # Global exception handler
β β β β βββ model/ # Entity models
β β β β βββ repository/ # JPA repositories
β β β β βββ security/ # JWT and security config
β β β β βββ service/ # Business logic
β β β βββ resources/
β β β βββ application.properties # Local config (PostgreSQL)
β β β βββ application-h2.properties # Live demo config (embedded H2)
β β β βββ application-render.properties # Postgres-backed production config
β β β βββ db/migration/ # Flyway migrations (schema + seed)
β β βββ test/ # 74 tests: unit, web-layer, and Postgres integration
β βββ pom.xml # Maven dependencies
β
βββ .github/workflows/ci.yml # CI: backend + frontend tests on every push
βββ docker-compose.yml # Local full-stack: PostgreSQL + API + frontend
βββ render.yaml # Render Blueprint (IaC)
API endpoints overview
Authenticate via POST /api/auth/register and POST /api/auth/login, then send the returned JWT on protected requests: Authorization: Bearer <token>.
| Category | Method | Endpoint | Description |
|---|---|---|---|
| Nodes | GET | /api/nodes |
List all supply chain nodes |
| GET | /api/nodes/:id |
Retrieve a specific node | |
| POST | /api/nodes |
Create a new node | |
| PUT | /api/nodes/:id |
Update an existing node | |
| DELETE | /api/nodes/:id |
Delete a node | |
| Connections | GET | /api/connections |
List all connections |
| POST | /api/connections |
Create a new connection | |
| PUT | /api/connections/:id |
Update a connection | |
| DELETE | /api/connections/:id |
Delete a connection | |
| Inventory | GET | /api/inventory |
List inventory across all nodes |
| GET | /api/inventory/node/:nodeId |
Inventory for a specific node | |
| GET | /api/inventory/low-stock |
List items at or below threshold | |
| POST | /api/inventory |
Add or update inventory data | |
| Shipments | GET | /api/shipments |
List all shipments |
| GET | /api/shipments/:id |
Retrieve a specific shipment | |
| POST | /api/shipments |
Create a new shipment | |
| PUT | /api/shipments/:id |
Update a shipment | |
| PUT | /api/shipments/status/:id |
Update shipment status | |
| Products | GET | /api/products |
List all products |
| GET | /api/products/sku/:sku |
Retrieve a product by SKU | |
| POST | /api/products |
Create a new product | |
| PUT | /api/products/:id |
Update a product | |
| DELETE | /api/products/:id |
Delete a product | |
| Analytics | GET | /api/analytics/summary |
KPIs, SLA by lane, lead-time variance |
Request/response schemas and a live sandbox are available in Swagger UI.
A note on demo data
Registered accounts share a single demo workspace β nodes, shipments, and inventory are common to all users, which keeps the live demo populated and interactive. Because the live demo runs on an embedded database, shared data may reset when the service is redeployed. Guest mode is fully isolated: it runs on an in-memory dataset in the browser and resets on refresh.
93 automated tests run in GitHub Actions CI on every push. The 74 backend tests (JUnit 5, Mockito, AssertJ) cover three layers: unit tests for the service and security layers (CRUD and filtering, inventory thresholds, shipment status transitions, analytics KPI calculations, JWT generation/validation), @WebMvcTest web-layer tests for auth rules, bean validation, and error response shapes, and a Testcontainers integration test that boots the app against real PostgreSQL to exercise the Flyway migrations and the register β login β authenticated request flow end to end (skipped automatically when Docker isn't available). The 19 frontend tests (Vitest + React Testing Library) cover the service layer β including the guest-mode fallback β shared components, and guest-mode rendering of the Dashboard and Shipment Tracker pages. ESLint (react + react-hooks) runs as a CI gate alongside the tests.
cd backend/supply-chain-visualizer && mvn test # backend
cd frontend && npm test # frontend
cd frontend && npm run lint # frontend lintBackend test coverage by class
| Test Class | Coverage |
|---|---|
NodeServiceImplTest |
CRUD ops, filter by type/status β 11 tests |
ProductServiceImplTest |
CRUD ops, filter by status, lookup by SKU β 12 tests |
InventoryServiceImplTest |
CRUD ops, status thresholds (critical/low/optimal/excess) β 11 tests |
ShipmentServiceImplTest |
Status transitions, inventory adjustment on delivery β 8 tests |
AnalyticsServiceImplTest |
On-time rate, exception rate, avg lead time, SLA by lane, lead-time variance β 8 tests |
JwtUtilsTest |
Token generation, username extraction, validation (valid/expired/malformed) β 7 tests |
AuthControllerTest |
Login/register endpoints: JWT response shape, invalid credentials, duplicate username, field validation errors β 6 tests |
NodeControllerTest |
Web-layer security (401 for anonymous requests), validation error bodies, 404 handling β 7 tests |
PostgresIntegrationTest |
Full app against Testcontainers PostgreSQL: Flyway schema + seed, register β login β authenticated fetch β 4 tests |
Deployed on Render via a one-click Blueprint (render.yaml):
- Backend β Dockerized Spring Boot API (multi-stage Maven β JRE build) running as a web service; the free-tier demo persists to embedded H2, and switching the profile to
renderwith an attached database runs it against managed PostgreSQL (entrypoint.shparses Render's connection string into JDBC components automatically) - Frontend β React production build served as a static site with client-side routing support
- Configuration β JWT secrets, CORS origins, and database credentials all come from environment variables
To deploy your own instance: fork the repo, create a new Blueprint in the Render Dashboard (it auto-detects render.yaml), and update the CORS/API URL environment variables after provisioning.
Issues and pull requests are welcome β feel free to open an issue first to discuss larger changes.
- Fork the repository
- Create a branch:
git checkout -b feat/your-feature-name(orfix/...for bug fixes) - Make your changes and ensure both test suites pass
- Commit with a descriptive message and push to your fork
- Open a pull request explaining your changes
Maria Rodriguez β mrodr.contact@gmail.com