Skip to content

Instantly share code, notes, and snippets.

@sjchmiela
Created October 8, 2016 16:39
Show Gist options
  • Save sjchmiela/b9df9a178f41d7bc9c28f03d42bbb4ae to your computer and use it in GitHub Desktop.
Save sjchmiela/b9df9a178f41d7bc9c28f03d42bbb4ae to your computer and use it in GitHub Desktop.
defmodule Sheetly.Schema.Types do
@moduledoc """
Types used by GraphQL endpoint
"""
import Canada, only: [can?: 2]
use Absinthe.Schema.Notation
use Absinthe.Relay.Schema.Notation
alias Ecto.{Date, DateTime}
alias Sheetly.{
ContractResolver,
ProjectResolver,
ClientResolver,
ActorResolver,
UserResolver,
Contract,
Project,
Viewer,
Client,
User,
}
defmacro can({action, _, nil}) do
quote do
fn _, %{source: src, context: ctx} ->
{:ok, can?(ctx, unquote(action)(src))}
end
end
end
defmacro can(ability) do
quote do: fn _, %{source: src} -> {:ok, can?(src, unquote ability)} end
end
scalar :date do
description "Date (in ISO 8601 format)"
parse &Date.cast/1
serialize &Date.to_string/1
end
scalar :datetime do
description "Time (in ISOz format)"
parse &DateTime.cast(&1)
serialize &DateTime.to_string(&1)
end
scalar :decimal do
description "Decimal value"
parse &Decimal.new/1
serialize &Decimal.to_string/1
end
node interface do
resolve_type fn
%Contract{}, _ -> :contract
%Project{}, _ -> :project
%Client{}, _ -> :client
%Viewer{}, _ -> :viewer
%User{}, _ -> :user
_, _ -> nil
end
end
node object :client do
field :id, :id
field :name, :string
field :inserted_at, :datetime
field :users, list_of(:user), do: resolve &UserResolver.list/2
field :projects, list_of(:project), do: resolve &ProjectResolver.list/2
field :can_edit, :boolean, do: resolve can(edit)
field :can_destroy, :boolean, do: resolve can(destroy)
end
connection node_type: :client
node object :project do
field :id, :id
field :name, :string
field :inserted_at, :datetime
field :client, :client, do: resolve &ClientResolver.find/2
field :users, list_of(:user), do: resolve &UserResolver.list/2
field :can_edit, :boolean, do: resolve can(edit)
field :can_destroy, :boolean, do: resolve can(destroy)
end
connection node_type: :project
node object :user do
field :id, :id
field :first_name, :string
field :last_name, :string
field :email, :string
field :inserted_at, :datetime
field :is_accountant, :boolean, do: resolve &UserResolver.accountant?/2
field :is_admin, :boolean, do: resolve &UserResolver.admin?/2
field :client, :client, do: resolve &ClientResolver.find/2
field :is_employee, :boolean, do: resolve &UserResolver.employee?/2
field :projects, list_of(:project), do: resolve &ProjectResolver.list/2
field :contracts, list_of(:contract), do: resolve &ContractResolver.list/2
field :can_create_clients, :boolean, do: resolve can(create(Client))
field :can_list_clients, :boolean, do: resolve can(list(Client))
field :can_list_users, :boolean, do: resolve can(list(User))
end
connection node_type: :user
node object :contract do
field :id, :id
field :from, :date
field :to, :date
field :hourly_rate, :decimal
field :user, :user, do: resolve &UserResolver.find/2
field :can_edit, :boolean, do: resolve can(edit)
field :can_destroy, :boolean, do: resolve can(destroy)
end
node object :viewer do
field :id, :id
field :actor, :user, do: resolve &ActorResolver.find/2
connection field :clients, node_type: :client do
arg :query, :string
arg :order_by, :string
arg :order_direction, :string
resolve &ClientResolver.list/2
end
connection field :users, node_type: :user do
arg :query, :string
arg :order_by, :string
arg :order_direction, :string
resolve &UserResolver.list/2
end
connection field :projects, node_type: :project do
arg :query, :string
arg :order_by, :string
arg :order_direction, :string
resolve &ProjectResolver.list/2
end
field :expiring_contracts, list_of(:contract) do
resolve &ContractResolver.list_expiring/2
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment