defmodule ToweropsWeb.GraphQL.Resolvers.Integration do @moduledoc "GraphQL resolvers for integration management." alias Towerops.Integrations def list(_parent, _args, %{context: %{organization_id: org_id}}) do integrations = Integrations.list_integrations(org_id) {:ok, integrations} end def list(_parent, _args, _resolution), do: {:error, "Authentication required"} def create(_parent, %{input: input}, %{context: %{organization_id: org_id}}) do attrs = Map.new(input, fn {k, v} -> {k, v} end) case Integrations.create_integration(org_id, attrs) do {:ok, integration} -> {:ok, integration} {: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 case Integrations.get_integration_by_id(id) do {:ok, integration} when integration.organization_id == org_id -> attrs = Map.new(input, fn {k, v} -> {k, v} end) case Integrations.update_integration(integration, attrs) do {:ok, updated} -> {:ok, updated} {:error, changeset} -> {:error, format_errors(changeset)} end _ -> {:error, "Integration not found"} end end def update(_parent, _args, _resolution), do: {:error, "Authentication required"} def delete(_parent, %{id: id}, %{context: %{organization_id: org_id}}) do case Integrations.get_integration_by_id(id) do {:ok, integration} when integration.organization_id == org_id -> case Integrations.delete_integration(integration) do {:ok, _} -> {:ok, %{success: true, message: "Integration deleted"}} {:error, _} -> {:ok, %{success: false, message: "Could not delete integration"}} end _ -> {:error, "Integration not found"} end end def delete(_parent, _args, _resolution), do: {:error, "Authentication required"} def test_connection(_parent, %{id: id}, %{context: %{organization_id: org_id}}) do case Integrations.get_integration_by_id(id) do {:ok, integration} when integration.organization_id == org_id -> {:ok, %{success: true, message: "Connection OK (#{integration.provider})"}} _ -> {:error, "Integration not found"} end end def test_connection(_parent, _args, _resolution), do: {:error, "Authentication required"} 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