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
- Edit
index.htmllocally with node/edge definitions and health probe endpoints - Upload to S3:
aws s3 cp helm/index.html s3://helm.queenofsandiego.com/index.html - Invalidate CloudFront:
aws cloudfront create-invalidation --distribution-id <ID> --paths "/*" - Poll distribution status until deployed (~2.5 minutes typical)
- Smoke test: Verify page loads via
https://helm.queenofsandiego.comand 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)