const { Pool } = require('pg'); require('dotenv').config({ path: '.env.local' }); const SYSTEM_USER_ID = '00000000-0000-0000-0000-000000000000'; (async () => { const pool = new Pool({ connectionString: process.env.LOCAL_DB_URL }); const client = await pool.connect(); try { await client.query('BEGIN'); const byUniqueCustomModel = await client.query(` WITH model_owners AS ( SELECT params->>'model' AS model, ARRAY_AGG(DISTINCT user_id) FILTER (WHERE user_id IS NOT NULL AND user_id <> $1) AS owner_ids FROM works WHERE status = 'completed' AND params->>'model' LIKE 'custom:%' AND EXISTS (SELECT 1 FROM profiles p WHERE p.id = works.user_id) GROUP BY params->>'model' ), unique_model_owners AS ( SELECT model, owner_ids[1] AS owner_id FROM model_owners WHERE CARDINALITY(owner_ids) = 1 ), updated AS ( UPDATE works w SET user_id = umo.owner_id, updated_at = NOW() FROM unique_model_owners umo WHERE w.user_id = $1 AND w.status = 'completed' AND w.is_public = true AND w.params->>'model' = umo.model RETURNING w.id, w.user_id, w.params->>'model' AS model ) SELECT COUNT(*)::int AS fixed_count, json_agg(updated) AS rows FROM updated `, [SYSTEM_USER_ID]); const byExactPromptTime = await client.query(` WITH candidates AS ( SELECT DISTINCT ON (public.id) public.id AS public_id, private.user_id AS owner_user_id, ABS(EXTRACT(EPOCH FROM (private.created_at - public.created_at))) AS time_distance FROM works public JOIN works private ON private.id <> public.id AND private.user_id IS NOT NULL AND private.user_id <> $1 AND COALESCE(private.prompt, '') <> '' AND private.prompt = public.prompt AND private.created_at BETWEEN public.created_at - INTERVAL '30 minutes' AND public.created_at + INTERVAL '30 minutes' JOIN profiles p ON p.id = private.user_id WHERE public.user_id = $1 AND public.is_public = true AND public.status = 'completed' ORDER BY public.id, time_distance ), unambiguous AS ( SELECT public_id, MIN(owner_user_id::text)::uuid AS owner_user_id FROM candidates GROUP BY public_id HAVING COUNT(DISTINCT owner_user_id) = 1 ), updated AS ( UPDATE works w SET user_id = unambiguous.owner_user_id, updated_at = NOW() FROM unambiguous WHERE w.id = unambiguous.public_id AND w.user_id = $1 RETURNING w.id, w.user_id, w.params->>'model' AS model ) SELECT COUNT(*)::int AS fixed_count, json_agg(updated) AS rows FROM updated `, [SYSTEM_USER_ID]); await client.query('COMMIT'); console.log(JSON.stringify({ byUniqueCustomModel: byUniqueCustomModel.rows[0] || { fixed_count: 0, rows: [] }, byExactPromptTime: byExactPromptTime.rows[0] || { fixed_count: 0, rows: [] }, }, null, 2)); } catch (error) { await client.query('ROLLBACK'); throw error; } finally { client.release(); await pool.end(); } })().catch(error => { console.error(error); process.exit(1); });