fix: Fix SEO generator - lazy pool init, fallback queries
- Move pool initialization inside functions (lazy loading) - Fix page_key parsing for state-XX format - Add fallback query if mv_state_metrics doesn't exist 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -6,8 +6,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { getPool } from '../db/pool';
|
import { getPool } from '../db/pool';
|
||||||
|
|
||||||
const pool = getPool();
|
|
||||||
import { ContentValidator } from '../utils/ContentValidator';
|
import { ContentValidator } from '../utils/ContentValidator';
|
||||||
|
|
||||||
interface SeoPage {
|
interface SeoPage {
|
||||||
@@ -47,6 +45,7 @@ interface GenerationSpec {
|
|||||||
* Build generation spec based on page type
|
* Build generation spec based on page type
|
||||||
*/
|
*/
|
||||||
async function buildSeoGenerationSpec(page: SeoPage): Promise<GenerationSpec> {
|
async function buildSeoGenerationSpec(page: SeoPage): Promise<GenerationSpec> {
|
||||||
|
const pool = getPool();
|
||||||
const spec: GenerationSpec = {
|
const spec: GenerationSpec = {
|
||||||
type: page.type,
|
type: page.type,
|
||||||
slug: page.slug,
|
slug: page.slug,
|
||||||
@@ -54,12 +53,29 @@ async function buildSeoGenerationSpec(page: SeoPage): Promise<GenerationSpec> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (page.type === 'state') {
|
if (page.type === 'state') {
|
||||||
// Fetch state metrics
|
// Fetch state metrics - page_key format is "state-az" or slug is "dispensaries-az"
|
||||||
const stateCode = page.page_key.replace('states/', '').toUpperCase();
|
const stateCode = (page.page_key.replace('state-', '') || page.slug.replace('dispensaries-', '')).toUpperCase();
|
||||||
const metricsResult = await pool.query(`
|
|
||||||
SELECT store_count, total_products, unique_brands, state_name
|
// Try materialized view first, fall back to direct query
|
||||||
FROM mv_state_metrics WHERE state = $1
|
let metricsResult;
|
||||||
`, [stateCode]);
|
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]) {
|
if (metricsResult.rows[0]) {
|
||||||
spec.metrics = {
|
spec.metrics = {
|
||||||
@@ -150,6 +166,8 @@ function generateSeoContent(spec: GenerationSpec): GeneratedSeoPayload {
|
|||||||
* Main generation pipeline
|
* Main generation pipeline
|
||||||
*/
|
*/
|
||||||
export async function generateSeoPageWithClaude(pageId: number): Promise<SeoPageContent> {
|
export async function generateSeoPageWithClaude(pageId: number): Promise<SeoPageContent> {
|
||||||
|
const pool = getPool();
|
||||||
|
|
||||||
// 1. Load page
|
// 1. Load page
|
||||||
const pageResult = await pool.query(
|
const pageResult = await pool.query(
|
||||||
'SELECT id, type, slug, page_key, primary_keyword FROM seo_pages WHERE id = $1',
|
'SELECT id, type, slug, page_key, primary_keyword FROM seo_pages WHERE id = $1',
|
||||||
|
|||||||
Reference in New Issue
Block a user