[object Object]

← back to Ventura Corridor

iter 93: sponsor-candidate-first generation order — generate_features.ts pickCandidates() now ORDERs by (paid_ads_count > 0 DESC, has_pitch DESC, random()) so businesses already running paid ads (proven ad buyers, monetization targets) get featured first; the next batch of overnight gens will surface sponsor-ready features for /scoreboard's 'sponsor candidates' board and the '$' badge filter on /magazine.html

21beb480bac6149ca4eb71607271e92eb03acd1a · 2026-05-06 17:07:29 -0700 · SteveStudio2

Files touched

Diff

commit 21beb480bac6149ca4eb71607271e92eb03acd1a
Author: SteveStudio2 <steve@designerwallcoverings.com>
Date:   Wed May 6 17:07:29 2026 -0700

    iter 93: sponsor-candidate-first generation order — generate_features.ts pickCandidates() now ORDERs by (paid_ads_count > 0 DESC, has_pitch DESC, random()) so businesses already running paid ads (proven ad buyers, monetization targets) get featured first; the next batch of overnight gens will surface sponsor-ready features for /scoreboard's 'sponsor candidates' board and the '$' badge filter on /magazine.html
---
 src/jobs/generate_features.ts | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/src/jobs/generate_features.ts b/src/jobs/generate_features.ts
index 97715db..64fb683 100644
--- a/src/jobs/generate_features.ts
+++ b/src/jobs/generate_features.ts
@@ -81,21 +81,30 @@ async function pickCandidates() {
     );
     return r.rows;
   }
-  // Skip businesses already featured; prefer those with a pitch (better metadata)
+  // Priority tiers for picking what to feature next:
+  //   1. Has paid-ad pixels (sponsor candidate — monetization target)
+  //   2. Has a pitch (rich metadata for better editorial)
+  //   3. Random
+  // Skip merged dupes, LLC/INC/CORP shells, anyone already featured.
   const r = await query(
     `SELECT b.id, b.name, b.address, b.city, b.zip, b.category,
             b.raw->>'primary_naics_description' AS naics,
             p.pitch_type,
+            COALESCE((be.ad_signals->>'paid_ads_count')::int, 0) AS paid_ads_count,
             TRIM(regexp_replace(b.address, '\\s*(SUITE|STE|UNIT|#).*$', '', 'i')) AS bldg_address
      FROM businesses b
      LEFT JOIN pitches p ON p.business_id = b.id
+     LEFT JOIN business_enrichment be ON be.business_id = b.id
      WHERE b.on_corridor
        AND b.merged_into IS NULL
        AND b.address IS NOT NULL
        AND b.name NOT ILIKE '%LLC' AND b.name NOT ILIKE '%INC' AND b.name NOT ILIKE '%CORP'
        AND length(b.name) BETWEEN 4 AND 60
        AND NOT EXISTS (SELECT 1 FROM magazine_features mf WHERE mf.business_id = b.id)
-     ORDER BY (p.pitch_type IS NOT NULL) DESC, random()
+     ORDER BY
+       (COALESCE((be.ad_signals->>'paid_ads_count')::int, 0) > 0) DESC,
+       (p.pitch_type IS NOT NULL) DESC,
+       random()
      LIMIT $1`,
     [COUNT]
   );

← bdb5ece iter 91+92: related-features carousel on /magazine/:id + mor  ·  back to Ventura Corridor  ·  iter 94+95+96: sponsorship rate-card + author byline + month 07a36d7 →