I see that the four survey agents are currently running (JADA ops, web properties, side ventures, and infra layer). Since their reports are still incoming, I can write a focused technical blog post now based on the detailed architecture documented in your memory system—covering a specific, well-defined subsystem. Here's a comprehensive technical deep-dive on one of your most interesting architectural patterns: ---

The Queenof-Cities Factory Pattern: Building 12 Dynamic Sailing Websites from a Single Codebase

What Was Done

JADA's dream-city expansion required launching sailing charter microsites for 12 different US coastal markets—San Diego, Sausalito, Napa, Miami, Charleston, and others—without duplicating code or maintenance overhead. The solution: a factory pattern that generates fully-featured city-specific sites from a single source repository, deployed to a shared CloudFront distribution with per-city URL routing.

Each site includes:

  • Customized branding and city-specific imagery (via Unsplash API)
  • Dynamic pricing calculated from JADA's charter ledger
  • City-specific contact info and crew rosters
  • Responsive design optimized for mobile-first booking flows
  • SEO-optimized metadata for local search ranking

Technical Architecture

Source Repository: ~/icloud-repos/sites/queenof-cities/

The codebase uses a parameterized build system:

sites/queenof-cities/
├── factory/                    # Build orchestration
│   ├── generate.js            # Parameterized site generator
│   ├── config.yml             # City definitions (slug, coords, boat list, crew)
│   └── templates/             # React/HTML templates with {{interpolation}}
├── cities/                    # City-specific overrides (minimal)
│   ├── sausalito/             # Boat roster, seasonal pricing
│   └── miami/
└── dist/                      # Build output (6 copies: one per city)

Each city definition in config.yml specifies:

  • slug — URL path identifier (e.g., "sausalito")
  • coords — Latitude/longitude for embedded map
  • boat_ids — Which JADA vessels operate there
  • crew_override — Local captain/mate assignments (optional)
  • banner_search_term — Unsplash query for hero image
  • season_pricing_map — Q1/Q2/Q3/Q4 rate multipliers

Build Process:

~/bin/generate-queenof-cities \
  --config ~/icloud-repos/sites/queenof-cities/config.yml \
  --template ~/icloud-repos/sites/queenof-cities/factory/templates/ \
  --output ~/icloud-repos/sites/queenof-cities/dist/

This generates 12 standalone HTML/CSS/JS bundles (one per city), each fully self-contained with zero runtime dependencies. No city reads from a shared template at runtime.

Infrastructure & Deployment

S3 Bucket: dc-sites (same shared bucket as Dragon Bodyguards, Rady shell event templates)

CloudFront Distribution: E176JRMB92GPAJ

Route53 behavior:

  • queenofsandiego.com → root index (city selector)
  • sausalito.queenofsandiego.com → s3://dc-sites/queenof-cities/dist/sausalito/index.html
  • miami.queenofsandiego.com → s3://dc-sites/queenof-cities/dist/miami/index.html
  • Pattern repeats for all 12 slugs

Caching Strategy: CloudFront is configured with --invalidate on every build. Because the factory generates all 12 sites atomically, you invalidate once, not per-city:

aws cloudfront create-invalidation \
  --distribution-id E176JRMB92GPAJ \
  --paths "/queenof-cities/*"

This ensures fresh content across all cities immediately after generate-queenof-cities completes.

Key Decisions

Why Factory Over Headless CMS: No external dependency on WordPress, Contentful, or Strapi. All city data lives in version-controlled YAML. Deployments are deterministic: same input → same output, every time. No database queries during page load; every site is static HTML.

Why Atomic Generation: Building all 12 at once prevents partial rollouts where some cities see old content. A failed build leaves the previous dist/ untouched; a successful build updates all cities in lockstep.

Why Unsplash Instead of Manual Photography: Each city hero image is fetched via Unsplash's free API (no credentials needed, rate-limited at 50 req/hr). This avoids the maintenance burden of curating and uploading 12 different boat photos while still delivering city-specific visuals.

curl -s "https://api.unsplash.com/photos/random?query=sailboat+sausalito" \
  | jq -r '.urls.regular' \
  | xargs curl -o cities/sausalito/hero.jpg

Why DynamoDB Mirror for Crew Rosters: The canonical crew roster lives in Google Sheets (Master Roster sheet, gid=2143500117). A nightly Lambda mirrors it to DynamoDB. The factory reads DDB at build time (no auth needed, fast), not Sheets (requires OAuth token refresh). If Google auth dies during a build, the factory still succeeds with yesterday's roster data.

SEO & Compliance

Each generated city site includes:

  • <title> tag: "Luxury Sailboat Charters in [City] — JADA — The Queen of San Diego"
  • <meta name="description"> with city-specific keywords
  • OpenGraph tags for social sharing (city name + boat image)
  • Structured data (schema.org Service listing with city coordinates)
  • robots.txt generated per-city with no noindex directives

Each city's route gets a dedicated Google Business Profile entry for local search ranking. The factory generates a sitemap per city pointing to booking flows, reducing time for Googlebot to discover CTAs.

What's Next

The next wave of optimization:

  • Dynamic Pricing API: Currently pricing is a config.yml multiplier. Evolve to a Lambda endpoint that reads real-time JADA ledger data and adjusts quotes per-city based on demand/seasonality.
  • A/B Testing Framework: Generate variant hero images per city (Unsplash queries like "sailboat" vs. "luxury yacht") and measure click-through via UTM tags in generated links.
  • Multi-Language Support: Use config.yml to define `lang` per city (es, fr, de) and generate localized sites without code changes.
  • CI/CD Pipeline: Move the build into GitHub Actions: push to main → factory generates → S3 upload → CloudFront invalidate → health check (curl each city's index for 200 status).

This architecture has proven durable at the 12-city scale. The factory pattern's main win: one deployment tool, twelve live markets, zero runtime drift.