defmodule ToweropsWeb.GraphQL.Resolvers.Site do @moduledoc "GraphQL resolvers for site queries and mutations." alias Towerops.Repo alias Towerops.Sites alias Towerops.Sites.Site def list(_parent, _args, %{context: %{organization_id: org_id}}) do sites = Sites.list_organization_sites(org_id) {:ok, sites} end def list(_parent, _args, _resolution), do: {:error, "Authentication required"} def get(_parent, %{id: id}, %{context: %{organization_id: org_id}}) do fetch_org_site(id, org_id) end def get(_parent, _args, _resolution), do: {:error, "Authentication required"} def create(_parent, %{input: input}, %{context: %{organization_id: org_id}}) do attrs = input |> Map.new(fn {k, v} -> {to_string(k), v} end) |> Map.put("organization_id", org_id) case Sites.create_site(attrs) do {:ok, site} -> {:ok, site} {:error, changeset} -> {:error, format_errors(changeset)} end end def create(_parent, _args, _resolution), do: {:error, "Authentication required"} def update(_parent, %{id: id, input: input}, %{context: %{organization_id: org_id}}) do with {:ok, site} <- fetch_org_site(id, org_id) do attrs = Map.new(input, fn {k, v} -> {to_string(k), v} end) case Sites.update_site(site, attrs) do {:ok, updated} -> {:ok, updated} {:error, changeset} -> {:error, format_errors(changeset)} end end end def update(_parent, _args, _resolution), do: {:error, "Authentication required"} def delete(_parent, %{id: id}, %{context: %{organization_id: org_id}}) do with {:ok, site} <- fetch_org_site(id, org_id) do case Sites.delete_site(site) do {:ok, _} -> {:ok, %{success: true, message: "Site deleted"}} {:error, _} -> {:ok, %{success: false, message: "Could not delete site"}} end end end def delete(_parent, _args, _resolution), do: {:error, "Authentication required"} defp fetch_org_site(id, org_id) do case Repo.get(Site, id) do nil -> {:error, "Site not found"} %Site{organization_id: ^org_id} = site -> {:ok, site} %Site{} -> {:error, "Site not found"} end end defp format_errors(changeset) do changeset |> Ecto.Changeset.traverse_errors(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_join("; ", fn {field, messages} -> "#{field}: #{Enum.join(messages, ", ")}" end) end end