Overview / Technical Docs / Installation
Freight Quote Tool · Installation

Installation — first-time setup

How to stand the tool up from scratch in a Cloudflare account. Normally Rogue Agents does this for Keystone; these notes let Keystone (or anyone) do it themselves. For day-to-day use see the Usage guide; for ongoing upkeep see Maintenance.

The tool is one Cloudflare Worker + a D1 database + static files, gated by Cloudflare Access. Hosting it costs little to nothing on Cloudflare's free/low tiers.

Prerequisites

  • Node.js 18+ and npm.
  • A Cloudflare account (the Worker, D1, and Access all live here).
  • UPS API credentials — an OAuth client ID + secret for a UPS developer app tied to the shipping account, with Rating API access.
  • This source code (a clone or the provided .zip, unzipped).

1. Install dependencies

cd keystone-freight-tool
npm install

2. Sign in to Cloudflare

npx wrangler login        # opens a browser to authorize

3. Create the database and tables

npx wrangler d1 create keystone-freight

Copy the database_id it prints into wrangler.jsonc (the d1_databases[0].database_id field). Then create the tables:

npm run db:remote         # applies schema.sql to the live D1

schema.sql creates everything, including the price column — a fresh install needs no migration. (The ALTER TABLE note in schema.sql is only for upgrading an older database that predates price.)

4. Set UPS credentials and settings

Secrets (never stored in the repo):

npx wrangler secret put UPS_CLIENT_ID
npx wrangler secret put UPS_CLIENT_SECRET

Non-secret settings live in wrangler.jsonc under vars — set these to the shipper's values:

  • UPS_STUB"0" for live UPS rates ("1" serves fake demo rates with no credentials).
  • ORIGIN_ZIP, ORIGIN_STATE — the ship-from location (default 46514 / IN, Elkhart).
  • UPS_ACCOUNT — the UPS account number.

5. Deploy

npm run deploy

This publishes the Worker and prints its *.workers.dev URL.

6. Gate sign-in with Cloudflare Access

The Worker itself doesn't authenticate — put Cloudflare Access (Zero Trust) in front of it so only approved emails get in:

  1. In the Cloudflare dashboard → Zero Trust → Access → Applications → Add an application → Self-hosted.
  2. Point it at the Worker's hostname.
  3. Add a policy that allows the right people — e.g. an "Emails ending in" rule for the company domain (@keystonerecognition.com), plus any individual support addresses. Use the One-time PIN login method.
  4. Save. Visiting the URL now prompts for an email, then a one-time code.

Full details and the scriptable API version are in Maintenance ("Who can sign in").

7. Load the catalog

Sign in, open Admin → Catalog, and upload the product export (.xlsx or .csv) — see the catalog format in Maintenance. The tool replaces its catalog with the file and reports how many products loaded.

You're live. Quote a known part number to confirm real rates come back.

Running locally (development)

cp /dev/null .dev.vars                                  # then add the two UPS keys:
printf 'UPS_CLIENT_ID=...\nUPS_CLIENT_SECRET=...\n' >> .dev.vars   # gitignored
npm run fixture     # writes fixtures/catalog-sample.csv (synthetic catalog)
npm run db:local    # creates the local D1 tables
npm run dev         # http://localhost:8787  (shows "dev@local — no Access")

Upload fixtures/catalog-sample.csv via Admin → Catalog and quote away. With no UPS keys set, it serves stub rates; with keys in .dev.vars, it serves live rates.