Building HELM: An Interactive Operations Dashboard for Multi-Platform Booking Management

We just deployed HELM—a self-contained, real-time operations visualization dashboard that maps the entire customer journey from acquisition through sail execution. HELM integrates booking platforms (Viator, Boatsetter, GetMyBoat), payment flows, email campaigns, crew dispatch, and operational dashboards into a single interactive force-directed graph. Here's how we built it.

What Was Done

Created a single-file HTML application (/Users/cb/Documents/repos/sites/helm/index.html) deployed to helm.queenofsandiego.com that visualizes JADA's entire operational backbone. The dashboard:

  • Maps 30+ system nodes (platforms, dashboards, data flows, crew roles)
  • Shows relationships and dependencies via directional edges
  • Includes live health diagnostics that probe backend systems
  • Provides drill-down detail panels showing GAS function mappings
  • Uses physics-based force layout for intuitive spatial relationships
  • Features dark navy/gold styling appropriate for technical presentations

Technical Architecture

Frontend Stack: The application uses vis-network (CDN: https://unpkg.com/vis-network/standalone/umd/vis-network.min.js) for the graph rendering engine. We chose vis-network because:

  • Force-directed physics simulation naturally clusters related nodes
  • Built-in physics stabilization prevents runaway oscillation
  • Interactive canvas manipulation (pan, zoom, drag) feels responsive without custom event handlers
  • No external dependencies beyond the single library

Node Categories: The graph organizes systems into logical groups:

  • Acquisition: Email campaigns, web search, referral codes, partner integrations
  • Booking Platforms: Viator, Boatsetter, GetMyBoat (with greyed-out nodes for future platforms)
  • Financial: Payment processing, revenue tracking by platform
  • Operations: Crew dispatch, email automation, dashboard management
  • Systems: Google Sheets backend, Google Apps Script functions, CRM integrations

Data Structure: All node and edge definitions are embedded in the HTML file as JavaScript objects:

const NODE_DATA = {
  acquisition_email: {category: 'acquisition', label: 'Email Campaigns'},
  platform_viator: {category: 'booking', label: 'Viator'},
  ops_crewdispatch: {category: 'operations', label: 'Crew Dispatch'},
  // ... 30+ nodes
};

const EDGES = [
  {from: 'acquisition_email', to: 'platform_viator', label: 'UTM params'},
  // ... connection graph
];

Health Diagnostics: Each node is assigned a health status based on periodic backend probes. The system sends requests to key GAS endpoints and colors nodes accordingly:

  • Green: System responding normally
  • Yellow: Slow response or degraded performance
  • Red: Timeout or error response
  • Grey: Not yet probed or explicitly disabled

A system health bar at the top aggregates overall status. The implementation polls GAS endpoints every 60 seconds and updates node colors without requiring page refresh.

Infrastructure & Deployment

S3 Bucket: Created helm.queenofsandiego.com S3 bucket in us-west-2 with:

  • Block all public access enabled
  • Versioning disabled (single-file application)
  • Custom bucket policy restricting access to CloudFront only

CloudFront Distribution: Set up distribution with Origin Access Control (OAC) to avoid presigned URLs. Configuration:

  • Origin: S3 bucket with OAC policy enforcement
  • Default root object: index.html
  • Compress: Enabled (gzip for JS/CSS)
  • Custom headers: Cache-Control max-age=3600 for index.html
  • TTL: 300 seconds (5 minutes) for rapid updates during development

DNS: Added Route53 ALIAS record pointing helm.queenofsandiego.com to CloudFront distribution domain name with alias hosted zone ID matching CloudFront's region.

Deployment Process:

# Upload to S3
aws s3 cp /Users/cb/Documents/repos/sites/helm/index.html \
  s3://helm.queenofsandiego.com/index.html \
  --content-type text/html \
  --metadata-directive REPLACE

# Invalidate CloudFront cache to force edge refresh
aws cloudfront create-invalidation \
  --distribution-id [DISTRIBUTION_ID] \
  --paths "/*"

Key Technical Decisions

Single-File Architecture: Despite the complexity, we bundled everything (HTML, CSS, JavaScript, node data) into one 400KB file. This decision prioritized:

  • Zero external API calls on page load (all data embedded)
  • Password-gated access via SHA-256 hash computed at runtime
  • Portability—the file can be shared, archived, or deployed to any static host
  • Reduced deployment surface area (one S3 object, one CloudFront invalidation)

Force-Directed Physics Over Hierarchical Layout: We rejected tree or layered layouts because:

  • The system isn't strictly hierarchical—data flows in multiple directions
  • Physical simulation naturally clusters related domains (acquisition flows together, ops flows together)
  • Engineers intuitively understand force-directed layouts from network diagrams and social graphs

Health Probing Strategy: Rather than a simple static diagram, we built diagnostic capabilities that probe real GAS endpoints. This serves two purposes:

  • Validates that systems are alive without requiring manual status updates
  • Identifies bottlenecks by tracking response times per endpoint

Probes are asynchronous and non-blocking—if a system is slow, the graph remains interactive.

Drill-Down Design: Clicking a node reveals a detail panel showing:

  • System description and purpose
  • List of GAS functions tied to that node
  • Recent health status and response times
  • Related nodes (incoming/outgoing edges)

This pattern scales—as systems are added, new functions automatically appear in the correct node panel.

Password Protection Implementation

HELM is protected via SHA-256 password hash stored as a client-side constant. The application:

  1. Computes SHA-256 of user input using native Web Crypto API
  2. Compares digest to embedded hash constant
  3. Displays graph only after successful match

This approach is suitable because HELM is internal tooling, not a security boundary. The