diff --git a/backend/src/services/seoGenerator.ts b/backend/src/services/seoGenerator.ts index a4c869e1..2cacae3b 100644 --- a/backend/src/services/seoGenerator.ts +++ b/backend/src/services/seoGenerator.ts @@ -6,8 +6,6 @@ */ import { getPool } from '../db/pool'; - -const pool = getPool(); import { ContentValidator } from '../utils/ContentValidator'; interface SeoPage { @@ -47,6 +45,7 @@ interface GenerationSpec { * Build generation spec based on page type */ async function buildSeoGenerationSpec(page: SeoPage): Promise { + const pool = getPool(); const spec: GenerationSpec = { type: page.type, slug: page.slug, @@ -54,12 +53,29 @@ async function buildSeoGenerationSpec(page: SeoPage): Promise { }; if (page.type === 'state') { - // Fetch state metrics - const stateCode = page.page_key.replace('states/', '').toUpperCase(); - const metricsResult = await pool.query(` - SELECT store_count, total_products, unique_brands, state_name - FROM mv_state_metrics WHERE state = $1 - `, [stateCode]); + // Fetch state metrics - page_key format is "state-az" or slug is "dispensaries-az" + const stateCode = (page.page_key.replace('state-', '') || page.slug.replace('dispensaries-', '')).toUpperCase(); + + // Try materialized view first, fall back to direct query + let metricsResult; + try { + metricsResult = await pool.query(` + SELECT store_count, total_products, unique_brands, state_name + FROM mv_state_metrics WHERE state = $1 + `, [stateCode]); + } catch (e) { + // Materialized view doesn't exist, use direct query + metricsResult = await pool.query(` + SELECT + COUNT(DISTINCT d.id) as store_count, + COUNT(DISTINCT p.id) as total_products, + COUNT(DISTINCT p.brand_name) as unique_brands, + $1 as state_name + FROM dispensaries d + LEFT JOIN dutchie_products p ON p.dispensary_id = d.id + WHERE d.state = $1 + `, [stateCode]); + } if (metricsResult.rows[0]) { spec.metrics = { @@ -150,6 +166,8 @@ function generateSeoContent(spec: GenerationSpec): GeneratedSeoPayload { * Main generation pipeline */ export async function generateSeoPageWithClaude(pageId: number): Promise { + const pool = getPool(); + // 1. Load page const pageResult = await pool.query( 'SELECT id, type, slug, page_key, primary_keyword FROM seo_pages WHERE id = $1',