What: the pattern that builds the network BACKWARDS from ticketed/scheduled events. An external feed lists events at venues; each venue becomes a Google-Places- backed Doozer site, enriched with its upcoming events, turned into a Global Gathering, with affiliate ticket links. Marquee (Ticketmaster) is the first live instance; the plan is to generalize it into one engine with per-source adapters.
The pipeline (source-agnostic after the fetch): feed fetch -> normalize -> match venue to an existing business (accuracy-first) OR build it (resolvePlaceToEcosystem) -> stamp the external venue id (Magellan link) -> business-events.php renders events on the site -> gathering + affiliate link.
The universal join key is the Google place_id. Every feed's venue resolves to one, so multiple feeds enrich the SAME site instead of duplicating. This is why the accuracy-first matcher matters as feeds multiply.
Marquee today (includes/marquee-engine.php, admin-marquee.php):
marqueeTmFetch (Discovery API v2), marqueeNormalizeTm, marqueeIngest.marqueeMatchVenue($name,$city,$state,$lat,$lng,$tmVenueId) — accuracy-first(v2.2.433): tm_venue_id -> physical geo (name-confirmed, never geo-only, generic venue words excluded) -> normalized name -> legacy. Unit-tested 7/7 on real collisions. Ingest stamps businesses.tm_venue_id on every match (enriches existing sites, no rebuild).
(sort=relevance,desc), no city. Skims the hottest venues everywhere; widen into quieter markets over time.
marqueeRecentVenues). Was silentlyempty until v2.2.431 (an ORDER BY g.site_domain alias bug — a correlated-subquery alias can't be table-qualified in ORDER BY).
dz marquee [do=status|repair|backfill|trending]. repair re-links orphans;backfill re-runs the matcher over stored events.
Business-first enrichment (v2.2.438) — the complement to feed-first: a venue site built OUTSIDE Marquee (More Places Nearby / Prospector) has no events, because Marquee is feed-first (events arrive only when a sweep covers that venue). marqueeEnrichBusiness($bizId) probes the feeds BY the business's own name + coordinates and links its shows to the existing site. Reuses everything (marqueeIngest keyword+geo → accuracy match → stamp → site renders); 1 TM call (+1 SeatGeek) per business, 3-day freshness guard. marqueeEnrichScan($limit) = niche-gated backfill of venue sites that have a site but no upcoming events. dz marquee do=enrich biz=<id> / do=enrich-scan [limit=]. THE PRINCIPLE: every enrichment feed is a business-first probe keyed on identity (name+geo+niche) whose results route to the right section; Marquee/events is the first.
GOTCHAS (learned the hard way):
pr_discoveries.status='site_created' but the domain never persisted, because linkDomainToBusiness() returned true without verifying the INSERT. Every rebuild then dead-ended on the "already created" guard. Fix: the link now VERIFIES the row + logs the real error; the guard SELF-HEALS (only blocks when a live domain exists).
now surfaces skip count + first error and does not auto-reload over a zero-store.
Multi-source (v2.2.436): marqueeIngest takes opts['source'] (ticketmaster | seatgeek) and dispatches the adapter; marquee_events.source + marquee_sweeps.source are bound, not hardcoded. Cross-feed dedup is by Google place_id (a venue built from TM is ENRICHED by SeatGeek, never duplicated).
SeatGeek — feed #2, SHIPPED (includes/seatgeek.php): the affiliate revenue play (~$11/sale vs TM's thin margins). Pure adapter: seatGeekFetch/seatGeekNormalize emit the same flat shape as marqueeNormalizeTm. Key = seatgeek client_id in api_keys (free at seatgeek.com/build). Affiliate aid in platform_settings seatgeek.affiliate_id, wrapped onto ticket urls when set (blank = links go straight to SeatGeek). Its native score is the trending order (sort=score.desc). Admin -> Marquee has a SeatGeek card + a Source selector on Ingest/Trending. dz seatgeek [do=test|trending|ingest].
Generalization plan: see docs/features/EVENT_FEEDS_ROADMAP.md. FeedSource interface; Ticketmaster + SeatGeek are adapters #1/#2. Facebook events are DEAD (no compliant API). Movies (Popcorn) = theaters from Places + Fandango affiliate deep-links now; paid showtimes feed only on demand. A generic ICS/RSS adapter is the on-brand long-tail win (civic/library/campus calendars -> gatherings). Keep it ONE engine with adapters, not forked per vertical.
Links: [[project_marquee_status]], the Observed World, GoHe.re gatherings, [[project_monetization_plan]] (per-source affiliate ledger).