← back to Small Business Builder

src/lib/vertical.js

43 lines

// Cheap heuristic classifier — no LLM, just keyword match on already-scraped meta.
// Returns one of: salon, restaurant, lawyer, vet, ecom, saas-landing, advocacy, generic.

const RULES = [
  { v: 'salon',         kws: ['salon','barber','barbershop','nails','nail salon','blowout','color services','stylist','haircut'] },
  { v: 'restaurant',    kws: ['restaurant','menu','reservations','dine','cafe','bistro','eatery','catering','bar & grill'] },
  { v: 'lawyer',        kws: ['attorney','lawyer','law firm','legal services','injury law','dui','divorce attorney','of counsel'] },
  { v: 'vet',           kws: ['veterinary','veterinarian','animal hospital','pet clinic','vaccination','spay','neuter'] },
  { v: 'advocacy',      kws: ['501(c)','non-profit','non profit','donate','petition','take action','our mission','volunteer','coalition','student debt','justice'] },
  { v: 'saas-landing',  kws: ['platform','api','sdk','dashboard','sign up free','start free trial','pricing per seat','log in','features','docs'] },
  { v: 'ecom',          kws: ['add to cart','shop now','free shipping','my bag','checkout','reviews ★','pdp','product details'] },
];

export function detectVertical({ title='', description='', og_description='', og_title='', html='' } = {}) {
  const blob = [title, description, og_description, og_title, (html||'').slice(0, 8000)]
    .join(' ').toLowerCase();
  for (const { v, kws } of RULES) {
    let hits = 0;
    for (const kw of kws) if (blob.includes(kw)) hits += 1;
    if (hits >= 2) return v;
  }
  // single-keyword fallback
  for (const { v, kws } of RULES) for (const kw of kws) if (blob.includes(kw)) return v;
  return 'generic';
}

// Pick 3 distinct theme directions for a given vertical.
// Lite version of the mockups skill — used by the small-business-builder /website-analysis
// entry endpoint.
export function pickThemesFor(vertical) {
  const POOL = {
    salon:        ['editorial', 'neon', 'minimalist-spa'],
    restaurant:   ['magazine', 'neon', 'minimalist'],
    lawyer:       ['authoritative', 'minimalist', 'editorial'],
    vet:          ['warm', 'editorial', 'minimalist'],
    advocacy:     ['brutalist', 'magazine', 'tools-forward'],
    'saas-landing': ['minimalist', 'editorial', 'brutalist'],
    ecom:         ['editorial', 'minimalist', 'magazine'],
    generic:      ['editorial', 'brutalist', 'minimalist'],
  };
  return POOL[vertical] || POOL.generic;
}