feat: content generation engine - spintax resolver, API endpoints, BullMQ worker

This commit is contained in:
cawcenter
2025-12-15 01:53:51 -05:00
parent 2a9b4c5f92
commit 0fc881c0ad
6 changed files with 727 additions and 0 deletions

View File

@@ -0,0 +1,54 @@
-- Phase 1: Content Generation Schema Updates
-- Add columns to existing tables
ALTER TABLE avatars
ADD COLUMN IF NOT EXISTS industry VARCHAR(255),
ADD COLUMN IF NOT EXISTS pain_point TEXT,
ADD COLUMN IF NOT EXISTS value_prop TEXT;
ALTER TABLE campaign_masters
ADD COLUMN IF NOT EXISTS site_id UUID REFERENCES sites (id) ON DELETE CASCADE;
ALTER TABLE content_fragments
ADD COLUMN IF NOT EXISTS campaign_id UUID REFERENCES campaign_masters (id) ON DELETE CASCADE,
ADD COLUMN IF NOT EXISTS content_hash VARCHAR(64) UNIQUE,
ADD COLUMN IF NOT EXISTS use_count INTEGER DEFAULT 0;
-- New table: variation_registry (track unique combinations)
CREATE TABLE IF NOT EXISTS variation_registry (
id UUID PRIMARY KEY DEFAULT gen_random_uuid (),
campaign_id UUID NOT NULL REFERENCES campaign_masters (id) ON DELETE CASCADE,
variation_hash VARCHAR(64) UNIQUE NOT NULL,
resolved_variables JSONB NOT NULL,
spintax_choices JSONB NOT NULL,
post_id UUID REFERENCES posts (id) ON DELETE SET NULL,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE UNIQUE INDEX IF NOT EXISTS idx_variation_hash ON variation_registry (variation_hash);
-- New table: block_usage_stats (track how many times each block is used)
CREATE TABLE IF NOT EXISTS block_usage_stats (
id UUID PRIMARY KEY DEFAULT gen_random_uuid (),
content_fragment_id UUID REFERENCES content_fragments (id) ON DELETE CASCADE,
block_type VARCHAR(255) NOT NULL,
total_uses INTEGER DEFAULT 0,
last_used_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE (content_fragment_id)
);
-- New table: spintax_variation_stats (track which spintax choices are used most)
CREATE TABLE IF NOT EXISTS spintax_variation_stats (
id UUID PRIMARY KEY DEFAULT gen_random_uuid (),
content_fragment_id UUID REFERENCES content_fragments (id) ON DELETE CASCADE,
variation_path TEXT NOT NULL, -- e.g., "hero.h1.option_1"
variation_text TEXT NOT NULL,
use_count INTEGER DEFAULT 0,
last_used_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_block_usage_fragment ON block_usage_stats (content_fragment_id);
CREATE INDEX IF NOT EXISTS idx_spintax_stats_fragment ON spintax_variation_stats (content_fragment_id);