Deploying QuickDumpNow Dispatch Tool to Production: Job Creation, CloudFront Invalidation, and Rewrite Rule Updates

What Was Done

This deployment pushed the QuickDumpNow dispatch platform to production, including updates to the Cloudflare Workers rewrite function, promotion of the dashboard and tracking pages from staging to production, creation of a new job record for a customer named Mark, and cache invalidations across CloudFront distributions. The work involved coordinating multiple infrastructure layers: a Cloudflare Workers function handling URL rewrites, S3-backed static assets, CloudFront edge caching, and a JSON job database.

Technical Details: The Dispatch System Architecture

The QuickDumpNow dispatch tool operates on a relatively simple but effective architecture:

  • URL Routing Layer: /Users/cb/Documents/repos/sites/quickdumpnow.com/cf/qdn-track-rewrite.js — A Cloudflare Workers script that intercepts requests and rewrites URLs. Before this deployment, it only handled /track/* paths. We extended it to also rewrite /book/* paths, allowing both customer tracking and booking flows to be served from the same static asset pool.
  • Job Storage: A jobs.json file stored in S3 containing job metadata (customer name, address, job status, tracking tokens, pricing). This is the single source of truth for all dispatch records.
  • Frontend Assets: Two primary HTML/JS applications:
    • Dashboard (qdn-dashboard.html) — Internal dispatch view showing all jobs as kanban cards, status flows, and job assignment UI
    • Customer Track Page (track.html) — Public-facing page where customers can view their job status using a tracking token
  • Edge Caching: CloudFront distributions sitting in front of the S3 origin, with separate distribution IDs for the main domain and asset paths. Cache invalidation is critical when pushing new code.

Deployment Steps and Rationale

1. Cloudflare Workers Function Update

The CF function needed modification to support booking pages alongside tracking pages. The original logic was:

if (request.pathname.startsWith('/track/')) {
  return rewriteToStaticAsset('/track.html');
}

We extended this to:

if (request.pathname.startsWith('/track/')) {
  return rewriteToStaticAsset('/track.html');
}
if (request.pathname.startsWith('/book/')) {
  return rewriteToStaticAsset('/book.html');
}

Why: This allows both customer flows (tracking existing jobs and booking new ones) to share the same deployment pipeline without requiring separate domain routing or API endpoints.

The function was fetched with its current ETag (for version control), modified locally, and published to the LIVE stage with full output capture to verify the deployment succeeded.

2. Job Creation for Mark

A new job record was generated with the following workflow:

  • Generated a unique job ID (UUID format)
  • Created a tracking token (cryptographically random, 32+ characters)
  • Built Mark's job JSON structure:
    {
      "job_id": "fcdc1c82cb284dbe",
      "customer_name": "Mark",
      "address": "Soderblom Ave",
      "status": "scheduled",
      "pickup_date": "[timestamp for this afternoon]",
      "price": 600,
      "currency": "USD",
      "tracking_token": "[secure random token]",
      "created_at": "[ISO timestamp]"
    }
  • Uploaded this record to jobs.json in S3

Why the token-based approach: Rather than exposing job IDs directly, we use secure tracking tokens. This means even if someone guesses a job ID, they cannot access the job details without the token. Tokens are shared only via SMS/email to the customer.

3. Static Asset Promotion

Three assets were promoted from staging to production:

  • Dashboard: qdn-dashboard.html — Contains the kanban UI, status pill rendering, and job assignment logic
  • Track Page: track.html — Contains token extraction, API fetch logic, and status display
  • Booking Pages: book.html and related assets

Promotion meant copying from the staging S3 prefix to the production prefix. For example:

aws s3 cp s3://quickdumpnow-staging/dashboard.html s3://quickdumpnow-prod/dashboard.html

Why staging first: The staging environment allows full QA without affecting customer-facing pages. Once validated, the same assets move to prod without rebuild, ensuring identical behavior.

4. CloudFront Cache Invalidation

Two cache invalidations were issued:

  • Dashboard distribution: Invalidated all paths to flush the old dashboard code
  • Main quickdumpnow.com distribution: Invalidated /track/* and /book/* paths to ensure the new rewrite rules take effect immediately

Invalidation commands take the form:

aws cloudfront create-invalidation \
  --distribution-id [DIST_ID] \
  --paths "/track/*" "/book/*"

Why not wait for TTL expiry: CloudFront default TTLs are often 24 hours or longer. Customers hitting the site immediately after deploy would receive stale HTML with old JavaScript logic. Invalidation forces a fresh origin fetch, ensuring they get the new code instantly.

Resolving Mark's Tracking Link Error

After deployment, Mark's tracking link returned "Job not found, or this tracking link is no longer valid." This was traced to:

  1. Token extraction issue: The track page's JavaScript was not correctly extracting the tracking token from the URL fragment or query string.
  2. Job lookup failure: Even with a token, the fetch to the job API endpoint was failing silently, and the error handler was showing the generic "not found" message.
  3. Cache timing: The CloudFront cache had old versions of the track page that predated the job creation.

Resolution: We patched the track page's token extraction logic, re-promoted to production, invalidated the CloudFront distribution, and verified the API endpoint directly with Mark's token. The tracking link now resolves correctly on mobile browsers (the original error was observed on a phone).

Key Infrastructure Decisions

  • Stateless frontend with S3/CloudFront: The dashboard and track pages are pure HTML/JavaScript, with no server state. This makes scaling trivial and deployment safe — there are no databases to lock or sessions to migrate.
  • jobs.json as source of truth: Rather than a database, we use a single JSON file in S3. This simplifies the architecture, makes backups trivial, and allows version control integration. For a dispatch system handling dozens of jobs per day, this scales adequately.
  • Cloudflare Workers for routing: Instead of