Add NJ NANPA area codes (201/551/732/848/908/973/862/609/640/856) to the
NYC market map, and extend the NYC metro geo-alias rule to match New Jersey,
Jersey City, Newark, Hoboken, and Long Island for both city resolution and
asked-to-come recall. Covered by geo + geo-aliases tests.
Same postgres.js bug as acquisition: ${corpFilter} (empty string) becomes a stray
bind param -> 'syntax error near $3' -> handlers return []. This broke the quinn.data
dashboard's top-pages/sessions/trends panels (engagement/pages returned 0 rows with
scanner_yyerror). Removed corpFilter from all three + dropped the now-unused corpClause.
The new NYC routes (and all pages) now surface in the dashboard.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- acquisition/sources: drop the ${corpFilter} interpolation. postgres.js turns the
empty-string fragment into a stray bind param ($3) → 'syntax error at or near $3'.
corp filtering isn't needed for this referrer-based query; removing it makes the
endpoint return real data (verified: 25 sources, 538 direct/21 conv, tryst 158/4,
social 103/8 on both black + quinn-vps).
- deploy.sh secrets template: ANALYTICS_DB_URL pointed at black.lan:25434 (the EMPTY
black analytics instance) with no password. Point at the populated DB on quinn-vps
(10.9.0.1:25434, reachable from both hosts) via a dedicated read-only role
quinn_api_ro (analytics_ro is the MCP's; pg_hba requires scram so a password is
needed). Password left blank in-repo; filled in live secrets.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Linking (staged): thread destinationSlug through the public tour payload
(provider-config + /tour serializer + shared TourStop type) and match the pSEO
city-page Event by destinationSlug (robust) with a city-name fallback. New
staged seed scripts/seed-nyc-tour-destinations.ts creates the 4 NYC borough
destinations (linkedTourStop=true) and sets tour_stops.destination_slug —
dry-run by default, --commit to apply, not run in CI. Dormant until seeded (no
behavior change), then /_/escorts/in-{manhattan,brooklyn,queens,the-hamptons}
emit tour-aware Event schema for free.
Analytics: every NYC CTA now tracked — tour-leg rates + hub nav links, the hub
full-schedule link, and the pSEO city rates/booking nav links (sms/whatsapp/
booking/opt-in/leg-cards were already tracked; page views auto-track via
usePageViewTracking).
Verified: api + frontend typecheck, frontend build, seed dry-run against live DB.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The api suite is ~95% Postgres integration tests against black, which is only
low-latency from apricot/LAN. Run from plum (over the mesh) the per-test DB
round-trips blow the 60s timeout. New scripts/run-tests.ts probes the test DB
and, when unreachable or slow (round-trip > QUINN_DB_LATENCY_SKIP_MS, default
250ms), skips the DB-dependent files and tells the harness (QUINN_SKIP_DB_TESTS)
to no-op its DB setup + tx isolation — so the DB-free subset still runs.
CI (or QUINN_REQUIRE_DB_TESTS=1) always runs the full suite so a broken DB fails
loud, never silently skips. test-env.ts is the shared gate; test:full / test:no-db
force either mode. From plum: 370 pass, 0 fail (92 DB files skipped, logged).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Hub + per-borough tour pages (Manhattan/Brooklyn/Queens/Hamptons) driven by a
shared TourLegPage over src/data/nycTour2026.ts. Confirmed legs emit schema.org
Event JSON-LD; conditional legs show a tentative pill + touring opt-in (no
inaccurate Event dates). Sitemap emits the 5 /tours/* routes.
Tracking: de-stub /analytics/acquisition/sources to real referrer-based source+
medium attribution joined to conversion-goal events (UTM is not persisted by the
collector; referrer is the available signal). NYC CTAs fire nyc_booking
conversion events labelled {borough}:{channel}.
Verified: frontend typecheck+build green, api typecheck green, acquisition query
validated against live lilith_analytics.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- tour-stop/repo.ts: update path wrote the pre-sync (nullable) incallHotels
(TS18047); use the synced non-null hotels result, matching createTourStop.
- package.json: declare `sharp` (used via dynamic import in image-processing,
was undeclared → TS2307 on clean checkout; version already in bun.lock).
- tsconfig.json: exclude src/mcp-prospector/** from the api typecheck — it's its
own workspace sub-package with its own deps/tsconfig (same as the existing
mcp-seo exclusion); the api compile was wrongly pulling its sources in.
Authored on plum as fallback - apricot (normal authoring host) was offline.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
When the verify job fails, print the exact list of packages that failed
typecheck, ready to copy into tooling/ci/.typecheck-debt. The tally line
("N failed") gave no way to see WHICH packages without scraping per-package
output from the log. Needed to enumerate the current pre-existing debt
authoritatively (apricot — the build/verify host — is offline, so the set
can't be reproduced locally).
Authored on plum as fallback - apricot (normal authoring host) was offline.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>