towerops/lib/towerops_web/graphql_socket.ex
Graham McIntire 72f81c572d
add real-time GraphQL API with time-series queries and subscriptions
- add absinthe_phoenix for WebSocket subscription support
- create GraphQL WebSocket socket with API token auth at /socket/graphql
- add time-series queries: deviceSensors, sensorReadings, interfaceTraffic, checkResults
- add subscriptions: deviceStatusChanged, alertEvent, sensorReadingsUpdated
- wire subscription triggers into agent_channel and alerts contexts
- add org-scoped access control for sensors/interfaces via join queries
- add 17 tests covering queries, org isolation, empty data edge cases, and auth
- update GraphQL API docs page with time-series and subscription sections
2026-03-12 10:24:39 -05:00

32 lines
889 B
Elixir

defmodule ToweropsWeb.GraphQLSocket do
@moduledoc """
WebSocket endpoint for GraphQL subscriptions.
Authenticates via API token passed as a connection parameter.
"""
use Phoenix.Socket
use Absinthe.Phoenix.Socket, schema: ToweropsWeb.GraphQL.Schema
@impl true
def connect(%{"token" => token}, socket, _connect_info) when is_binary(token) do
case Towerops.ApiTokens.verify_token(token) do
{:ok, org_id, user} ->
socket =
socket
|> assign(:organization_id, org_id)
|> assign(:user, user)
|> Absinthe.Phoenix.Socket.put_options(context: %{organization_id: org_id, user: user})
{:ok, socket}
{:error, :invalid_token} ->
:error
end
end
def connect(_params, _socket, _connect_info), do: :error
@impl true
def id(socket), do: "graphql_socket:#{socket.assigns.organization_id}"
end