← back to Ventura Claw Leads

scripts/geocode-seed.js

45 lines

#!/usr/bin/env node
// v0.1 geocode pass — every seed business gets approximate coordinates based
// on the neighborhood centroid + a deterministic per-slug jitter (~±0.55mi)
// so dots don't stack in MarkerCluster. v0.2 swaps to Google Places lat/lng
// when we ingest real businesses.

const path = require('node:path');
require('dotenv').config({ path: path.resolve(__dirname, '..', '.env') });
const crypto = require('node:crypto');
const db = require('../lib/db');

// Approximate centroids on Ventura Blvd through each neighborhood.
const CENTROIDS = {
  'Sherman Oaks':   { lat: 34.1500, lng: -118.4498 },
  'Studio City':    { lat: 34.1450, lng: -118.3947 },
  'Encino':         { lat: 34.1597, lng: -118.5012 },
  'Tarzana':        { lat: 34.1717, lng: -118.5526 },
  'Woodland Hills': { lat: 34.1683, lng: -118.6068 }
};

function jitter(slug) {
  // ±0.008° ≈ ±0.55mi. Deterministic per slug.
  const h = crypto.createHash('sha256').update(slug).digest();
  const lx = ((h[0] / 255) - 0.5) * 0.016;
  const ly = ((h[1] / 255) - 0.5) * 0.016;
  return { lat: ly, lng: lx };
}

(async () => {
  const rows = await db.many(`SELECT id, slug, neighborhood, latitude FROM businesses`);
  let updated = 0, skipped = 0;
  for (const r of rows) {
    if (r.latitude !== null) { skipped++; continue; }
    const c = CENTROIDS[r.neighborhood] || CENTROIDS['Sherman Oaks'];
    const j = jitter(r.slug);
    await db.query(
      `UPDATE businesses SET latitude = $1, longitude = $2 WHERE id = $3`,
      [c.lat + j.lat, c.lng + j.lng, r.id]
    );
    updated++;
  }
  console.log(`[geocode-seed] updated=${updated} skipped=${skipped}`);
  await db.pool.end();
})().catch(e => { console.error('[geocode-seed] FATAL', e.message); process.exit(1); });