Rebuilding the Queen of San Diego Booking Platform: From Broken Maps to Multi-Channel Payment Integration
This session involved a comprehensive rebuild of the queen of san diego booking experience, addressing a critical site failure and implementing a modern payment infrastructure. The work spanned frontend HTML/CSS fixes, Google Apps Script automation, AWS infrastructure provisioning, and CloudFront distribution management.
The Problem: Broken Maps and Missing Payment Options
The live site at queenofsandiego.com was serving broken Google Maps embeds and lacked direct payment integration. The user-facing issues were:
- Non-functional Google Maps iframe in the hero section
- No clear payment QR codes for clients (Stripe, Zelle, Venmo)
- Booking modal missing duration selection (2hr vs 3hr charters)
- File path mismatch:
zelle-qr.jpgreferenced but actual file waszelle-qr.jpeg
Technical Implementation
Frontend Fixes: HTML/CSS Repairs
The primary work occurred in /Users/cb/Documents/repos/sites/queenofsandiego.com/index.html. Multiple edits were required to the hero section and booking modal:
- Replaced the broken Google Maps embed with a responsive payment QR code panel containing three payment options: Stripe link, Zelle QR code, and Venmo QR code. This eliminates the map dependency while providing immediate monetization paths for clients.
- Fixed orphaned CSS: Found and resolved a mismatched
</style>tag at line 3090 with no corresponding opening tag, which was causing CSS parsing failures. - Updated the reserve button in the navigation and hero CTA to trigger the
jadaOpenBook()function with duration parameters (2 or 3 hours). - Corrected image references: Changed
zelle-qr.jpgtozelle-qr.jpegto match actual S3 assets.
The booking modal enhancement required modifying the jadaOpenBook function to accept a duration parameter, allowing the function signature to change from jadaOpenBook() to jadaOpenBook(durationHours).
Google Apps Script Automation
The BookingAutomation.gs file received updates to handle booking requests with duration information. The deployment included:
- A new endpoint in the published GAS web app to handle
booked_datesqueries, allowing the frontend calendar to display unavailable dates. - Integration with Google Calendar API (
CalendarApp) to read the JADA calendar and return booked time slots, preventing double-bookings. - Modification of the deployment ID to expose the updated endpoint while maintaining backward compatibility with existing integrations.
The GAS files were deployed using clasp push to the published web app, and the deployment ID was verified in the clasp configuration.
Infrastructure: S3, CloudFront, and DNS
Main Site Deployment
Updates to the main site followed this pattern:
# Push updated index.html to S3 bucket
aws s3 cp index.html s3://queenofsandiego.com/
# Invalidate CloudFront cache for immediate distribution
aws cloudfront create-invalidation \
--distribution-id [DISTRIBUTION_ID] \
--paths "/index.html" "/*"
The CloudFront distribution for queenofsandiego.com was identified and its cache invalidated to ensure all edge locations served the updated HTML within seconds.
Private P&L Calculator Infrastructure
A secondary project during this session involved creating a private, authenticated P&L (profit/loss) calculator at pnl.queenofsandiego.com. This required new infrastructure:
- S3 Bucket: Created a private bucket for the P&L calculator HTML
- ACM Certificate: Requested an SSL certificate for
pnl.queenofsandiego.comwith DNS validation via Route 53 - Origin Access Control (OAC): Implemented OAC instead of the deprecated OAI to restrict S3 bucket access to CloudFront only
- CloudFront Function: Deployed a basic authentication function at the CloudFront edge to enforce credentials before serving content
- Route 53: Added A and AAAA alias records pointing to the CloudFront distribution
The basic auth implementation computed base64-encoded credentials and injected authentication logic into a CloudFront Function, published to the LIVE stage. The function returns a 401 Unauthorized response unless valid credentials are provided in the Authorization header.
Ops and HELM Index Updates
Parallel infrastructure work involved updating internal tools indices:
- Ops Index: Updated
/tmp/ops-index.htmlto include new tools in the tools section - HELM Index: Modified
/tmp/helm-index.htmlto include financial/ledger nodes in the ROOT_NODES array, making them discoverable in the HELM navigation structure
Both indices were uploaded to their respective S3 buckets and CloudFront caches were invalidated.
Key Architectural Decisions
- QR Code-Based Payments Over Maps: Replacing non-functional maps with payment QR codes directly addresses revenue while reducing external API dependencies. QR codes are client-friendly and support multiple payment processors (Stripe, Zelle, Venmo).
- CloudFront Functions for Edge Authentication: Rather than application-level basic auth, implementing authentication at the CloudFront edge reduces backend load and provides immediate rejection of unauthorized requests before they reach S3.
- OAC Over OAI: AWS deprecated OAI in favor of OAC for improved security and flexibility. All new distributions use OAC with explicit bucket policies.
- GAS Web App for Calendar Sync: Using Google Apps Script eliminates the need for a separate backend service. The CalendarApp API provides direct read access to the JADA calendar, and the published web app endpoint makes it accessible from the frontend.
- Dual-Channel Infrastructure: Public site (
queenofsandiego.com) and private tools (pnl.queenofsandiego.com) use the same CloudFront + S3 + Route 53 pattern but with different security layers appropriate to their use cases.
Verification and Testing
Post-deployment verification included:
- Checking live HTTP responses from the main site to confirm asset delivery
- Testing the P&L site without authentication (expected 401 response)
- Testing the P&L site with correct credentials (expected 200 response)
- Polling ACM certificate validation status until ISSUED state
- Confirming CloudFront distribution reached DEPLOYED state before testing
What's Next
Future work includes: