Fixed Step 3 pipeline_configs migration: - Simplified JSONB aggregation logic - Properly scope pc alias in subqueries - Use UNNEST with FROM clause for array expansion Previous version had correlation issues with nested subqueries.
125 lines
4.6 KiB
SQL
125 lines
4.6 KiB
SQL
-- Migration 020: Unified Prompt System (Issue #28)
|
|
-- Consolidate ai_prompts and pipeline_configs into single system
|
|
-- Type: 'base' (reusable building blocks) or 'pipeline' (workflows)
|
|
|
|
-- Step 1: Add new columns to ai_prompts
|
|
ALTER TABLE ai_prompts
|
|
ADD COLUMN IF NOT EXISTS type VARCHAR(20) DEFAULT 'pipeline',
|
|
ADD COLUMN IF NOT EXISTS stages JSONB,
|
|
ADD COLUMN IF NOT EXISTS output_format VARCHAR(10) DEFAULT 'text',
|
|
ADD COLUMN IF NOT EXISTS output_schema JSONB;
|
|
|
|
-- Step 2: Migrate existing single-prompts to 1-stage pipeline format
|
|
-- All existing prompts become single-stage pipelines with inline source
|
|
UPDATE ai_prompts
|
|
SET
|
|
type = 'pipeline',
|
|
stages = jsonb_build_array(
|
|
jsonb_build_object(
|
|
'stage', 1,
|
|
'prompts', jsonb_build_array(
|
|
jsonb_build_object(
|
|
'source', 'inline',
|
|
'template', template,
|
|
'output_key', REPLACE(slug, 'pipeline_', ''),
|
|
'output_format', 'text'
|
|
)
|
|
)
|
|
)
|
|
),
|
|
output_format = 'text'
|
|
WHERE stages IS NULL;
|
|
|
|
-- Step 3: Migrate pipeline_configs into ai_prompts as multi-stage pipelines
|
|
-- Each pipeline_config becomes a pipeline-type prompt with multiple stages
|
|
INSERT INTO ai_prompts (
|
|
slug,
|
|
name,
|
|
description,
|
|
type,
|
|
stages,
|
|
output_format,
|
|
active,
|
|
is_system_default,
|
|
category
|
|
)
|
|
SELECT
|
|
'pipeline_config_' || LOWER(REPLACE(pc.name, ' ', '_')) || '_' || SUBSTRING(pc.id::TEXT FROM 1 FOR 8) as slug,
|
|
pc.name,
|
|
pc.description,
|
|
'pipeline' as type,
|
|
-- Build stages JSONB: combine stage1_prompts, stage2_prompt, stage3_prompt
|
|
(
|
|
-- Stage 1: Convert array to prompts
|
|
SELECT jsonb_agg(stage_obj ORDER BY stage_num)
|
|
FROM (
|
|
SELECT 1 as stage_num,
|
|
jsonb_build_object(
|
|
'stage', 1,
|
|
'prompts', (
|
|
SELECT jsonb_agg(
|
|
jsonb_build_object(
|
|
'source', 'reference',
|
|
'slug', s1.slug_val,
|
|
'output_key', REPLACE(s1.slug_val, 'pipeline_', 'stage1_'),
|
|
'output_format', 'json'
|
|
)
|
|
)
|
|
FROM UNNEST(pc.stage1_prompts) AS s1(slug_val)
|
|
)
|
|
) as stage_obj
|
|
WHERE array_length(pc.stage1_prompts, 1) > 0
|
|
|
|
UNION ALL
|
|
|
|
SELECT 2 as stage_num,
|
|
jsonb_build_object(
|
|
'stage', 2,
|
|
'prompts', jsonb_build_array(
|
|
jsonb_build_object(
|
|
'source', 'reference',
|
|
'slug', pc.stage2_prompt,
|
|
'output_key', 'synthesis',
|
|
'output_format', 'text'
|
|
)
|
|
)
|
|
) as stage_obj
|
|
WHERE pc.stage2_prompt IS NOT NULL
|
|
|
|
UNION ALL
|
|
|
|
SELECT 3 as stage_num,
|
|
jsonb_build_object(
|
|
'stage', 3,
|
|
'prompts', jsonb_build_array(
|
|
jsonb_build_object(
|
|
'source', 'reference',
|
|
'slug', pc.stage3_prompt,
|
|
'output_key', 'goals',
|
|
'output_format', 'text'
|
|
)
|
|
)
|
|
) as stage_obj
|
|
WHERE pc.stage3_prompt IS NOT NULL
|
|
) all_stages
|
|
) as stages,
|
|
'text' as output_format,
|
|
pc.active,
|
|
pc.is_default as is_system_default,
|
|
'pipeline' as category
|
|
FROM pipeline_configs pc;
|
|
|
|
-- Step 4: Add indices for performance
|
|
CREATE INDEX IF NOT EXISTS idx_ai_prompts_type ON ai_prompts(type);
|
|
CREATE INDEX IF NOT EXISTS idx_ai_prompts_stages ON ai_prompts USING GIN (stages);
|
|
|
|
-- Step 5: Add comment explaining stages structure
|
|
COMMENT ON COLUMN ai_prompts.stages IS 'JSONB array of stages, each with prompts array. Structure: [{"stage":1,"prompts":[{"source":"reference|inline","slug":"...","template":"...","output_key":"key","output_format":"text|json"}]}]';
|
|
|
|
-- Step 6: Backup pipeline_configs before eventual deletion
|
|
CREATE TABLE IF NOT EXISTS pipeline_configs_backup_pre_020 AS
|
|
SELECT * FROM pipeline_configs;
|
|
|
|
-- Note: We keep pipeline_configs table for now during transition period
|
|
-- It can be dropped in a later migration once all code is migrated
|