towerops/lib/towerops_web/graphql/schema.ex
Graham McIntire f6e9063577
feat: add REST API and GraphQL for on-call schedules and escalation policies
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.
2026-03-11 14:01:15 -05:00

346 lines
10 KiB
Elixir

defmodule ToweropsWeb.GraphQL.Schema do
@moduledoc """
GraphQL schema for the TowerOps API.
Provides a complete GraphQL interface for managing devices, sites, alerts,
agents, organization settings, members, integrations, and activity feeds.
"""
use Absinthe.Schema
import_types(ToweropsWeb.GraphQL.Types.Common)
import_types(ToweropsWeb.GraphQL.Types.Device)
import_types(ToweropsWeb.GraphQL.Types.Site)
import_types(ToweropsWeb.GraphQL.Types.Alert)
import_types(ToweropsWeb.GraphQL.Types.Agent)
import_types(ToweropsWeb.GraphQL.Types.Organization)
import_types(ToweropsWeb.GraphQL.Types.Member)
import_types(ToweropsWeb.GraphQL.Types.Integration)
import_types(ToweropsWeb.GraphQL.Types.Activity)
import_types(ToweropsWeb.GraphQL.Types.Schedule)
import_types(ToweropsWeb.GraphQL.Types.EscalationPolicy)
query do
# Devices
field :devices, list_of(:device) do
arg(:site_id, :id)
arg(:status, :string)
arg(:limit, :integer, default_value: 100)
resolve(&ToweropsWeb.GraphQL.Resolvers.Device.list/3)
end
field :device, :device do
arg(:id, non_null(:id))
resolve(&ToweropsWeb.GraphQL.Resolvers.Device.get/3)
end
# Sites
field :sites, list_of(:site) do
resolve(&ToweropsWeb.GraphQL.Resolvers.Site.list/3)
end
field :site, :site do
arg(:id, non_null(:id))
resolve(&ToweropsWeb.GraphQL.Resolvers.Site.get/3)
end
# Alerts
field :alerts, list_of(:alert) do
arg(:status, :string)
arg(:device_id, :id)
arg(:limit, :integer, default_value: 100)
resolve(&ToweropsWeb.GraphQL.Resolvers.Alert.list/3)
end
field :alert, :alert do
arg(:id, non_null(:id))
resolve(&ToweropsWeb.GraphQL.Resolvers.Alert.get/3)
end
# Agents
field :agents, list_of(:agent) do
resolve(&ToweropsWeb.GraphQL.Resolvers.Agent.list/3)
end
field :agent, :agent do
arg(:id, non_null(:id))
resolve(&ToweropsWeb.GraphQL.Resolvers.Agent.get/3)
end
# Organization
field :organization, :organization do
resolve(&ToweropsWeb.GraphQL.Resolvers.Organization.get/3)
end
# Members
field :members, list_of(:member) do
resolve(&ToweropsWeb.GraphQL.Resolvers.Member.list/3)
end
# Integrations
field :integrations, list_of(:integration) do
resolve(&ToweropsWeb.GraphQL.Resolvers.Integration.list/3)
end
# Activity feed
field :activity, list_of(:activity_item) do
arg(:limit, :integer, default_value: 50)
arg(:type, :string)
resolve(&ToweropsWeb.GraphQL.Resolvers.Activity.list/3)
end
# Device metrics
field :device_metrics, list_of(:metric_point) do
arg(:device_id, non_null(:id))
arg(:sensor_type, :string)
arg(:time_range, :string, default_value: "24h")
resolve(&ToweropsWeb.GraphQL.Resolvers.Device.metrics/3)
end
# Device interfaces
field :device_interfaces, list_of(:interface) do
arg(:device_id, non_null(:id))
resolve(&ToweropsWeb.GraphQL.Resolvers.Device.interfaces/3)
end
# Schedules
field :schedules, list_of(:schedule) do
resolve(&ToweropsWeb.GraphQL.Resolvers.Schedule.list/3)
end
field :schedule, :schedule do
arg(:id, non_null(:id))
resolve(&ToweropsWeb.GraphQL.Resolvers.Schedule.get/3)
end
field :on_call, :on_call_result do
arg(:schedule_id, non_null(:id))
resolve(&ToweropsWeb.GraphQL.Resolvers.Schedule.on_call/3)
end
# Escalation Policies
field :escalation_policies, list_of(:escalation_policy) do
resolve(&ToweropsWeb.GraphQL.Resolvers.EscalationPolicy.list/3)
end
field :escalation_policy, :escalation_policy do
arg(:id, non_null(:id))
resolve(&ToweropsWeb.GraphQL.Resolvers.EscalationPolicy.get/3)
end
end
mutation do
# Device CRUD
field :create_device, :device do
arg(:input, non_null(:device_input))
resolve(&ToweropsWeb.GraphQL.Resolvers.Device.create/3)
end
field :update_device, :device do
arg(:id, non_null(:id))
arg(:input, non_null(:device_input))
resolve(&ToweropsWeb.GraphQL.Resolvers.Device.update/3)
end
field :delete_device, :delete_result do
arg(:id, non_null(:id))
resolve(&ToweropsWeb.GraphQL.Resolvers.Device.delete/3)
end
# Site CRUD
field :create_site, :site do
arg(:input, non_null(:site_input))
resolve(&ToweropsWeb.GraphQL.Resolvers.Site.create/3)
end
field :update_site, :site do
arg(:id, non_null(:id))
arg(:input, non_null(:site_input))
resolve(&ToweropsWeb.GraphQL.Resolvers.Site.update/3)
end
field :delete_site, :delete_result do
arg(:id, non_null(:id))
resolve(&ToweropsWeb.GraphQL.Resolvers.Site.delete/3)
end
# Alert actions
field :acknowledge_alert, :alert do
arg(:id, non_null(:id))
resolve(&ToweropsWeb.GraphQL.Resolvers.Alert.acknowledge/3)
end
field :resolve_alert, :alert do
arg(:id, non_null(:id))
resolve(&ToweropsWeb.GraphQL.Resolvers.Alert.resolve_alert/3)
end
# Agent management
field :create_agent, :agent_with_token do
arg(:name, non_null(:string))
resolve(&ToweropsWeb.GraphQL.Resolvers.Agent.create/3)
end
field :delete_agent, :delete_result do
arg(:id, non_null(:id))
resolve(&ToweropsWeb.GraphQL.Resolvers.Agent.delete/3)
end
# Organization settings
field :update_organization, :organization do
arg(:input, non_null(:organization_input))
resolve(&ToweropsWeb.GraphQL.Resolvers.Organization.update/3)
end
# Member management
field :send_invitation, :invitation do
arg(:email, non_null(:string))
arg(:role, :string, default_value: "technician")
resolve(&ToweropsWeb.GraphQL.Resolvers.Member.invite/3)
end
field :cancel_invitation, :delete_result do
arg(:id, non_null(:id))
resolve(&ToweropsWeb.GraphQL.Resolvers.Member.cancel_invitation/3)
end
field :remove_member, :delete_result do
arg(:id, non_null(:id))
resolve(&ToweropsWeb.GraphQL.Resolvers.Member.remove/3)
end
field :update_member_role, :member do
arg(:id, non_null(:id))
arg(:role, non_null(:string))
resolve(&ToweropsWeb.GraphQL.Resolvers.Member.update_role/3)
end
# Integrations
field :create_integration, :integration do
arg(:input, non_null(:integration_input))
resolve(&ToweropsWeb.GraphQL.Resolvers.Integration.create/3)
end
field :update_integration, :integration do
arg(:id, non_null(:id))
arg(:input, non_null(:integration_input))
resolve(&ToweropsWeb.GraphQL.Resolvers.Integration.update/3)
end
field :delete_integration, :delete_result do
arg(:id, non_null(:id))
resolve(&ToweropsWeb.GraphQL.Resolvers.Integration.delete/3)
end
field :test_integration, :test_result do
arg(:id, non_null(:id))
resolve(&ToweropsWeb.GraphQL.Resolvers.Integration.test_connection/3)
end
# Schedule CRUD
field :create_schedule, :schedule do
arg(:input, non_null(:schedule_input))
resolve(&ToweropsWeb.GraphQL.Resolvers.Schedule.create/3)
end
field :update_schedule, :schedule do
arg(:id, non_null(:id))
arg(:input, non_null(:schedule_input))
resolve(&ToweropsWeb.GraphQL.Resolvers.Schedule.update/3)
end
field :delete_schedule, :delete_result do
arg(:id, non_null(:id))
resolve(&ToweropsWeb.GraphQL.Resolvers.Schedule.delete/3)
end
# Layer CRUD
field :create_layer, :layer do
arg(:schedule_id, non_null(:id))
arg(:input, non_null(:layer_input))
resolve(&ToweropsWeb.GraphQL.Resolvers.Schedule.create_layer/3)
end
field :update_layer, :layer do
arg(:id, non_null(:id))
arg(:input, non_null(:layer_input))
resolve(&ToweropsWeb.GraphQL.Resolvers.Schedule.update_layer/3)
end
field :delete_layer, :delete_result do
arg(:id, non_null(:id))
resolve(&ToweropsWeb.GraphQL.Resolvers.Schedule.delete_layer/3)
end
# Layer member management
field :add_layer_member, :layer_member do
arg(:layer_id, non_null(:id))
arg(:user_id, non_null(:id))
arg(:position, non_null(:integer))
resolve(&ToweropsWeb.GraphQL.Resolvers.Schedule.add_member/3)
end
field :remove_layer_member, :delete_result do
arg(:id, non_null(:id))
resolve(&ToweropsWeb.GraphQL.Resolvers.Schedule.remove_member/3)
end
# Override management
field :create_override, :override do
arg(:schedule_id, non_null(:id))
arg(:input, non_null(:override_input))
resolve(&ToweropsWeb.GraphQL.Resolvers.Schedule.create_override/3)
end
field :delete_override, :delete_result do
arg(:id, non_null(:id))
resolve(&ToweropsWeb.GraphQL.Resolvers.Schedule.delete_override/3)
end
# Escalation Policy CRUD
field :create_escalation_policy, :escalation_policy do
arg(:input, non_null(:escalation_policy_input))
resolve(&ToweropsWeb.GraphQL.Resolvers.EscalationPolicy.create/3)
end
field :update_escalation_policy, :escalation_policy do
arg(:id, non_null(:id))
arg(:input, non_null(:escalation_policy_input))
resolve(&ToweropsWeb.GraphQL.Resolvers.EscalationPolicy.update/3)
end
field :delete_escalation_policy, :delete_result do
arg(:id, non_null(:id))
resolve(&ToweropsWeb.GraphQL.Resolvers.EscalationPolicy.delete/3)
end
# Escalation Rule CRUD
field :create_escalation_rule, :escalation_rule do
arg(:escalation_policy_id, non_null(:id))
arg(:input, non_null(:escalation_rule_input))
resolve(&ToweropsWeb.GraphQL.Resolvers.EscalationPolicy.create_rule/3)
end
field :update_escalation_rule, :escalation_rule do
arg(:id, non_null(:id))
arg(:input, non_null(:escalation_rule_input))
resolve(&ToweropsWeb.GraphQL.Resolvers.EscalationPolicy.update_rule/3)
end
field :delete_escalation_rule, :delete_result do
arg(:id, non_null(:id))
resolve(&ToweropsWeb.GraphQL.Resolvers.EscalationPolicy.delete_rule/3)
end
# Escalation Target management
field :create_escalation_target, :escalation_target do
arg(:escalation_rule_id, non_null(:id))
arg(:input, non_null(:escalation_target_input))
resolve(&ToweropsWeb.GraphQL.Resolvers.EscalationPolicy.create_target/3)
end
field :delete_escalation_target, :delete_result do
arg(:id, non_null(:id))
resolve(&ToweropsWeb.GraphQL.Resolvers.EscalationPolicy.delete_target/3)
end
end
end