diff --git a/priv/repo/migrations/20260122231235_assign_mitglied_role_to_existing_users.exs b/priv/repo/migrations/20260122231235_assign_mitglied_role_to_existing_users.exs index 2f345a2..548de8b 100644 --- a/priv/repo/migrations/20260122231235_assign_mitglied_role_to_existing_users.exs +++ b/priv/repo/migrations/20260122231235_assign_mitglied_role_to_existing_users.exs @@ -3,35 +3,54 @@ defmodule Mv.Repo.Migrations.AssignMitgliedRoleToExistingUsers do Assigns the "Mitglied" role to all existing users without a role. This migration runs once during deployment to ensure all users have a role assigned. - New users will automatically get the "Mitglied" role via the AssignDefaultRole change. + New users will automatically get the "Mitglied" role via the role_id attribute's default function. """ use Ecto.Migration import Ecto.Query def up do - # Find the Mitglied role ID + # Find or create the "Mitglied" role + # This ensures the migration works even if seeds haven't run yet mitglied_role_id = - repo().one( - from(r in "roles", - where: r.name == "Mitglied", - select: r.id - ) + case repo().one( + from(r in "roles", + where: r.name == "Mitglied", + select: r.id + ) + ) do + nil -> + # Role doesn't exist - create it + # This is idempotent and safe because the role name is unique + # Use execute with SQL string to properly use uuid_generate_v7() function + execute(""" + INSERT INTO roles (id, name, description, permission_set_name, is_system_role, inserted_at, updated_at) + VALUES (uuid_generate_v7(), 'Mitglied', 'Default member role with access to own data only', 'own_data', true, (now() AT TIME ZONE 'utc'), (now() AT TIME ZONE 'utc')) + """) + + # Get the created role ID + role_id = + repo().one( + from(r in "roles", + where: r.name == "Mitglied", + select: r.id + ) + ) + + IO.puts("✅ Created 'Mitglied' role (was missing)") + role_id + + role_id -> + role_id + end + + # Assign Mitglied role to all users without a role + {count, _} = + repo().update_all( + from(u in "users", where: is_nil(u.role_id)), + set: [role_id: mitglied_role_id] ) - if mitglied_role_id do - # Assign Mitglied role to all users without a role - updated_count = - repo().update_all( - from(u in "users", where: is_nil(u.role_id)), - set: [role_id: mitglied_role_id] - ) - - IO.puts("✅ Assigned 'Mitglied' role to #{updated_count} existing user(s)") - else - IO.puts("⚠️ Warning: 'Mitglied' role not found - skipping role assignment") - IO.puts(" This is expected if roles haven't been seeded yet.") - IO.puts(" New users will get the role automatically via AssignDefaultRole change.") - end + IO.puts("✅ Assigned 'Mitglied' role to #{count} existing user(s)") end def down do