dev @ fe9d096 · not production

Build Jul 18, 2026, 10:58 PM EDT

The 860 Life — Connecticut events and things to do in the 860

Product backlog

Ideas we have agreed to explore but have not shipped yet. When work starts it moves to our dev changelog; when it ships it appears in release notes.

Deploy hygiene (operator)

After the first prod promote that ships [releases/2026-07-17.md](./releases/2026-07-17.md), delete all of these scripts and their calls in `prisma-post-db-push.mjs`:

  • `deploy-seed-category-fallback.ts`
  • `deploy-backfill-top-picks-scores.ts`
  • `deploy-tag-date-night.ts`
  • `deploy-platform-cron-defaults.ts`
  • `deploy-purge-we-ha-ai-phantoms.ts`
  • `deploy-scrape-target-bootstrap.ts`
  • `deploy-normalize-scrape-event-slug-queue.ts`
  • `deploy-oakdale-official-listing-url.ts`
  • `deploy-peoplesbank-arena-listing-url.ts`
  • `deploy-blox-things-to-do-listing-url.ts`
  • `deploy-ajax-shell-playwright-locks.ts`
  • `deploy-clear-playwright-first-tribe-direct.ts` (optional later: drop `playwrightFirstEvidenceUnlockedAt`)
  • `deploy-merge-venue-name-phantoms.ts`
  • `deploy-publisher-venue-heal.ts` (optional later: drop `publisherVenueHealDeployedAt`)
  • `deploy-normalize-merged-away-events.ts` (`EventSlugAlias` keeps redirects after cleanup)
  • `deploy-crawl-qc-run-plans.ts` (optional later: drop `crawlQcRunPlansDeployedAt`)
  • `deploy-venue-address-identity.ts` (optional later: drop `venueAddressIdentityBackfillAt`)

Do not leave “REMOVE after promote” hooks wired forever.

---

Account & engagement

  • User accounts — Optional login to persist saved events, home town / radius, and hearts across devices. On first sign-in, merge the anonymous `the860_harted` cookie into the account. Scope auth provider (magic link vs OAuth) when there is enough traction to justify it. *(Hearts ship cookie-only today.)*

---

Site / public

  • Venue detail page — Places-rich redesign — Public `/venues/[slug]` (and listing cards) currently show name/town/address/logo/description/website only. After Places/Foursquare identity + first-pass enrich, surface richer on-file facts: Google rating, hours, parking/accessibility/dining highlights from snapshots/`venueTips`, clearer logo vs hero art. Keep voice/layout consistent; do not dump raw API JSON.
  • Venue image gallery (curated hero + logo) ↳ partial — unified missing-photo UX + Venue Hero / Venue Logo naming shipped. Remaining: optional gallery and admin upload; AI-assisted Venue Hero candidate picking is future work (current ranking is deterministic).
  • Homepage back-navigation performance ↳ partial — SSR near-you reuse, static root layout, home `loading.tsx`, remount/prefetch trim shipped. Remaining (lower priority): EventCard `prefetch={true}` site-wide; `/api/events/filters` on home mount; localStorage hydration second fetch when cookie ≠ storage.
  • Homepage / detail client bundle ↳ partial — `EventDescription` server-rendered and browse/home rows slimmed. Remaining: confirm event-detail client components don’t pull the scrape graph under webpack; keep scrape/server modules out of card UI; optional lazy `EventHartControl` on listing cards.
  • `/api/events` memory-pool row ceiling ↳ partial — Top Picks (including town/category/date/Near bbox/map) is DB `ORDER BY topPicksScore, startsAt`. Remaining: same discipline for `recommended` / `distance` memory pools; Top Picks still uses ≤`TOP_PICKS_CANDIDATE_CEILING` only for `q` / today / time-of-day memory passes.
  • Better “cool” scoring + discover more top events ↳ partial — Persisted coolness + admin pin/edit shipped. Remaining: scoring formula tweaks / surfacing more hidden gems.
  • SEO landing pages (phase 2) — More towns (Enfield, Torrington, Meriden, Simsbury, Wethersfield, Mystic/Essex) and seasonal copy; Search Console after index. *(Trivia Near Me v1 + filter UI shipped.)*
  • Release note visitor-copy lint — Checklist in team-norms so “For visitors” passes [vision-and-brand.md](./vision-and-brand.md) before promote.
  • Security doc — Admin secret model and `/api/event-image` SSRF notes (held per owner request).

---

