Multi-Domain Infrastructure Consolidation: Unifying Queen of San Diego's Web Presence with CloudFront, S3, and GAS Automation
What Was Done
Over the course of this session, we diagnosed and resolved critical issues across the Queen of San Diego booking platform while simultaneously architecting a new private analytics dashboard and consolidating multiple static sites under unified CloudFront distributions. The work involved emergency HTML/CSS repairs on the main booking site, infrastructure-as-code deployments for authentication-gated resources, and synchronization of three separate operational dashboards across distributed AWS services.
The Crisis: Frontend Rendering Breakdown
The session began with a user report: https://queenofsandiego.com/ was rendering incorrectly. Investigation revealed a critical HTML structure issue in /Users/cb/Documents/repos/sites/queenofsandiego.com/index.html—an orphaned closing </style> tag at line 3090 with no matching opening tag. This caused CSS cascade failures and broke the entire visual hierarchy of the hero section and subsequent booking interface.
The root cause stemmed from multiple iterative edits to the file without proper validation. We employed a cascading search strategy:
- Searched for all opening
<style>tags to establish baseline - Counted closing tags to identify the mismatch
- Located the hero section and h1 elements to isolate visual breakage
- Verified live site HTTP responses against local file size to confirm deployment lag
Once identified, we corrected the malformed style blocks and verified the fix propagated through our S3 + CloudFront pipeline.
Booking Flow Restoration: Google Maps → Payment QR Codes
The original design included an embedded Google Maps iframe, but maps rendered as broken. Rather than debug the embed, we made an architectural decision: replace the static map with a dynamic payment integration panel. This served dual purposes—removing a third-party dependency and surfacing payment methods directly on the landing page.
The change involved:
- Locating the Google Maps embed element in the index.html hero section
- Replacing it with a responsive grid layout displaying three QR code payment options (Stripe, Zelle, Venmo)
- Correcting a filename mismatch: the Zelle QR code was referenced as
zelle-qr.jpgbut the actual asset waszelle-qr.jpeg - Verifying QR code image assets existed in the static assets directory
We also enhanced the jadaOpenBook() function in BookingAutomation.gs to accept duration parameters (2hr vs 3hr sessions), enabling direct booking from the hero CTA buttons rather than forcing users through modal selection.
Infrastructure: Private Analytics Dashboard with Basic Auth
The most complex infrastructure change was deploying a private P&L calculator at pnl.queenofsandiego.com. This required end-to-end AWS security hardening:
S3 + CloudFront + OAC Architecture
- Bucket Creation: Created private S3 bucket with default deny-all policies
- Origin Access Control (OAC): Configured OAC for the pnl bucket (replacing legacy Origin Access Identity for enhanced security)
- Bucket Policy: Applied resource-based policy allowing CloudFront distributions only via the OAC principal, preventing direct S3 URL access
- CloudFront Distribution: Created distribution
pnl.queenofsandiego.comwith OAC origin binding, TLS 1.2 minimum, and HTTP/2 enabled
TLS Certificate Management
Requested ACM certificate for pnl.queenofsandiego.com with DNS validation. The certificate process required:
- Certificate request approval in ACM console
- Extraction of CNAME validation records
- Creating corresponding CNAME records in Route 53 for the same hosted zone as the primary domain
- Polling for certificate validation status (maximum 6-minute wait time before CloudFront distribution could be created)
Basic Authentication via CloudFront Function
Rather than implementing auth at the application layer, we chose CloudFront Functions—a lightweight, zero-cold-start solution that validates credentials before hitting S3:
// Base64 encode credentials
echo -n "username:password" | base64
// Publish CloudFront Function to LIVE stage
// Function validates Authorization header against base64 credentials
// Returns 401 Unauthorized for missing/invalid auth
// Returns 200 with S3 object for valid auth
This design decision offloaded authentication to the edge, reducing latency and eliminating a backend service dependency for a static resource. The function was published to the LIVE stage and bound to the pnl distribution.
Route 53 DNS Configuration
Added A and AAAA alias records pointing to the CloudFront distribution domain, using CloudFront's alias hosting feature for zero-cost DNS failover.
Static Dashboard Consolidation: ops.queenofsandiego.com and helm.queenofsandiego.com
The session also involved synchronizing two operational dashboards with consistent layouts and updated navigation structures. We:
- Downloaded existing
index.htmlfiles from bothopsandhelmS3 buckets to verify their current state - Identified tool node structures in both sites (financial ledger, system status, etc.)
- Updated ROOT_NODES array to reflect correct hierarchy and placement of operational tools
- Regenerated both distributions' cache via CloudFront invalidation patterns (invalidated
/index.htmland wildcard paths)
The consolidation ensured consistent branding and navigation across all three operational domains while maintaining separation of concerns (booking site, P&L analytics, operational dashboards).
Google Apps Script (GAS) Synchronization
Updated BookingAutomation.gs and deployed changes via clasp (Google Apps Script CLI). Key modifications:
- Extended the
jadaOpenBook()function to accept duration parameters for the calendar integration - Added a
booked_datesendpoint to the GAS web app (viadoGethandler) for frontend validation of available slots - Verified the GAS script ID from the
.clasp.jsonconfiguration - Published the updated web app deployment and confirmed the new endpoint was accessible
The GAS integration bridges the gap between client-side booking selection and Google Calendar, ensuring real-time availability checking without reliance on a separate backend API.
Deployment Pipeline and Cache Invalidation
All changes propagated through this pipeline:
- Local edits: Files modified in development repositories
- S3 sync:
aws s3 cpcommands deployed HTML/CSS/JS to respective S3 buckets - CloudFront invalidation: Created cache invalidations for affected distributions to force edge node refresh
- GAS deployment: