mitai-jinkendo/backend/migrations/020_unified_prompt_system.sql
Lars 2e0838ca08
All checks were successful
Deploy Development / deploy (push) Successful in 50s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 13s
feat: unified prompt system migration schema (Issue #28 Phase 1)
- Migration 020: Add type, stages, output_format columns to ai_prompts
- Migrate existing prompts to 1-stage pipeline format
- Migrate pipeline_configs into ai_prompts as multi-stage pipelines
- Add UnifiedPrompt Pydantic models for new API
- Backup pipeline_configs table (keep during transition)

Schema structure:
- type: 'base' (reusable) or 'pipeline' (multi-stage)
- stages: JSONB array [{stage:1, prompts:[{source, slug, template, output_key, output_format}]}]
- output_format: 'text' or 'json'
- output_schema: JSON validation schema (optional)

Next: Backend executor + Frontend UI consolidation
2026-03-25 10:43:10 +01:00

125 lines
4.1 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(name, ' ', '_')) || '_' || SUBSTRING(id::TEXT FROM 1 FOR 8),
name,
description,
'pipeline',
-- Build stages JSONB structure
(
SELECT jsonb_agg(
jsonb_build_object(
'stage', stage_num,
'prompts', stage_prompts
)
ORDER BY stage_num
)
FROM (
-- Stage 1: All parallel prompts
SELECT
1 as stage_num,
jsonb_agg(
jsonb_build_object(
'source', 'reference',
'slug', stage1_slug,
'output_key', REPLACE(stage1_slug, 'pipeline_', 'stage1_'),
'output_format', 'json'
)
) as stage_prompts
FROM UNNEST(pc.stage1_prompts) as stage1_slug
UNION ALL
-- Stage 2: Synthesis prompt
SELECT
2 as stage_num,
jsonb_build_array(
jsonb_build_object(
'source', 'reference',
'slug', pc.stage2_prompt,
'output_key', 'synthesis',
'output_format', 'text'
)
) as stage_prompts
WHERE pc.stage2_prompt IS NOT NULL
UNION ALL
-- Stage 3: Optional goals/analysis prompt
SELECT
3 as stage_num,
jsonb_build_array(
jsonb_build_object(
'source', 'reference',
'slug', pc.stage3_prompt,
'output_key', 'goals',
'output_format', 'text'
)
) as stage_prompts
WHERE pc.stage3_prompt IS NOT NULL
) stages_union
) as stages,
'text',
pc.active,
pc.is_default,
'pipeline'
FROM pipeline_configs pc
WHERE pc.id IS NOT NULL;
-- 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