Skip to content

Victor-Caceres/nodevantage

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NodeVantage

A fulfillment network optimization platform for logistics consultants. Upload client order history and carrier rate data, configure constraints, and get zip-code-level fulfillment center placement recommendations scored on cost, speed, and sustainability.

Live: https://nodevantage.vercel.app


The Problem

Fulfillment network design is one of the highest-leverage decisions in e-commerce logistics — and one of the least data-driven in practice. Most consultants are doing this work in Excel: manually mapping order volumes, eyeballing zone distributions, and building cost models that break every time a carrier updates their rate card.

NodeVantage is a first attempt at productizing that process. It's built on a problem space I know well from logistics consulting work, and designed around the actual inputs consultants have access to: order history CSVs and carrier rate cards.


The Core Design Decisions

Zone lookup is isolated by design.

Zone depth — the primary speed proxy in the scoring model — is approximated using straight-line distance between zip code centroids. That logic lives in a single isolated module (zone_lookup.py) that owns all zone math and is intentionally decoupled from the optimizer. The MVP uses distance bands mapped to carrier zones (0–50 miles → Zone 2, 1200+ miles → Zone 8). Swapping this for a live carrier API requires changing one module — nothing else.

The scoring pipeline is deterministic.

Every FC recommendation traces back to a formula. Order assignment uses a weighted score across three components — cost (inverse of DIM-adjusted billable rate), speed (inverse of zone depth), and sustainability (zone depth proxy at MVP). Weights are user-configurable. There are no black box outputs: every number in the results has a traceable source.

Rate cards are carrier-agnostic.

The system doesn't hard-code carrier logic. Each rate card is uploaded as a CSV with a defined schema — carrier, service level, origin zip prefix, destination zone, weight bracket, rate, transit days — and a DIM divisor captured at upload time. UPS Ground, FedEx 2-Day, a regional carrier, a fictional carrier: the optimizer doesn't care. Multiple rate cards participate in scoring simultaneously, so cross-carrier cost comparisons happen automatically.


How It Works

  1. Upload order history CSV and one or more carrier rate cards
  2. Configure optimization: KPI weights, FC count, locked and flexible existing FCs
  3. The backend parses inputs and runs K-means clustering on destination zips
  4. The scoring engine assigns each order to the best FC by weighted score — locked FCs honored as hard constraints, flexible FCs always included without consuming recommendation slots
  5. Results are persisted to Supabase with a job ID written to the URL
  6. The frontend renders FC cards with per-carrier cost breakdowns and a Leaflet map — results survive page refresh and can be shared or revisited by URL

Try It

The live instance at nodevantage.vercel.app is the intended entry point.

Sample data is included in the repo under sample-data/ if you want to run a real analysis without building your own files:

  • sample_orders.csv — 500 synthetic orders with destination zips, dimensions, and weight
  • sample_rates_ups_ground.csv, sample_rates_ups_2day.csv, sample_rates_fedex_ground.csv — rate cards for three carrier/service level combinations

Upload the order history, upload one or more rate cards with carrier metadata, configure your constraints, and run the analysis.


What the Results Show

Each recommended FC includes:

  • Zip code and city/state
  • Orders assigned and coverage percentage
  • Average zone depth across assigned orders
  • Per-carrier, per-service-level cost breakdown with billable weight and cost per order
  • FC type badge: Recommended, Locked FC, or Flexible FC

Results are plotted on an interactive map with distinct markers per FC type.


Stack

Layer Choice
Frontend React + Vite + Tailwind + Leaflet.js
Backend Python + FastAPI
Database Supabase (PostgreSQL)
Frontend hosting Vercel
Backend hosting Render
Keep-alive UptimeRobot pinging /ping every 5 minutes

Project Structure

nodevantage/
├── backend/
│   ├── app/
│   │   ├── data/
│   │   │   └── uszips.csv
│   │   ├── db/
│   │   │   └── supabase.py
│   │   ├── models/
│   │   │   └── schemas.py
│   │   ├── routers/
│   │   │   ├── analysis.py
│   │   │   ├── jobs.py
│   │   │   └── upload.py
│   │   ├── services/
│   │   │   ├── csv_parser.py
│   │   │   ├── dim_weight.py       # isolated DIM weight logic
│   │   │   ├── optimizer.py
│   │   │   ├── scorer.py
│   │   │   └── zone_lookup.py      # isolated zone approximation
│   │   └── main.py
│   ├── tests/
│   │   ├── test_db.py
│   │   ├── test_optimizer.py
│   │   └── test_services.py
│   ├── .env.example
│   ├── render.yaml
│   └── requirements.txt
├── frontend/
│   ├── public/
│   │   ├── nodevantage_carrier_rates_template.csv
│   │   └── nodevantage_order_history_template.csv
│   ├── src/
│   │   ├── components/
│   │   │   ├── ConfigPanel.jsx
│   │   │   ├── FCCard.jsx
│   │   │   ├── ResultsMap.jsx
│   │   │   ├── ResultsTable.jsx
│   │   │   └── UploadPanel.jsx
│   │   ├── lib/
│   │   │   ├── api.js
│   │   │   └── supabaseClient.js
│   │   ├── pages/
│   │   │   ├── Analysis.jsx
│   │   │   └── Home.jsx
│   │   ├── App.jsx
│   │   ├── index.css
│   │   └── main.jsx
│   ├── index.html
│   ├── package.json
│   ├── tailwind.config.js
│   └── vite.config.js
├── sample-data/
│   ├── sample_orders.csv
│   ├── sample_rates_fedex_ground.csv
│   ├── sample_rates_ups_2day.csv
│   └── sample_rates_ups_ground.csv
├── supabase_schema.sql
└── README.md

Built As

A portfolio project anchored in a problem space I know well from logistics consulting. My first end-to-end solo build — planned using a structured five-phase product and engineering framework before any code was written, then built and deployed using Claude Code.

Built by Victor Caceres · LinkedIn

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors