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