REST API v1 endpoints for schedules (14 endpoints) and escalation policies (10 endpoints) with full CRUD for nested resources (layers, members, overrides, rules, targets). GraphQL types, resolvers, and schema mutations for both resource trees.
168 lines
5.7 KiB
Elixir
168 lines
5.7 KiB
Elixir
defmodule ToweropsWeb.GraphQL.Resolvers.EscalationPolicy do
|
|
@moduledoc "GraphQL resolvers for escalation policy queries and mutations."
|
|
|
|
alias Towerops.OnCall
|
|
alias Towerops.OnCall.EscalationPolicy
|
|
alias Towerops.OnCall.EscalationRule
|
|
alias Towerops.OnCall.EscalationTarget
|
|
alias Towerops.Repo
|
|
alias ToweropsWeb.GraphQL.Resolvers.Helpers
|
|
alias ToweropsWeb.ScopedResource
|
|
|
|
# --- Queries ---
|
|
|
|
def list(_parent, _args, %{context: %{organization_id: org_id}}) do
|
|
{:ok, OnCall.list_escalation_policies(org_id)}
|
|
end
|
|
|
|
def list(_parent, _args, _resolution), do: Helpers.authentication_error()
|
|
|
|
def get(_parent, %{id: id}, %{context: %{organization_id: org_id}}) do
|
|
case ScopedResource.fetch_preload(EscalationPolicy, id, org_id, rules: :targets) do
|
|
{:ok, policy} -> {:ok, policy}
|
|
{:error, _} -> {:error, "Escalation policy not found"}
|
|
end
|
|
end
|
|
|
|
def get(_parent, _args, _resolution), do: Helpers.authentication_error()
|
|
|
|
# --- Mutations ---
|
|
|
|
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 OnCall.create_escalation_policy(attrs) do
|
|
{:ok, policy} -> {:ok, policy}
|
|
{:error, changeset} -> {:error, Helpers.format_changeset_errors(changeset)}
|
|
end
|
|
end
|
|
|
|
def create(_parent, _args, _resolution), do: Helpers.authentication_error()
|
|
|
|
def update(_parent, %{id: id, input: input}, %{context: %{organization_id: org_id}}) do
|
|
with {:ok, policy} <- fetch_org_policy(id, org_id) do
|
|
attrs = Map.new(input, fn {k, v} -> {to_string(k), v} end)
|
|
|
|
case OnCall.update_escalation_policy(policy, attrs) do
|
|
{:ok, updated} -> {:ok, updated}
|
|
{:error, changeset} -> {:error, Helpers.format_changeset_errors(changeset)}
|
|
end
|
|
end
|
|
end
|
|
|
|
def update(_parent, _args, _resolution), do: Helpers.authentication_error()
|
|
|
|
def delete(_parent, %{id: id}, %{context: %{organization_id: org_id}}) do
|
|
with {:ok, policy} <- fetch_org_policy(id, org_id) do
|
|
case OnCall.delete_escalation_policy(policy) do
|
|
{:ok, _} -> {:ok, %{success: true, message: "Escalation policy deleted"}}
|
|
{:error, _} -> {:ok, %{success: false, message: "Could not delete escalation policy"}}
|
|
end
|
|
end
|
|
end
|
|
|
|
def delete(_parent, _args, _resolution), do: Helpers.authentication_error()
|
|
|
|
# --- Rule mutations ---
|
|
|
|
def create_rule(_parent, %{escalation_policy_id: policy_id, input: input}, %{context: %{organization_id: org_id}}) do
|
|
with {:ok, _policy} <- fetch_org_policy(policy_id, org_id) do
|
|
attrs =
|
|
input
|
|
|> Map.new(fn {k, v} -> {to_string(k), v} end)
|
|
|> Map.put("escalation_policy_id", policy_id)
|
|
|
|
case OnCall.create_escalation_rule(attrs) do
|
|
{:ok, rule} -> {:ok, rule}
|
|
{:error, changeset} -> {:error, Helpers.format_changeset_errors(changeset)}
|
|
end
|
|
end
|
|
end
|
|
|
|
def create_rule(_parent, _args, _resolution), do: Helpers.authentication_error()
|
|
|
|
def update_rule(_parent, %{id: id, input: input}, %{context: %{organization_id: org_id}}) do
|
|
with {:ok, rule} <- fetch_rule_by_org(id, org_id) do
|
|
attrs = Map.new(input, fn {k, v} -> {to_string(k), v} end)
|
|
|
|
case OnCall.update_escalation_rule(rule, attrs) do
|
|
{:ok, updated} -> {:ok, updated}
|
|
{:error, changeset} -> {:error, Helpers.format_changeset_errors(changeset)}
|
|
end
|
|
end
|
|
end
|
|
|
|
def update_rule(_parent, _args, _resolution), do: Helpers.authentication_error()
|
|
|
|
def delete_rule(_parent, %{id: id}, %{context: %{organization_id: org_id}}) do
|
|
with {:ok, rule} <- fetch_rule_by_org(id, org_id) do
|
|
case OnCall.delete_escalation_rule(rule) do
|
|
{:ok, _} -> {:ok, %{success: true, message: "Rule deleted"}}
|
|
{:error, _} -> {:ok, %{success: false, message: "Could not delete rule"}}
|
|
end
|
|
end
|
|
end
|
|
|
|
def delete_rule(_parent, _args, _resolution), do: Helpers.authentication_error()
|
|
|
|
# --- Target mutations ---
|
|
|
|
def create_target(_parent, %{escalation_rule_id: rule_id, input: input}, %{context: %{organization_id: org_id}}) do
|
|
with {:ok, _rule} <- fetch_rule_by_org(rule_id, org_id) do
|
|
attrs =
|
|
input
|
|
|> Map.new(fn {k, v} -> {to_string(k), v} end)
|
|
|> Map.put("escalation_rule_id", rule_id)
|
|
|
|
case OnCall.create_escalation_target(attrs) do
|
|
{:ok, target} -> {:ok, target}
|
|
{:error, changeset} -> {:error, Helpers.format_changeset_errors(changeset)}
|
|
end
|
|
end
|
|
end
|
|
|
|
def create_target(_parent, _args, _resolution), do: Helpers.authentication_error()
|
|
|
|
def delete_target(_parent, %{id: id}, %{context: %{organization_id: _org_id}}) do
|
|
case Repo.get(EscalationTarget, id) do
|
|
nil ->
|
|
{:error, "Target not found"}
|
|
|
|
target ->
|
|
case OnCall.delete_escalation_target(target) do
|
|
{:ok, _} -> {:ok, %{success: true, message: "Target deleted"}}
|
|
{:error, _} -> {:ok, %{success: false, message: "Could not delete target"}}
|
|
end
|
|
end
|
|
end
|
|
|
|
def delete_target(_parent, _args, _resolution), do: Helpers.authentication_error()
|
|
|
|
# --- Private helpers ---
|
|
|
|
defp fetch_org_policy(id, org_id) do
|
|
case ScopedResource.fetch(EscalationPolicy, id, org_id) do
|
|
{:ok, policy} -> {:ok, policy}
|
|
{:error, _} -> {:error, "Escalation policy not found"}
|
|
end
|
|
end
|
|
|
|
defp fetch_rule_by_org(rule_id, org_id) do
|
|
case Repo.get(EscalationRule, rule_id) do
|
|
nil ->
|
|
{:error, "Rule not found"}
|
|
|
|
rule ->
|
|
rule = Repo.preload(rule, :escalation_policy)
|
|
|
|
if rule.escalation_policy.organization_id == org_id do
|
|
{:ok, rule}
|
|
else
|
|
{:error, "Rule not found"}
|
|
end
|
|
end
|
|
end
|
|
end
|