feat: SEO template library, discovery pipeline, and orchestrator enhancements
## SEO Template Library - Add complete template library with 7 page types (state, city, category, brand, product, search, regeneration) - Add Template Library tab in SEO Orchestrator with accordion-based editors - Add template preview, validation, and variable injection engine - Add API endpoints: /api/seo/templates, preview, validate, generate, regenerate ## Discovery Pipeline - Add promotion.ts for discovery location validation and promotion - Add discover-all-states.ts script for multi-state discovery - Add promotion log migration (067) - Enhance discovery routes and types ## Orchestrator & Admin - Add crawl_enabled filter to stores page - Add API permissions page - Add job queue management - Add price analytics routes - Add markets and intelligence routes - Enhance dashboard and worker monitoring ## Infrastructure - Add migrations for worker definitions, SEO settings, field alignment - Add canonical pipeline for scraper v2 - Update hydration and sync orchestrator - Enhance multi-state query service 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
140
backend/migrations/066_dutchie_field_alignment.sql
Normal file
140
backend/migrations/066_dutchie_field_alignment.sql
Normal file
@@ -0,0 +1,140 @@
|
||||
-- Migration 066: Align dispensaries and discovery_locations tables with Dutchie field names
|
||||
-- Uses snake_case convention (Postgres standard) mapped from Dutchie's camelCase
|
||||
--
|
||||
-- Changes:
|
||||
-- 1. dispensaries: rename address→address1, zip→zipcode, remove company_name
|
||||
-- 2. dispensaries: add missing Dutchie fields
|
||||
-- 3. dutchie_discovery_locations: add missing Dutchie fields
|
||||
|
||||
-- ============================================================================
|
||||
-- DISPENSARIES TABLE
|
||||
-- ============================================================================
|
||||
|
||||
-- Rename address to address1 (matches Dutchie's address1)
|
||||
ALTER TABLE dispensaries RENAME COLUMN address TO address1;
|
||||
|
||||
-- Rename zip to zipcode (matches Dutchie's zip, but we use zipcode for clarity)
|
||||
ALTER TABLE dispensaries RENAME COLUMN zip TO zipcode;
|
||||
|
||||
-- Drop company_name (redundant with name)
|
||||
ALTER TABLE dispensaries DROP COLUMN IF EXISTS company_name;
|
||||
|
||||
-- Add address2
|
||||
ALTER TABLE dispensaries ADD COLUMN IF NOT EXISTS address2 VARCHAR(255);
|
||||
|
||||
-- Add country
|
||||
ALTER TABLE dispensaries ADD COLUMN IF NOT EXISTS country VARCHAR(100) DEFAULT 'United States';
|
||||
|
||||
-- Add timezone
|
||||
ALTER TABLE dispensaries ADD COLUMN IF NOT EXISTS timezone VARCHAR(50);
|
||||
|
||||
-- Add email
|
||||
ALTER TABLE dispensaries ADD COLUMN IF NOT EXISTS email VARCHAR(255);
|
||||
|
||||
-- Add description
|
||||
ALTER TABLE dispensaries ADD COLUMN IF NOT EXISTS description TEXT;
|
||||
|
||||
-- Add logo_image (Dutchie: logoImage)
|
||||
ALTER TABLE dispensaries ADD COLUMN IF NOT EXISTS logo_image TEXT;
|
||||
|
||||
-- Add banner_image (Dutchie: bannerImage)
|
||||
ALTER TABLE dispensaries ADD COLUMN IF NOT EXISTS banner_image TEXT;
|
||||
|
||||
-- Add offer_pickup (Dutchie: offerPickup)
|
||||
ALTER TABLE dispensaries ADD COLUMN IF NOT EXISTS offer_pickup BOOLEAN DEFAULT TRUE;
|
||||
|
||||
-- Add offer_delivery (Dutchie: offerDelivery)
|
||||
ALTER TABLE dispensaries ADD COLUMN IF NOT EXISTS offer_delivery BOOLEAN DEFAULT FALSE;
|
||||
|
||||
-- Add offer_curbside_pickup (Dutchie: offerCurbsidePickup)
|
||||
ALTER TABLE dispensaries ADD COLUMN IF NOT EXISTS offer_curbside_pickup BOOLEAN DEFAULT FALSE;
|
||||
|
||||
-- Add is_medical (Dutchie: isMedical)
|
||||
ALTER TABLE dispensaries ADD COLUMN IF NOT EXISTS is_medical BOOLEAN DEFAULT FALSE;
|
||||
|
||||
-- Add is_recreational (Dutchie: isRecreational)
|
||||
ALTER TABLE dispensaries ADD COLUMN IF NOT EXISTS is_recreational BOOLEAN DEFAULT FALSE;
|
||||
|
||||
-- Add chain_slug (Dutchie: chain)
|
||||
ALTER TABLE dispensaries ADD COLUMN IF NOT EXISTS chain_slug VARCHAR(255);
|
||||
|
||||
-- Add enterprise_id (Dutchie: retailer.enterpriseId)
|
||||
ALTER TABLE dispensaries ADD COLUMN IF NOT EXISTS enterprise_id VARCHAR(100);
|
||||
|
||||
-- Add status (Dutchie: status - open/closed)
|
||||
ALTER TABLE dispensaries ADD COLUMN IF NOT EXISTS status VARCHAR(50);
|
||||
|
||||
-- Add c_name (Dutchie: cName - the URL slug used in embedded menus)
|
||||
ALTER TABLE dispensaries ADD COLUMN IF NOT EXISTS c_name VARCHAR(255);
|
||||
|
||||
-- ============================================================================
|
||||
-- DUTCHIE_DISCOVERY_LOCATIONS TABLE
|
||||
-- ============================================================================
|
||||
|
||||
-- Add phone
|
||||
ALTER TABLE dutchie_discovery_locations ADD COLUMN IF NOT EXISTS phone VARCHAR(50);
|
||||
|
||||
-- Add website (Dutchie: embedBackUrl)
|
||||
ALTER TABLE dutchie_discovery_locations ADD COLUMN IF NOT EXISTS website TEXT;
|
||||
|
||||
-- Add email
|
||||
ALTER TABLE dutchie_discovery_locations ADD COLUMN IF NOT EXISTS email VARCHAR(255);
|
||||
|
||||
-- Add description
|
||||
ALTER TABLE dutchie_discovery_locations ADD COLUMN IF NOT EXISTS description TEXT;
|
||||
|
||||
-- Add logo_image
|
||||
ALTER TABLE dutchie_discovery_locations ADD COLUMN IF NOT EXISTS logo_image TEXT;
|
||||
|
||||
-- Add banner_image
|
||||
ALTER TABLE dutchie_discovery_locations ADD COLUMN IF NOT EXISTS banner_image TEXT;
|
||||
|
||||
-- Add chain_slug
|
||||
ALTER TABLE dutchie_discovery_locations ADD COLUMN IF NOT EXISTS chain_slug VARCHAR(255);
|
||||
|
||||
-- Add enterprise_id
|
||||
ALTER TABLE dutchie_discovery_locations ADD COLUMN IF NOT EXISTS enterprise_id VARCHAR(100);
|
||||
|
||||
-- Add c_name
|
||||
ALTER TABLE dutchie_discovery_locations ADD COLUMN IF NOT EXISTS c_name VARCHAR(255);
|
||||
|
||||
-- Add country
|
||||
ALTER TABLE dutchie_discovery_locations ADD COLUMN IF NOT EXISTS country VARCHAR(100) DEFAULT 'United States';
|
||||
|
||||
-- Add store status
|
||||
ALTER TABLE dutchie_discovery_locations ADD COLUMN IF NOT EXISTS store_status VARCHAR(50);
|
||||
|
||||
-- ============================================================================
|
||||
-- INDEXES
|
||||
-- ============================================================================
|
||||
|
||||
-- Index for chain lookups
|
||||
CREATE INDEX IF NOT EXISTS idx_dispensaries_chain_slug ON dispensaries(chain_slug) WHERE chain_slug IS NOT NULL;
|
||||
CREATE INDEX IF NOT EXISTS idx_discovery_locations_chain_slug ON dutchie_discovery_locations(chain_slug) WHERE chain_slug IS NOT NULL;
|
||||
|
||||
-- Index for enterprise lookups (for multi-location chains)
|
||||
CREATE INDEX IF NOT EXISTS idx_dispensaries_enterprise_id ON dispensaries(enterprise_id) WHERE enterprise_id IS NOT NULL;
|
||||
CREATE INDEX IF NOT EXISTS idx_discovery_locations_enterprise_id ON dutchie_discovery_locations(enterprise_id) WHERE enterprise_id IS NOT NULL;
|
||||
|
||||
-- Index for c_name lookups
|
||||
CREATE INDEX IF NOT EXISTS idx_dispensaries_c_name ON dispensaries(c_name) WHERE c_name IS NOT NULL;
|
||||
|
||||
-- ============================================================================
|
||||
-- COMMENTS
|
||||
-- ============================================================================
|
||||
|
||||
COMMENT ON COLUMN dispensaries.address1 IS 'Street address line 1 (Dutchie: address1)';
|
||||
COMMENT ON COLUMN dispensaries.address2 IS 'Street address line 2 (Dutchie: address2)';
|
||||
COMMENT ON COLUMN dispensaries.zipcode IS 'ZIP/postal code (Dutchie: zip)';
|
||||
COMMENT ON COLUMN dispensaries.c_name IS 'Dutchie URL slug for embedded menus (Dutchie: cName)';
|
||||
COMMENT ON COLUMN dispensaries.chain_slug IS 'Chain identifier slug (Dutchie: chain)';
|
||||
COMMENT ON COLUMN dispensaries.enterprise_id IS 'Parent enterprise UUID (Dutchie: retailer.enterpriseId)';
|
||||
COMMENT ON COLUMN dispensaries.logo_image IS 'Logo image URL (Dutchie: logoImage)';
|
||||
COMMENT ON COLUMN dispensaries.banner_image IS 'Banner image URL (Dutchie: bannerImage)';
|
||||
COMMENT ON COLUMN dispensaries.offer_pickup IS 'Offers in-store pickup (Dutchie: offerPickup)';
|
||||
COMMENT ON COLUMN dispensaries.offer_delivery IS 'Offers delivery (Dutchie: offerDelivery)';
|
||||
COMMENT ON COLUMN dispensaries.offer_curbside_pickup IS 'Offers curbside pickup (Dutchie: offerCurbsidePickup)';
|
||||
COMMENT ON COLUMN dispensaries.is_medical IS 'Licensed for medical sales (Dutchie: isMedical)';
|
||||
COMMENT ON COLUMN dispensaries.is_recreational IS 'Licensed for recreational sales (Dutchie: isRecreational)';
|
||||
|
||||
SELECT 'Migration 066 completed: Dutchie field alignment' as status;
|
||||
Reference in New Issue
Block a user