Ensure system actor user exists via migration
Creates user system@mila.local with Admin role if missing. Idempotent; guarantees system actor in production without relying on seeds.
This commit is contained in:
parent
0a2aa3bad0
commit
acb33b9f3b
1 changed files with 59 additions and 0 deletions
|
|
@ -0,0 +1,59 @@
|
|||
defmodule Mv.Repo.Migrations.EnsureSystemActorUserExists do
|
||||
@moduledoc """
|
||||
Ensures the system actor user always exists.
|
||||
|
||||
The system actor is used for systemic operations (email sync, cycle generation,
|
||||
background jobs). It is created by seeds in development; in production seeds
|
||||
may not run, so this migration guarantees the user exists.
|
||||
|
||||
Creates a user with email "system@mila.local" (default from Mv.Helpers.SystemActor)
|
||||
and the Admin role. The user has no password and no OIDC ID, so it cannot log in.
|
||||
"""
|
||||
use Ecto.Migration
|
||||
import Ecto.Query
|
||||
|
||||
@system_user_email "system@mila.local"
|
||||
|
||||
def up do
|
||||
admin_role_id = ensure_admin_role_exists()
|
||||
ensure_system_actor_user_exists(admin_role_id)
|
||||
end
|
||||
|
||||
def down do
|
||||
# Not reversible - do not delete system user on rollback
|
||||
:ok
|
||||
end
|
||||
|
||||
defp ensure_admin_role_exists do
|
||||
case repo().one(from(r in "roles", where: r.name == "Admin", select: r.id)) do
|
||||
nil ->
|
||||
execute("""
|
||||
INSERT INTO roles (id, name, description, permission_set_name, is_system_role, inserted_at, updated_at)
|
||||
VALUES (uuid_generate_v7(), 'Admin', 'Administrator with full access', 'admin', false, (now() AT TIME ZONE 'utc'), (now() AT TIME ZONE 'utc'))
|
||||
""")
|
||||
|
||||
role_id = repo().one(from(r in "roles", where: r.name == "Admin", select: r.id))
|
||||
IO.puts("✅ Created 'Admin' role (was missing)")
|
||||
role_id
|
||||
|
||||
role_id ->
|
||||
role_id
|
||||
end
|
||||
end
|
||||
|
||||
defp ensure_system_actor_user_exists(_admin_role_id) do
|
||||
case repo().one(from(u in "users", where: u.email == ^@system_user_email, select: u.id)) do
|
||||
nil ->
|
||||
execute("""
|
||||
INSERT INTO users (id, email, hashed_password, oidc_id, member_id, role_id)
|
||||
SELECT gen_random_uuid(), '#{@system_user_email}', NULL, NULL, NULL, r.id
|
||||
FROM roles r WHERE r.name = 'Admin' LIMIT 1
|
||||
""")
|
||||
|
||||
IO.puts("✅ Created system actor user (#{@system_user_email})")
|
||||
|
||||
_ ->
|
||||
:ok
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue