```html

Building Deterministic Vendor Tests & Multi-Site Deployments on CloudFront + S3

Challenge: JADA operates three separate sailing websites (sailjada.com, queenofsandiego.com, burialsatseasandiego.com) with vendor partner pages that must stay in sync across domains. Vendor contact info (URLs, phone numbers) changes frequently, and stale data creates a trust problem — particularly for referral partners like law firms, marine services, and event vendors. Manual updates were error-prone and invisible.

Solution: A deterministic test suite that validates vendor endpoints before deployment, coupled with a centralized vendor JSON source-of-truth and automated multi-site CloudFront invalidation.

Architecture: Single Source, Multiple Destinations

All three sites share a common vendor data source at:

/Users/cb/icloud-jada-ops/vendors/vendors.json

This JSON file holds vendor records with name, URL, phone (E.164 format), category, and notes. Each site's build process pulls from this file and renders vendor pages. Changes to vendors.json trigger site rebuilds and immediate CloudFront cache invalidation.

The Vendor Test Suite

We built test_vendor_pages.py at:

/Users/cb/icloud-repos/sites/queenofsandiego.com/tests/test_vendor_pages.py

What it does:

  • URL validation: Fetches each vendor's domain with a 5-second timeout. If the domain 404s or times out, the test fails with the exact vendor name and URL.
  • Phone format validation: Checks that all phone numbers conform to E.164 format (e.g., +16195551234). Catches typos before they go live.
  • Data consistency: Ensures every vendor record has required fields (name, URL, phone, category). Gaps are flagged immediately.
  • Multi-site coverage: Runs the same suite against vendor pages on all three sites to ensure they all pulled the latest data correctly.

Why deterministic: The test reads from a static file snapshot and validates against live external endpoints. It has no mock database, no test fixtures that can drift from reality. Every run produces the same results given the same input data and network conditions. This means the test suite itself becomes part of our deployment checklist — if tests pass, deployment is safe.

pytest /Users/cb/icloud-repos/sites/queenofsandiego.com/tests/test_vendor_pages.py -v

Domain Registration & Routing

During this work, we registered morenoferrolaw.com via the Namecheap API (called from Lightsail, which has a whitelisted IP). The domain now points to dangerouscentaur.com via CNAME, serving vendor-related pages for a legal partner.

Why Lightsail for DNS calls: Namecheap's API whitelist is IP-based. The Mac's IP varies (home WiFi, mobile hotspot). Lightsail has a static public IP (34.239.233.28), making it reliable for automated DNS operations. This is documented in the deployment procedures so future automation can reuse the same pattern.

Multi-Site Deployment Pipeline

The build-deploy cycle:

  1. Build phase: Site-specific build scripts read vendors.json and generate HTML vendor pages for each site.
  2. Test phase: test_vendor_pages.py validates URLs and phone numbers before anything goes live.
  3. Deploy phase: Uploads rendered pages to S3 buckets:
    • sailjada-web (sailjada.com)
    • qos-web (queenofsandiego.com)
    • bssd-web (burialsatseasandiego.com)
    • dc-sites (dangerouscentaur.com, including Daniela's subdomain)
  4. Invalidation phase: CloudFront cache invalidation fires automatically for cached paths. Non-cached paths (like /print/* and /g/*) skip invalidation since they have CachingDisabled headers.

Key CloudFront distributions involved:

  • E10WJ716X823DQ — dragonbodyguards.com (separate static site)
  • E176JRMB92GPAJ — queenof-cities staging (12 dream-city subdomains)
  • EPF415U2AO8B3 — sailjada.com main site
  • dc-sites — dangerouscentaur.com and vendor partner pages

Internationalization for Vendor Pages

Daniela Ferro's site (hosted at dangerouscentaur.com as a subdomain) required bilingual support. Files at:

/Users/cb/icloud-jada-ops/state/danielaferro/index.html
/Users/cb/icloud-jada-ops/state/danielaferro/i18n.js
/Users/cb/icloud-jada-ops/state/danielaferro/style.css
/Users/cb/icloud-jada-ops/state/danielaferro/main.js

i18n.js provides a simple key-value translation system. The main page loads Spanish/English text from this module and swaps it on language toggle. This keeps translation logic out of HTML, making content updates easier and reducing duplication.

Why This Matters

Trust and speed: A stale vendor URL in print materials or a website is worse than no link at all — it signals operational sloppiness. By testing URLs before deployment and validating phone numbers in a strict format, we ensure vendor pages stay trustworthy.

Scalability: As JADA adds more vendor partnerships and brands (dangerouscentaur.com, queenof-* staging), a single vendors.json source prevents duplicate data entry and drift. New partners are added once, deployed everywhere.

Operational safety: Deterministic tests catch errors before they reach production. There's no "deploy and hope" — the test suite is part of the definition of "done."

What's Next

Future work includes expanding the test suite to validate email addresses and social media handles, automating domain renewal checks, and integrating vendor page changes into the automated ticket-runner system on the jada-agent box (Lightsail 24/7 agent instance). The goal is zero-touch vendor updates for non-sensitive changes.

```