88 lines
3 KiB
Elixir
88 lines
3 KiB
Elixir
defmodule ToweropsWeb.GraphQL.Resolvers.Member do
|
|
@moduledoc "GraphQL resolvers for member and invitation management."
|
|
|
|
alias Towerops.Organizations
|
|
alias Towerops.Organizations.Invitation
|
|
alias Towerops.Repo
|
|
|
|
def list(_parent, _args, %{context: %{organization_id: org_id}}) do
|
|
members = Organizations.list_organization_members(org_id)
|
|
{:ok, members}
|
|
end
|
|
|
|
def list(_parent, _args, _resolution), do: {:error, "Authentication required"}
|
|
|
|
def invite(_parent, %{email: email} = args, %{context: %{organization_id: org_id, user: user}}) do
|
|
role = Map.get(args, :role, "member")
|
|
|
|
case Organizations.create_invitation(%{
|
|
email: email,
|
|
role: role,
|
|
organization_id: org_id,
|
|
invited_by_id: user.id
|
|
}) do
|
|
{:ok, invitation} -> {:ok, invitation}
|
|
{:error, changeset} -> {:error, format_errors(changeset)}
|
|
end
|
|
end
|
|
|
|
def invite(_parent, _args, _resolution), do: {:error, "Authentication required"}
|
|
|
|
def cancel_invitation(_parent, %{id: id}, %{context: %{organization_id: org_id}}) do
|
|
case Repo.get(Invitation, id) do
|
|
nil ->
|
|
{:error, "Invitation not found"}
|
|
|
|
invitation ->
|
|
if invitation.organization_id == org_id do
|
|
case Repo.delete(invitation) do
|
|
{:ok, _} -> {:ok, %{success: true, message: "Invitation cancelled"}}
|
|
{:error, _} -> {:ok, %{success: false, message: "Could not cancel invitation"}}
|
|
end
|
|
else
|
|
{:error, "Invitation not found"}
|
|
end
|
|
end
|
|
end
|
|
|
|
def cancel_invitation(_parent, _args, _resolution), do: {:error, "Authentication required"}
|
|
|
|
def remove(_parent, %{id: user_id}, %{context: %{organization_id: org_id}}) do
|
|
case Organizations.remove_member(org_id, user_id) do
|
|
{:ok, _} -> {:ok, %{success: true, message: "Member removed"}}
|
|
{:error, :cannot_remove_owner} -> {:error, "Cannot remove owner"}
|
|
{:error, :not_found} -> {:error, "Member not found"}
|
|
end
|
|
end
|
|
|
|
def remove(_parent, _args, _resolution), do: {:error, "Authentication required"}
|
|
|
|
def update_role(_parent, %{id: user_id, role: role}, %{context: %{organization_id: org_id}}) do
|
|
case Organizations.update_member_role(org_id, user_id, role) do
|
|
{:ok, membership} ->
|
|
membership = Repo.preload(membership, :user)
|
|
{:ok, membership}
|
|
|
|
{:error, :cannot_change_owner_role} ->
|
|
{:error, "Cannot change owner role"}
|
|
|
|
{:error, :not_found} ->
|
|
{:error, "Member not found"}
|
|
|
|
{:error, changeset} ->
|
|
{:error, format_errors(changeset)}
|
|
end
|
|
end
|
|
|
|
def update_role(_parent, _args, _resolution), do: {:error, "Authentication required"}
|
|
|
|
defp format_errors(changeset) do
|
|
Ecto.Changeset.traverse_errors(changeset, fn {msg, opts} ->
|
|
Regex.replace(~r"%{(\w+)}", msg, fn _, key ->
|
|
opts |> Keyword.get(String.to_existing_atom(key), key) |> to_string()
|
|
end)
|
|
end)
|
|
|> Enum.map(fn {field, messages} -> "#{field}: #{Enum.join(messages, ", ")}" end)
|
|
|> Enum.join("; ")
|
|
end
|
|
end
|