mirror of https://github.com/kortix-ai/suna.git
chore(dev): ui fixes
This commit is contained in:
parent
a5179cc5fc
commit
0255ce7988
|
@ -1,96 +0,0 @@
|
||||||
-- Migration to fix double-escaped JSON in messages table
|
|
||||||
-- This fixes both content and metadata fields that were incorrectly stored as JSON strings
|
|
||||||
|
|
||||||
-- First, let's check how many messages need fixing (optional - for logging)
|
|
||||||
DO $$
|
|
||||||
DECLARE
|
|
||||||
total_records INTEGER;
|
|
||||||
records_to_fix INTEGER;
|
|
||||||
BEGIN
|
|
||||||
SELECT COUNT(*) INTO total_records FROM messages;
|
|
||||||
|
|
||||||
SELECT COUNT(*) INTO records_to_fix
|
|
||||||
FROM messages
|
|
||||||
WHERE (jsonb_typeof(content) = 'string' AND content::text LIKE '{%}')
|
|
||||||
OR (content ? 'content' AND jsonb_typeof(content->'content') = 'string' AND (content->'content')::text LIKE '{%}')
|
|
||||||
OR (jsonb_typeof(metadata) = 'string' AND metadata::text LIKE '{%}')
|
|
||||||
OR (metadata ? 'metadata' AND jsonb_typeof(metadata->'metadata') = 'string' AND (metadata->'metadata')::text LIKE '{%}');
|
|
||||||
|
|
||||||
RAISE NOTICE 'Total messages: %, Messages to fix: %', total_records, records_to_fix;
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
-- Create a backup table before making changes
|
|
||||||
CREATE TABLE IF NOT EXISTS messages_backup_before_json_fix AS
|
|
||||||
SELECT * FROM messages;
|
|
||||||
|
|
||||||
-- Fix all messages with double-escaped JSON
|
|
||||||
UPDATE messages
|
|
||||||
SET
|
|
||||||
content =
|
|
||||||
CASE
|
|
||||||
-- Handle case where entire content field is a JSON string
|
|
||||||
WHEN jsonb_typeof(content) = 'string' AND content::text LIKE '{%}' THEN
|
|
||||||
content::text::jsonb
|
|
||||||
WHEN jsonb_typeof(content) = 'string' AND content::text LIKE '[%]' THEN
|
|
||||||
content::text::jsonb
|
|
||||||
-- Handle case where 'content' field inside the JSON is improperly escaped
|
|
||||||
WHEN content ? 'content' AND jsonb_typeof(content->'content') = 'string' AND
|
|
||||||
((content->'content')::text LIKE '{%}' OR (content->'content')::text LIKE '[%]') THEN
|
|
||||||
jsonb_set(content, '{content}', (content->'content')::text::jsonb)
|
|
||||||
ELSE content
|
|
||||||
END,
|
|
||||||
metadata =
|
|
||||||
CASE
|
|
||||||
-- Handle case where entire metadata field is a JSON string
|
|
||||||
WHEN jsonb_typeof(metadata) = 'string' AND metadata::text LIKE '{%}' THEN
|
|
||||||
metadata::text::jsonb
|
|
||||||
WHEN jsonb_typeof(metadata) = 'string' AND metadata::text LIKE '[%]' THEN
|
|
||||||
metadata::text::jsonb
|
|
||||||
-- Handle case where nested values in metadata need fixing
|
|
||||||
WHEN metadata ? 'metadata' AND jsonb_typeof(metadata->'metadata') = 'string' AND
|
|
||||||
((metadata->'metadata')::text LIKE '{%}' OR (metadata->'metadata')::text LIKE '[%]') THEN
|
|
||||||
jsonb_set(metadata, '{metadata}', (metadata->'metadata')::text::jsonb)
|
|
||||||
ELSE metadata
|
|
||||||
END,
|
|
||||||
updated_at = NOW()
|
|
||||||
WHERE
|
|
||||||
-- Only update records that actually need fixing
|
|
||||||
(jsonb_typeof(content) = 'string' AND (content::text LIKE '{%}' OR content::text LIKE '[%]'))
|
|
||||||
OR (content ? 'content' AND jsonb_typeof(content->'content') = 'string' AND
|
|
||||||
((content->'content')::text LIKE '{%}' OR (content->'content')::text LIKE '[%]'))
|
|
||||||
OR (jsonb_typeof(metadata) = 'string' AND (metadata::text LIKE '{%}' OR metadata::text LIKE '[%]'))
|
|
||||||
OR (metadata ? 'metadata' AND jsonb_typeof(metadata->'metadata') = 'string' AND
|
|
||||||
((metadata->'metadata')::text LIKE '{%}' OR (metadata->'metadata')::text LIKE '[%]'));
|
|
||||||
|
|
||||||
-- Log the number of records updated
|
|
||||||
DO $$
|
|
||||||
DECLARE
|
|
||||||
rows_updated INTEGER;
|
|
||||||
BEGIN
|
|
||||||
GET DIAGNOSTICS rows_updated = ROW_COUNT;
|
|
||||||
RAISE NOTICE 'Updated % messages with double-escaped JSON', rows_updated;
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
-- Verify the fix by checking if any messages still have double-escaped JSON
|
|
||||||
DO $$
|
|
||||||
DECLARE
|
|
||||||
remaining_issues INTEGER;
|
|
||||||
BEGIN
|
|
||||||
SELECT COUNT(*) INTO remaining_issues
|
|
||||||
FROM messages
|
|
||||||
WHERE (jsonb_typeof(content) = 'string' AND (content::text LIKE '{%}' OR content::text LIKE '[%]'))
|
|
||||||
OR (content ? 'content' AND jsonb_typeof(content->'content') = 'string' AND
|
|
||||||
((content->'content')::text LIKE '{%}' OR (content->'content')::text LIKE '[%]'))
|
|
||||||
OR (jsonb_typeof(metadata) = 'string' AND (metadata::text LIKE '{%}' OR metadata::text LIKE '[%]'))
|
|
||||||
OR (metadata ? 'metadata' AND jsonb_typeof(metadata->'metadata') = 'string' AND
|
|
||||||
((metadata->'metadata')::text LIKE '{%}' OR (metadata->'metadata')::text LIKE '[%]'));
|
|
||||||
|
|
||||||
IF remaining_issues > 0 THEN
|
|
||||||
RAISE WARNING 'There are still % messages with potential double-escaped JSON', remaining_issues;
|
|
||||||
ELSE
|
|
||||||
RAISE NOTICE 'All double-escaped JSON issues have been fixed successfully';
|
|
||||||
END IF;
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
-- Optional: Create an index on updated_at if not exists to help with future queries
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_messages_updated_at ON messages(updated_at);
|
|
|
@ -1,196 +0,0 @@
|
||||||
-- FOOLPROOF Migration to fix double-escaped JSON in messages table
|
|
||||||
-- This will definitely work by using the simplest possible approach
|
|
||||||
|
|
||||||
-- Step 1: Create backup with timestamp
|
|
||||||
DO $$
|
|
||||||
DECLARE
|
|
||||||
backup_name TEXT;
|
|
||||||
BEGIN
|
|
||||||
backup_name := 'messages_backup_' || to_char(NOW(), 'YYYYMMDD_HH24MISS');
|
|
||||||
EXECUTE 'CREATE TABLE ' || backup_name || ' AS SELECT * FROM messages';
|
|
||||||
RAISE NOTICE 'Created backup table: %', backup_name;
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
-- Step 2: Show exactly what we're dealing with
|
|
||||||
DO $$
|
|
||||||
DECLARE
|
|
||||||
total_count INTEGER;
|
|
||||||
string_content_count INTEGER;
|
|
||||||
string_metadata_count INTEGER;
|
|
||||||
sample_content TEXT;
|
|
||||||
sample_metadata TEXT;
|
|
||||||
BEGIN
|
|
||||||
-- Count totals
|
|
||||||
SELECT COUNT(*) INTO total_count FROM messages;
|
|
||||||
|
|
||||||
-- Count content that's stored as strings (should be objects)
|
|
||||||
SELECT COUNT(*) INTO string_content_count
|
|
||||||
FROM messages
|
|
||||||
WHERE jsonb_typeof(content) = 'string';
|
|
||||||
|
|
||||||
-- Count metadata that's stored as strings (should be objects)
|
|
||||||
SELECT COUNT(*) INTO string_metadata_count
|
|
||||||
FROM messages
|
|
||||||
WHERE jsonb_typeof(metadata) = 'string';
|
|
||||||
|
|
||||||
-- Get samples
|
|
||||||
SELECT content::text INTO sample_content
|
|
||||||
FROM messages
|
|
||||||
WHERE jsonb_typeof(content) = 'string'
|
|
||||||
LIMIT 1;
|
|
||||||
|
|
||||||
SELECT metadata::text INTO sample_metadata
|
|
||||||
FROM messages
|
|
||||||
WHERE jsonb_typeof(metadata) = 'string'
|
|
||||||
LIMIT 1;
|
|
||||||
|
|
||||||
RAISE NOTICE 'Total messages: %', total_count;
|
|
||||||
RAISE NOTICE 'Messages with string content (should be objects): %', string_content_count;
|
|
||||||
RAISE NOTICE 'Messages with string metadata (should be objects): %', string_metadata_count;
|
|
||||||
|
|
||||||
IF sample_content IS NOT NULL THEN
|
|
||||||
RAISE NOTICE 'Sample string content: %', LEFT(sample_content, 150);
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
IF sample_metadata IS NOT NULL THEN
|
|
||||||
RAISE NOTICE 'Sample string metadata: %', LEFT(sample_metadata, 150);
|
|
||||||
END IF;
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
-- Step 3: Test parsing a few records to make sure it will work
|
|
||||||
DO $$
|
|
||||||
DECLARE
|
|
||||||
test_record RECORD;
|
|
||||||
parsed_content JSONB;
|
|
||||||
parsed_metadata JSONB;
|
|
||||||
success_count INTEGER := 0;
|
|
||||||
error_count INTEGER := 0;
|
|
||||||
BEGIN
|
|
||||||
FOR test_record IN
|
|
||||||
SELECT message_id, content, metadata
|
|
||||||
FROM messages
|
|
||||||
WHERE jsonb_typeof(content) = 'string'
|
|
||||||
OR jsonb_typeof(metadata) = 'string'
|
|
||||||
LIMIT 10
|
|
||||||
LOOP
|
|
||||||
BEGIN
|
|
||||||
-- Test content parsing
|
|
||||||
IF jsonb_typeof(test_record.content) = 'string' THEN
|
|
||||||
parsed_content := test_record.content::text::jsonb;
|
|
||||||
success_count := success_count + 1;
|
|
||||||
RAISE NOTICE 'SUCCESS: Parsed content for message %', test_record.message_id;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
-- Test metadata parsing
|
|
||||||
IF jsonb_typeof(test_record.metadata) = 'string' THEN
|
|
||||||
parsed_metadata := test_record.metadata::text::jsonb;
|
|
||||||
success_count := success_count + 1;
|
|
||||||
RAISE NOTICE 'SUCCESS: Parsed metadata for message %', test_record.message_id;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
EXCEPTION WHEN OTHERS THEN
|
|
||||||
error_count := error_count + 1;
|
|
||||||
RAISE WARNING 'ERROR: Failed to parse JSON for message %: %', test_record.message_id, SQLERRM;
|
|
||||||
END;
|
|
||||||
END LOOP;
|
|
||||||
|
|
||||||
RAISE NOTICE 'Test results: % successes, % errors', success_count, error_count;
|
|
||||||
|
|
||||||
IF error_count > 0 THEN
|
|
||||||
RAISE EXCEPTION 'Found parsing errors. Migration aborted for safety.';
|
|
||||||
END IF;
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
-- Step 4: Fix content field (do this separately for clarity)
|
|
||||||
DO $$
|
|
||||||
DECLARE
|
|
||||||
content_updates INTEGER := 0;
|
|
||||||
BEGIN
|
|
||||||
UPDATE messages
|
|
||||||
SET
|
|
||||||
content = content::text::jsonb,
|
|
||||||
updated_at = NOW()
|
|
||||||
WHERE jsonb_typeof(content) = 'string';
|
|
||||||
|
|
||||||
GET DIAGNOSTICS content_updates = ROW_COUNT;
|
|
||||||
RAISE NOTICE 'Fixed content field in % messages', content_updates;
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
-- Step 5: Fix metadata field (do this separately)
|
|
||||||
DO $$
|
|
||||||
DECLARE
|
|
||||||
metadata_updates INTEGER := 0;
|
|
||||||
BEGIN
|
|
||||||
UPDATE messages
|
|
||||||
SET
|
|
||||||
metadata = metadata::text::jsonb,
|
|
||||||
updated_at = NOW()
|
|
||||||
WHERE jsonb_typeof(metadata) = 'string';
|
|
||||||
|
|
||||||
GET DIAGNOSTICS metadata_updates = ROW_COUNT;
|
|
||||||
RAISE NOTICE 'Fixed metadata field in % messages', metadata_updates;
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
-- Step 6: Verify everything is fixed
|
|
||||||
DO $$
|
|
||||||
DECLARE
|
|
||||||
remaining_string_content INTEGER;
|
|
||||||
remaining_string_metadata INTEGER;
|
|
||||||
sample_fixed_content JSONB;
|
|
||||||
sample_fixed_metadata JSONB;
|
|
||||||
BEGIN
|
|
||||||
-- Check if any string fields remain
|
|
||||||
SELECT COUNT(*) INTO remaining_string_content
|
|
||||||
FROM messages
|
|
||||||
WHERE jsonb_typeof(content) = 'string';
|
|
||||||
|
|
||||||
SELECT COUNT(*) INTO remaining_string_metadata
|
|
||||||
FROM messages
|
|
||||||
WHERE jsonb_typeof(metadata) = 'string';
|
|
||||||
|
|
||||||
-- Get samples of fixed data
|
|
||||||
SELECT content INTO sample_fixed_content
|
|
||||||
FROM messages
|
|
||||||
WHERE updated_at >= NOW() - INTERVAL '5 minutes'
|
|
||||||
AND jsonb_typeof(content) = 'object'
|
|
||||||
LIMIT 1;
|
|
||||||
|
|
||||||
SELECT metadata INTO sample_fixed_metadata
|
|
||||||
FROM messages
|
|
||||||
WHERE updated_at >= NOW() - INTERVAL '5 minutes'
|
|
||||||
AND jsonb_typeof(metadata) = 'object'
|
|
||||||
LIMIT 1;
|
|
||||||
|
|
||||||
RAISE NOTICE 'Verification Results:';
|
|
||||||
RAISE NOTICE '- Remaining string content fields: %', remaining_string_content;
|
|
||||||
RAISE NOTICE '- Remaining string metadata fields: %', remaining_string_metadata;
|
|
||||||
|
|
||||||
IF sample_fixed_content IS NOT NULL THEN
|
|
||||||
RAISE NOTICE '- Sample fixed content: %', sample_fixed_content;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
IF sample_fixed_metadata IS NOT NULL THEN
|
|
||||||
RAISE NOTICE '- Sample fixed metadata: %', sample_fixed_metadata;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
IF remaining_string_content = 0 AND remaining_string_metadata = 0 THEN
|
|
||||||
RAISE NOTICE 'SUCCESS: All double-escaped JSON has been fixed!';
|
|
||||||
ELSE
|
|
||||||
RAISE WARNING 'Some string fields remain - manual investigation needed';
|
|
||||||
END IF;
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
-- Step 7: Create index if needed
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_messages_updated_at ON messages(updated_at);
|
|
||||||
|
|
||||||
-- Step 8: Final safety check
|
|
||||||
DO $$
|
|
||||||
DECLARE
|
|
||||||
total_valid INTEGER;
|
|
||||||
BEGIN
|
|
||||||
SELECT COUNT(*) INTO total_valid
|
|
||||||
FROM messages
|
|
||||||
WHERE content IS NOT NULL AND metadata IS NOT NULL;
|
|
||||||
|
|
||||||
RAISE NOTICE 'Final check: % messages have valid data', total_valid;
|
|
||||||
END $$;
|
|
Loading…
Reference in New Issue