From 77f84c47b1da32126a727fa9e828118fd98cee39 Mon Sep 17 00:00:00 2001 From: Michael Freno Date: Thu, 23 Jul 2026 09:29:26 -0400 Subject: [PATCH] docs: add subdomain routing reference to AGENTS.md and verification script - Add Subdomain Routing section to AGENTS.md with route placement, site context, API routing, and auth boundary guidance for future tasks - Add scripts/verify-subdomains.sh for post-deployment verification of DNS, HTTPS, appcast regression, and SSL certificates --- AGENTS.md | 9 ++++ scripts/verify-subdomains.sh | 80 ++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100755 scripts/verify-subdomains.sh diff --git a/AGENTS.md b/AGENTS.md index 1ebbc8c..7b15e09 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -63,6 +63,15 @@ - Types in `src/types/` (shared types) or co-located - Utils in `src/lib/` or `src/server/utils.ts` +## Subdomain Routing + +This project serves four product subdomains (`nessa.freno.me`, `lineage.freno.me`, `gaze.freno.me`, `inputhalo.freno.me`) plus the personal site on `freno.me`. See `docs/subdomain-setup.md` for DNS/Vercel configuration. + +- **Route placement:** Subdomain pages live under `src/routes//*` (e.g. `src/routes/nessa/...`). The `vercel.json` host-based rewrites map each subdomain to its prefix. +- **Site context:** Use `useSite()` (SolidJS) or `getSiteFromEvent`/`getSiteFromRequest` (server) from `src/lib/site-context.ts` to detect the current site. Never host-snoop in route files — SolidStart's router can't match on host. +- **API routes:** `/api/*` is a shared pool — subdomain API requests pass through to existing routes via vercel.json pass-through rewrites (ordering matters). +- **Auth:** Host-scoped only — no cookie domain broadening. + ## Key Differences from React See `src/lib/SOLID-PATTERNS.md` for comprehensive React→Solid conversion guide. Key gotchas: - Signals must be called with `()` to read value diff --git a/scripts/verify-subdomains.sh b/scripts/verify-subdomains.sh new file mode 100755 index 0000000..5762126 --- /dev/null +++ b/scripts/verify-subdomains.sh @@ -0,0 +1,80 @@ +#!/usr/bin/env bash +# Verify subdomain DNS propagation, SSL, and rewrite routing +# Run after DNS CNAMEs are added and Vercel domains are configured. + +set -euo pipefail + +SUBDOMAINS=("nessa" "lineage" "gaze" "inputhalo") +APICAST_ROUTES=("Gaze" "InputHalo") +PASS=0 +FAIL=0 + +check() { + local desc="$1" + shift + if "$@" >/dev/null 2>&1; then + echo "✓ $desc" + PASS=$((PASS + 1)) + else + echo "✗ $desc" + FAIL=$((FAIL + 1)) + fi +} + +echo "=== DNS CNAME propagation ===" +for sub in "${SUBDOMAINS[@]}"; do + cname=$(dig +short "$sub.freno.me" 2>/dev/null | grep -i "cname.vercel-dns.com" || true) + if [[ -n "$cname" ]]; then + check "$sub.freno.me CNAME → cname.vercel-dns.com" true + else + check "$sub.freno.me CNAME → cname.vercel-dns.com" false + fi +done + +echo "" +echo "=== HTTPS landing pages ===" +for sub in "${SUBDOMAINS[@]}"; do + status=$(curl -sI -o /dev/null -w "%{http_code}" "https://${sub}.freno.me/" 2>/dev/null || echo "000") + if [[ "$status" == "200" ]]; then + check "https://${sub}.freno.me/ → 200" true + else + check "https://${sub}.freno.me/ → 200 (got ${status})" false + fi +done + +echo "" +echo "=== Appcast regression (freno.me) ===" +for route in "${APICAST_ROUTES[@]}"; do + status=$(curl -sI -o /dev/null -w "%{http_code}" "https://freno.me/api/${route}/appcast.xml" 2>/dev/null || echo "000") + if [[ "$status" == "200" ]]; then + check "https://freno.me/api/${route}/appcast.xml → 200" true + else + check "https://freno.me/api/${route}/appcast.xml → 200 (got ${status})" false + fi +done + +echo "" +echo "=== Main site regression ===" +status=$(curl -sI -o /dev/null -w "%{http_code}" "https://freno.me/" 2>/dev/null || echo "000") +if [[ "$status" == "200" ]]; then + check "https://freno.me/ → 200" true +else + check "https://freno.me/ → 200 (got ${status})" false +fi + +echo "" +echo "=== SSL certificates ===" +for sub in "${SUBDOMAINS[@]}"; do + if echo | openssl s_client -connect "${sub}.freno.me:443" -servername "${sub}.freno.me" 2>/dev/null | \ + openssl x509 -noout -checkend 0 2>/dev/null | grep -q "not expired"; then + check "${sub}.freno.me SSL valid" true + else + check "${sub}.freno.me SSL valid" false + fi +done + +echo "" +echo "=== Summary: ${PASS} passed, ${FAIL} failed ===" +if [[ $FAIL -gt 0 ]]; then + exit 1 +fi