diff --git a/prisma/migrations/20260507000000_migrate_todos_to_ideas/migration.sql b/prisma/migrations/20260507000000_migrate_todos_to_ideas/migration.sql new file mode 100644 index 0000000..4d740ae --- /dev/null +++ b/prisma/migrations/20260507000000_migrate_todos_to_ideas/migration.sql @@ -0,0 +1,59 @@ +BEGIN; + +WITH active_todos AS ( + SELECT t.id, t.user_id, t.product_id, t.title, t.description, t.created_at + FROM todos t + WHERE t.done = false + AND t.archived = false + AND NOT EXISTS ( + SELECT 1 FROM ideas i + WHERE i.user_id = t.user_id + AND lower(trim(i.title)) = lower(trim(t.title)) + ) +), +user_base AS ( + SELECT ut.user_id, u.idea_code_counter AS base_counter + FROM (SELECT DISTINCT user_id FROM active_todos) ut + JOIN users u ON u.id = ut.user_id +), +ranked AS ( + SELECT + at.user_id, at.product_id, at.title, at.description, at.created_at, + ub.base_counter, + ROW_NUMBER() OVER (PARTITION BY at.user_id ORDER BY at.created_at, at.id) AS rn + FROM active_todos at + JOIN user_base ub ON ub.user_id = at.user_id +), +inserted AS ( + INSERT INTO ideas ( + id, user_id, product_id, code, title, description, + status, archived, created_at, updated_at + ) + SELECT + gen_random_uuid()::text, + user_id, + product_id, + 'IDEA-' || lpad((base_counter + rn)::text, 3, '0'), + title, + description, + 'DRAFT', + false, + created_at, + now() + FROM ranked + RETURNING user_id, + (regexp_replace(code, '^IDEA-0*', ''))::int AS used_counter +) +UPDATE users u +SET idea_code_counter = sub.max_counter +FROM ( + SELECT user_id, MAX(used_counter) AS max_counter + FROM inserted + GROUP BY user_id +) sub +WHERE u.id = sub.user_id + AND sub.max_counter > u.idea_code_counter; + +DROP TABLE todos; + +COMMIT;