Scrape / data

  • Periodic missing-image review ↳ partial — Shipped: first missing photo → BugReport; later → soft flag; QC product defaults On via deploy hook on first prod promote. Remaining: broader offline gallery / Missing Image Heros pool (Admin / imagery).
  • Adaptive ingestion — run-plan learning ↳ partial — structured feeds, locks, learned caps, Needs run plan guidance shipped. Remaining: optional richer learning from crawl patterns, per-source “learning on event recrawl,” and a persisted admin checkbox (vs derived badge).
  • Facebook event sources ↳ partial — Shipped: tab outcome badges + auto-disable after repeated blocked/no-tab crawls; tiered cadence floors FB listings at weekly. Remaining: many FB listing URLs still return 0 extracted — structural listing strategy (or official API) needed before broad FB cadence; login/ToS limit browser depth.
  • Per-publisher crawl session — `ScrapeTarget.extraPrompt` + run-plan locks (not global env) for market cookies (AXS Hartford zip today), logged-in Facebook/Eventbrite as the860life, etc. AXS default zip lives in `SCRAPE_PIPELINE.axsDefaultZip` until per-source prose owns it.
  • Admin: unmerge / split Locations ↳ partial — Unmerge restores child + `preventAutoMerge`, relinks label-matching upcoming events, queues bounded source recrawls. Remaining: richer confirmation UI with event counts; optional `preventAutoMerge` on the winner when operators want both sides locked.
  • Admin: location merge audit trail — Persist a lightweight log when venue sync auto-merges two `Location` rows: timestamp, merge reason, before/after ids, optional `eventId` samples. Surface read-only on the venue detail row.
  • Generalized co-production venue rules — Hartford.com co-presented shows beyond `co-production-venue.ts` unite/co-production copy parser.
  • OpenAI pipeline ordering UX — Long recrawls can show publish progress then “spacing OpenAI calls”; clarify or reorder so Jobs progress matches operator mental model. *(Bulk 860 Take throttle for >12 events ships; Gemini failover + durable TPM notes ship.)*
  • Alfred ingest API (optional) — If the browser worker splits off the HP machine, a small authenticated ingest endpoint for rendered HTML instead of shared DB queue drain only. ADR: [0007](./decisions/0007-playwright-oracle-vm.md); ops: [alfred-setup.md](./alfred-setup.md).
  • Accessibility-tree crawl extraction — After a listing loads in Playwright on Alfred, try accessibility snapshot alongside stripped HTML and JSON-LD when rendered HTML is unusable or extract count is zero.
  • Recrawl on empty-but-valid feeds ↳ partial — Trusted-empty withdraw for Facebook + trusted structured paths ships; generic HTML/AI zero-extract still skips reconcile (see [known-issues.md](./known-issues.md)). Remaining: clearer operator signal when a feed is valid but returns zero events.
  • RSS / feed auto-registration — Detect new CivicLift, ICS, and Tribe feeds during crawl and surface “add as source” in admin. CivicLift/CitySpark ingestion lock for existing sources ships in `structured-feed-lock.ts`.
  • E2E smoke (crawl) — One Preview crawl test against fixture HTML in CI.
  • Mobile event-page screenshot — Playwright phone-width capture when listing + `og:image` fail.
  • Concise crawled event titles (SEO) ↳ partial — sports strip + occurrence/date suffixes + redundant `at {venue}` strip + prefer shorter compatible titles on recrawl + concert title guidance shipped. Remaining: broader marketing-tagline shortening at extract for all publishers.
  • Refresh compact occurrence titles — Re-crawl recurring series for `Sun 5/8`-style titles (Tribe occurrence URLs help HJS but not all publishers).
  • Trivia image from social — Facebook/Instagram art before generated trivia cards.
  • Crawl cost dashboard — Admin view rolling up per-`ScrapeTarget` cost signals from `ScrapeRun` (pages fetched, detail skips, Alfred wall time, AI token usage). Sort by spend last 7d / 30d.
  • Missing-category crawl audit — Post-crawl or scheduled script listing drafts/events dropped for missing/invalid category after guidance + AI pass. Group by `ScrapeTarget` + extraction path.
  • Legacy rows missing externalId — audit prod before delete ↳ partial — Events admin can filter/select/delete missing-`externalId` rows. Remaining: read-only prod count/classify script for operator sign-off before bulk delete.
  • Listing-only crawl must always yield stable externalId ↳ partial — extract rejects missing id; finalize/publish block blank `externalId`. Remaining: ensure every listing-only path synthesizes a stable structural id when publisher omits one.

---

Crawl cadence & self-healing QC

Shipped on `dev` (promote prep 2026-07-17): tiered cadence (12h imminence floor + pin + Platform caps); no auto SCRAPE_RESET; Extra scrape prompt stays operator-edited; Jobs `EVENT_QC`; missing photo first → BugReport, later soft flag; live schema/ICS confirmation for time/title findings; first prod deploy flips QC + auto suggested recrawls On.

↳ partial remaining: - Stale worker cancel thresholds — further tune Alfred hung-row cancel/re-enqueue if overlap still trips “no progress” in practice. - Periodic missing-image review gallery/backfill UX beyond `imageMissingFlaggedAt` (ties Admin / imagery).

---

Ops

  • Concise crawled event titles (SEO) — see Scrape / data.

---

Deployment / platform health

Baseline on `main`: [smoke-test.md](./smoke-test.md) (`verify:deployed:dev` / `:prod` / `verify:promote`), CI after prod→dev copy, [database-release-workflow.md](./database-release-workflow.md).

  • Public deployment status page — e.g. `/status` from `/api/health` (no secrets in UI).
  • Admin deployment status — e.g. `/admin/status` with schema parity, event counts, Actions links.
  • `GET /api/deploy-health` — One JSON payload for monitors and status UI.
  • External uptime monitoring — Document Better Stack / UptimeRobot polling www + dev health.

---

Admin / imagery

  • Category on uploaded hero ↳ partial — category mapping ships on Category Missing Images (multi-select). Remaining only if HP Hero Images themselves need category tags for homepage rotation (not requested).
  • Exclude from HP banner rotation — Per-image flag so a hero can serve missing-image fallbacks without entering the homepage banner carousel. *(Category Missing Images is now a separate pool — this flag may be obsolete.)*

---

Venue / admin guards

  • Venue create guard ↳ partial — admin Add venue + crawl ensure share `resolveVenueLocation` (admin-guard / ensure). Remaining: surface the existing row “open instead” UX polish if operators still get confused; complements Admin: unmerge / split Locations.

← Release notes