defmodule GlificWeb.Schema do
@moduledoc """
This is the container for the top level Absinthe GraphQL schema which encapsulates the entire Glific Public API.
This file is primarily a container and pulls in the relevant information for data type specific files.
"""
use Absinthe.Schema
import GlificWeb.Gettext
alias Glific.Repo
alias GlificWeb.Schema.Middleware
import_types(Absinthe.Type.Custom)
# Important: Needed to use the `:upload` type
import_types(Absinthe.Plug.Types)
import_types(__MODULE__.OrganizationTypes)
import_types(__MODULE__.ProfileTypes)
import_types(__MODULE__.ContactTypes)
import_types(__MODULE__.ContactTagTypes)
import_types(__MODULE__.EnumTypes)
import_types(__MODULE__.GenericTypes)
import_types(__MODULE__.LanguageTypes)
import_types(__MODULE__.MessageTypes)
import_types(__MODULE__.MessageMediaTypes)
import_types(__MODULE__.MessageTagTypes)
import_types(__MODULE__.CredentialTypes)
import_types(__MODULE__.ProviderTypes)
import_types(__MODULE__.SessionTemplateTypes)
import_types(__MODULE__.TemplateTagTypes)
import_types(__MODULE__.TagTypes)
import_types(__MODULE__.UserTypes)
import_types(__MODULE__.GroupTypes)
import_types(__MODULE__.ContactGroupTypes)
import_types(__MODULE__.UserGroupTypes)
import_types(__MODULE__.SearchTypes)
import_types(__MODULE__.FlowTypes)
import_types(__MODULE__.TriggerTypes)
import_types(__MODULE__.WebhookLogTypes)
import_types(__MODULE__.NotificationTypes)
import_types(__MODULE__.LocationTypes)
import_types(__MODULE__.BillingTypes)
import_types(__MODULE__.MediaTypes)
import_types(__MODULE__.ConsultingHourTypes)
import_types(__MODULE__.ContactsFieldTypes)
import_types(__MODULE__.ExtensionTypes)
import_types(__MODULE__.InteractiveTemplateTypes)
import_types(__MODULE__.FlowLabelTypes)
import_types(__MODULE__.RoleTypes)
import_types(__MODULE__.SheetTypes)
query do
import_fields(:profile_queries)
import_fields(:contact_queries)
import_fields(:language_queries)
import_fields(:message_queries)
import_fields(:message_media_queries)
import_fields(:organization_queries)
import_fields(:credential_queries)
import_fields(:provider_queries)
import_fields(:session_template_queries)
import_fields(:tag_queries)
import_fields(:user_queries)
import_fields(:group_queries)
import_fields(:search_queries)
import_fields(:flow_queries)
import_fields(:trigger_queries)
import_fields(:webhook_log_queries)
import_fields(:notification_queries)
import_fields(:location_queries)
import_fields(:billing_queries)
import_fields(:consulting_hours_queries)
import_fields(:contacts_field_queries)
import_fields(:extensions_queries)
import_fields(:interactive_template_queries)
import_fields(:flow_label_queries)
import_fields(:access_role_queries)
import_fields(:contact_group_queries)
import_fields(:sheet_queries)
end
mutation do
import_fields(:profile_mutations)
import_fields(:contact_mutations)
import_fields(:contact_tag_mutations)
import_fields(:language_mutations)
import_fields(:message_mutations)
import_fields(:message_media_mutations)
import_fields(:message_tag_mutations)
import_fields(:organization_mutations)
import_fields(:credential_mutations)
import_fields(:provider_mutations)
import_fields(:session_template_mutations)
import_fields(:template_tag_mutations)
import_fields(:tag_mutations)
import_fields(:user_mutations)
import_fields(:group_mutations)
import_fields(:contact_group_mutations)
import_fields(:user_group_mutations)
import_fields(:search_mutations)
import_fields(:flow_mutations)
import_fields(:trigger_mutations)
import_fields(:billing_mutations)
import_fields(:media_mutations)
import_fields(:consulting_hours_mutations)
import_fields(:notification_mutations)
import_fields(:contacts_field_mutations)
import_fields(:extensions_mutations)
import_fields(:interactive_template_mutations)
import_fields(:access_role_mutations)
import_fields(:sheet_mutations)
end
subscription do
import_fields(:message_subscriptions)
import_fields(:message_tag_subscriptions)
import_fields(:organization_subscriptions)
end
@doc """
Used to apply middleware on all or a group of fields based on pattern matching.
It is passed the existing middleware for a field, the field itself, and the object that the field is a part of.
"""
@spec middleware(
[Absinthe.Middleware.spec(), ...],
Absinthe.Type.Field.t(),
Absinthe.Type.Object.t()
) :: [Absinthe.Middleware.spec(), ...]
def middleware(middleware, _field, %{identifier: :mutation}),
do: [Middleware.AddOrganization | middleware] ++ [Middleware.ChangesetErrors]
def middleware(middleware, _field, %{identifier: :query}),
do: [Middleware.AddOrganization | middleware] ++ [Middleware.QueryErrors]
def middleware(middleware, _field, _object),
do: middleware
@spec repo_opts(map()) :: Keyword.t()
defp repo_opts(%{current_user: user}) when user != nil,
do: [organization_id: user.organization_id]
defp repo_opts(_params), do: []
@doc """
Used to set some values in the context that we may need in order to run.
We store the organization id and the current user in the context once the user has been
authenticated
"""
@spec context(map()) :: map()
def context(ctx) do
loader =
Dataloader.new()
|> Dataloader.add_source(
Repo,
Dataloader.Ecto.new(Repo, repo_opts: repo_opts(ctx))
)
Map.put(ctx, :loader, loader)
end
@doc """
Used to define the list of plugins to run before and after resolution.
"""
@spec plugins() :: [Absinthe.Plugin.t()]
def plugins do
[Absinthe.Middleware.Dataloader | Absinthe.Plugin.defaults()]
end
@doc """
Validation function for all subscriptions received by the system
"""
@spec config_fun(map(), map()) :: {:ok, Keyword.t()} | {:error, String.t()}
def config_fun(args, %{context: %{current_user: user}}) do
organization_id = args.organization_id
if organization_id == Integer.to_string(user.organization_id) do
{:ok, [topic: organization_id]}
else
{:error, dgettext("errors", "Auth Credentials mismatch")}
end
end
end