Building HELM: An Interactive Operations Graph for Multi-Platform Booking & Dispatch

We just deployed HELM — a real-time interactive operations visualization system for Queen of San Diego's entire booking-to-dispatch pipeline. This post documents the architecture, infrastructure decisions, and why we built it as a single self-contained HTML file deployed to a dedicated CloudFront distribution.

What Was Built

HELM is an interactive force-directed graph that visualizes:

  • Customer acquisition channels: organic search, email campaigns, referral partner codes, Viator, Boatsetter, GetMyBoat, and future platforms
  • Revenue streams: live nodes for active platforms, greyed-out nodes for known but inactive channels
  • Booking flow: how customers move from channel → booking confirmation → payment processing
  • Operational dashboards: each internal tool (crew dispatch, expense tracking, email automation) as drillable nodes
  • System health: real-time probe results from Google Apps Script functions with visual node state feedback (green/red glow)

The entire application lives in a single HTML file: /Users/cb/Documents/repos/sites/helm/index.html

Technical Architecture

Why a Single HTML File?

We chose a monolithic HTML approach for several reasons:

  • Zero build step: No webpack, no npm install, no deployment pipeline complexity. One file = one source of truth.
  • Self-contained: All dependencies (vis-network for graph rendering, no external CSS framework) bundled inline. Works offline with local data.
  • Fast iteration: Edit in place, deploy once, CloudFront cache invalidation handles distribution.
  • Security posture: No dynamic data fetching from multiple origins; health checks call GAS endpoints directly via CORS-enabled Apps Script deployments.

Graph Visualization Engine

We use vis-network for force-directed physics simulation. Why not D3 or Cytoscape?

  • vis-network's physics engine automatically prevents node overlap and creates readable layouts
  • Built-in interactivity: drag-to-pan, scroll-to-zoom, click-to-select
  • Minimal configuration needed; sensible defaults for edge rendering and physics damping
  • Smaller bundle footprint than D3 + plugins

Node structure defined in a NODE_DATA object with properties:

id: "gas_crewdispatch"
label: "Crew Dispatch"
category: "operations"
description: "Crew assignment, SMS notification, schedule management"
gasFunction: "trackCrewDispatchHealth"

Edges connect categories (e.g., "booking_flow" → "payment_processing") and include metadata about data dependencies.

Health Probing System

Each operational node can poll a corresponding Google Apps Script function:

// In HELM's client-side code:
fetch('https://script.google.com/macros/d/{DEPLOYMENT_ID}/usercallable')
  .then(r => r.json())
  .then(data => updateNodeHealth(nodeId, data.status))

GAS functions extracted from key files:

  • /repos/gas_main/Code.gs — primary entry points
  • /repos/gas_crewdispatch/Code.gs — crew health checks
  • /repos/gas_expenses/Code.gs — expense tracker status

Node visual state updates based on probe latency and response status:

  • Green glow: Function executed, data fresh (<60s old)
  • Yellow glow: Stale data (60s–5min)
  • Red glow: Function timeout or error

Infrastructure & Deployment

AWS Resources Provisioned

S3 Bucket: helm.queenofsandiego.com

aws s3 mb s3://helm.queenofsandiego.com --region us-west-2

Bucket policy restricts access to CloudFront origin only (via OAC — Origin Access Control).

CloudFront Distribution: New distribution created with:

  • Origin: S3 bucket with OAC (not legacy OAI)
  • Default root object: index.html
  • Cache behaviors: 1-hour TTL for index.html, 30-day TTL for static assets
  • Compression: GZIP enabled for HTML/JS/CSS
  • Security headers added via CloudFront function

Route53 ALIAS Record: Created CNAME-less alias pointing helm.queenofsandiego.com to CloudFront distribution domain

Type: A (IPv4)
Name: helm.queenofsandiego.com
Target: <CloudFront distribution domain>
Evaluate Target Health: Yes

ACM Certificate: Existing wildcard for *.queenofsandiego.com attached to distribution

Deployment Process

  1. Edit index.html locally with node/edge definitions and health probe endpoints
  2. Upload to S3: aws s3 cp helm/index.html s3://helm.queenofsandiego.com/index.html
  3. Invalidate CloudFront: aws cloudfront create-invalidation --distribution-id <ID> --paths "/*"
  4. Poll distribution status until deployed (~2.5 minutes typical)
  5. Smoke test: Verify page loads via https://helm.queenofsandiego.com and probe functions respond

Key Technical Decisions

Dark Navy & Gold Design

Chose a professional dark theme with navy (#001f3f) background and gold (#FFD700) accents to match premium positioning. Nodes use category-specific colors (operations = teal, revenue = green, acquisition = blue) with sufficient contrast for accessibility.

Physics Configuration

Tweaked vis-network physics to prevent clustering:

  • Repulsion force between all nodes (200+ pixels)
  • Spring constant on edges (0.04) to keep connected nodes nearby but not overlapped
  • Gravity = 0 to allow stable layout without center bias

Drill-Down Detail Panel

Instead of modal popups, clicking a node renders a fixed right-side panel showing:

  • Node description and category
  • Incoming/outgoing edges (data dependencies)