From b0bc8dfa5ddab2531a4012264134239628e012bc Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Mon, 14 Jan 2019 17:13:17 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=82=EF=B8=8F=20=20Split=20GraphQL=20schem?= =?UTF-8?q?a=20into=20several=20files?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Citharel --- lib/mobilizon_web/schema.ex | 296 +----------------- lib/mobilizon_web/schema/actor.ex | 62 ++++ lib/mobilizon_web/schema/actors/follower.ex | 15 + lib/mobilizon_web/schema/actors/group.ex | 68 ++++ lib/mobilizon_web/schema/actors/member.ex | 13 + lib/mobilizon_web/schema/actors/person.ex | 44 +++ lib/mobilizon_web/schema/address.ex | 36 +++ lib/mobilizon_web/schema/comment.ex | 14 + lib/mobilizon_web/schema/custom/point.ex | 38 +++ lib/mobilizon_web/schema/event.ex | 49 +++ lib/mobilizon_web/schema/events/category.ex | 11 + .../schema/events/participant.ex | 14 + lib/mobilizon_web/schema/user.ex | 33 ++ 13 files changed, 403 insertions(+), 290 deletions(-) create mode 100644 lib/mobilizon_web/schema/actor.ex create mode 100644 lib/mobilizon_web/schema/actors/follower.ex create mode 100644 lib/mobilizon_web/schema/actors/group.ex create mode 100644 lib/mobilizon_web/schema/actors/member.ex create mode 100644 lib/mobilizon_web/schema/actors/person.ex create mode 100644 lib/mobilizon_web/schema/address.ex create mode 100644 lib/mobilizon_web/schema/comment.ex create mode 100644 lib/mobilizon_web/schema/custom/point.ex create mode 100644 lib/mobilizon_web/schema/event.ex create mode 100644 lib/mobilizon_web/schema/events/category.ex create mode 100644 lib/mobilizon_web/schema/events/participant.ex create mode 100644 lib/mobilizon_web/schema/user.ex diff --git a/lib/mobilizon_web/schema.ex b/lib/mobilizon_web/schema.ex index 02e7543a8..f9d2021ca 100644 --- a/lib/mobilizon_web/schema.ex +++ b/lib/mobilizon_web/schema.ex @@ -10,285 +10,23 @@ defmodule MobilizonWeb.Schema do alias Mobilizon.Events.{Event, Comment, Participant} import_types(MobilizonWeb.Schema.Custom.UUID) + import_types(MobilizonWeb.Schema.Custom.Point) import_types(Absinthe.Type.Custom) import_types(Absinthe.Plug.Types) + import_types(MobilizonWeb.Schema.ActorInterface) + import_types(MobilizonWeb.Schema.Actors.PersonType) + import_types(MobilizonWeb.Schema.Actors.GroupType) + import_types(MobilizonWeb.Schema.CommentType) + alias MobilizonWeb.Resolvers - @desc """ - Represents a person identity - """ - object :person do - interfaces([:actor]) - field(:user, :user, description: "The user this actor is associated to") - - field(:member_of, list_of(:member), description: "The list of groups this person is member of") - - field(:url, :string, description: "The ActivityPub actor's URL") - field(:type, :actor_type, description: "The type of Actor (Person, Group,…)") - field(:name, :string, description: "The actor's displayed name") - field(:domain, :string, description: "The actor's domain if (null if it's this instance)") - field(:local, :boolean, description: "If the actor is from this instance") - field(:summary, :string, description: "The actor's summary") - field(:preferred_username, :string, description: "The actor's preferred username") - field(:keys, :string, description: "The actors RSA Keys") - - field(:manually_approves_followers, :boolean, - description: "Whether the actors manually approves followers" - ) - - field(:suspended, :boolean, description: "If the actor is suspended") - field(:avatar_url, :string, description: "The actor's avatar url") - field(:banner_url, :string, description: "The actor's banner url") - - # These one should have a privacy setting - field(:following, list_of(:follower), description: "List of followings") - field(:followers, list_of(:follower), description: "List of followers") - field(:followersCount, :integer, description: "Number of followers for this actor") - field(:followingCount, :integer, description: "Number of actors following this actor") - - # This one should have a privacy setting - field(:organized_events, list_of(:event), - resolve: dataloader(Events), - description: "A list of the events this actor has organized" - ) - end - - @desc """ - Represents a group of actors - """ - object :group do - interfaces([:actor]) - - field(:url, :string, description: "The ActivityPub actor's URL") - field(:type, :actor_type, description: "The type of Actor (Person, Group,…)") - field(:name, :string, description: "The actor's displayed name") - field(:domain, :string, description: "The actor's domain if (null if it's this instance)") - field(:local, :boolean, description: "If the actor is from this instance") - field(:summary, :string, description: "The actor's summary") - field(:preferred_username, :string, description: "The actor's preferred username") - field(:keys, :string, description: "The actors RSA Keys") - - field(:manually_approves_followers, :boolean, - description: "Whether the actors manually approves followers" - ) - - field(:suspended, :boolean, description: "If the actor is suspended") - field(:avatar_url, :string, description: "The actor's avatar url") - field(:banner_url, :string, description: "The actor's banner url") - - # These one should have a privacy setting - field(:following, list_of(:follower), description: "List of followings") - field(:followers, list_of(:follower), description: "List of followers") - field(:followersCount, :integer, description: "Number of followers for this actor") - field(:followingCount, :integer, description: "Number of actors following this actor") - - # This one should have a privacy setting - field(:organized_events, list_of(:event), - resolve: dataloader(Events), - description: "A list of the events this actor has organized" - ) - - field(:types, :group_type, description: "The type of group : Group, Community,…") - - field(:openness, :openness, - description: "Whether the group is opened to all or has restricted access" - ) - - field(:members, non_null(list_of(:member)), description: "List of group members") - end - - @desc """ - Describes how an actor is opened to follows - """ - enum :openness do - value(:invite_only, description: "The actor can only be followed by invitation") - - value(:moderated, description: "The actor needs to accept the following before it's effective") - - value(:open, description: "The actor is open to followings") - end - - @desc """ - The types of Group that exist - """ - enum :group_type do - value(:group, description: "A private group of persons") - value(:community, description: "A public group of many actors") - end - - @desc "An ActivityPub actor" - interface :actor do - field(:url, :string, description: "The ActivityPub actor's URL") - field(:type, :actor_type, description: "The type of Actor (Person, Group,…)") - field(:name, :string, description: "The actor's displayed name") - field(:domain, :string, description: "The actor's domain if (null if it's this instance)") - field(:local, :boolean, description: "If the actor is from this instance") - field(:summary, :string, description: "The actor's summary") - field(:preferred_username, :string, description: "The actor's preferred username") - field(:keys, :string, description: "The actors RSA Keys") - - field(:manually_approves_followers, :boolean, - description: "Whether the actors manually approves followers" - ) - - field(:suspended, :boolean, description: "If the actor is suspended") - field(:avatar_url, :string, description: "The actor's avatar url") - field(:banner_url, :string, description: "The actor's banner url") - - # These one should have a privacy setting - field(:following, list_of(:follower), description: "List of followings") - field(:followers, list_of(:follower), description: "List of followers") - field(:followersCount, :integer, description: "Number of followers for this actor") - field(:followingCount, :integer, description: "Number of actors following this actor") - - # This one should have a privacy setting - field(:organized_events, list_of(:event), - resolve: dataloader(Events), - description: "A list of the events this actor has organized" - ) - - # This one is for the person itself **only** - # field(:feed, list_of(:event), description: "List of events the actor sees in his or her feed") - - # field(:memberships, list_of(:member)) - - resolve_type(fn - %Actor{type: :Person}, _ -> - :person - - %Actor{type: :Group}, _ -> - :group - end) - end - - @desc "The list of types an actor can be" - enum :actor_type do - value(:Person, description: "An ActivityPub Person") - value(:Application, description: "An ActivityPub Application") - value(:Group, description: "An ActivityPub Group") - value(:Organization, description: "An ActivityPub Organization") - value(:Service, description: "An ActivityPub Service") - end - - @desc "A local user of Mobilizon" - object :user do - field(:id, non_null(:id), description: "The user's ID") - field(:email, non_null(:string), description: "The user's email") - - field(:profiles, non_null(list_of(:person)), - description: "The user's list of profiles (identities)" - ) - - field(:default_actor, non_null(:person), description: "The user's default actor") - - field(:confirmed_at, :datetime, - description: "The datetime when the user was confirmed/activated" - ) - - field(:confirmation_sent_at, :datetime, - description: "The datetime the last activation/confirmation token was sent" - ) - - field(:confirmation_token, :string, description: "The account activation/confirmation token") - - field(:reset_password_sent_at, :datetime, - description: "The datetime last reset password email was sent" - ) - - field(:reset_password_token, :string, - description: "The token sent when requesting password token" - ) - end - @desc "A JWT and the associated user ID" object :login do field(:token, non_null(:string), description: "A JWT Token for this session") field(:user, non_null(:user), description: "The user associated to this session") end - @desc "An event" - object :event do - field(:uuid, :uuid, description: "The Event UUID") - field(:url, :string, description: "The ActivityPub Event URL") - field(:local, :boolean, description: "Whether the event is local or not") - field(:title, :string, description: "The event's title") - field(:description, :string, description: "The event's description") - field(:begins_on, :datetime, description: "Datetime for when the event begins") - field(:ends_on, :datetime, description: "Datetime for when the event ends") - field(:state, :integer, description: "State of the event") - field(:status, :integer, description: "Status of the event") - field(:public, :boolean, description: "Whether the event is public or not") - # TODO replace me with picture object - field(:thumbnail, :string, description: "A thumbnail picture for the event") - # TODO replace me with banner - field(:large_image, :string, description: "A large picture for the event") - field(:publish_at, :datetime, description: "When the event was published") - field(:address_type, :address_type, description: "The type of the event's address") - # TODO implement these properly with an interface - # field(:online_address, :string, description: "???") - # field(:phone, :string, description: "") - - field(:organizer_actor, :person, - resolve: dataloader(Actors), - description: "The event's organizer (as a person)" - ) - - field(:attributed_to, :actor, description: "Who the event is attributed to (often a group)") - # field(:tags, list_of(:tag)) - field(:category, :category, description: "The event's category") - - field(:participants, list_of(:participant), - resolve: &Resolvers.Event.list_participants_for_event/3, - description: "The event's participants" - ) - - # field(:tracks, list_of(:track)) - # field(:sessions, list_of(:session)) - # field(:physical_address, :address) - - field(:updated_at, :datetime, description: "When the event was last updated") - field(:created_at, :datetime, description: "When the event was created") - end - - @desc "A comment" - object :comment do - field(:uuid, :uuid) - field(:url, :string) - field(:local, :boolean) - field(:text, :string) - field(:primaryLanguage, :string) - field(:replies, list_of(:comment)) - field(:threadLanguages, non_null(list_of(:string))) - end - - @desc "Represents a participant to an event" - object :participant do - field(:event, :event, - resolve: dataloader(Events), - description: "The event which the actor participates in" - ) - - field(:actor, :actor, description: "The actor that participates to the event") - field(:role, :integer, description: "The role of this actor at this event") - end - - @desc "The list of types an address can be" - enum :address_type do - value(:physical, description: "The address is physical, like a postal address") - value(:url, description: "The address is on the Web, like an URL") - value(:phone, description: "The address is a phone number for a conference") - value(:other, description: "The address is something else") - end - - @desc "A category" - object :category do - field(:id, :id, description: "The category's ID") - field(:description, :string, description: "The category's description") - field(:picture, :picture, description: "The category's picture") - field(:title, :string, description: "The category's title") - end - @desc "A picture" object :picture do field(:url, :string, description: "The URL for this picture") @@ -314,28 +52,6 @@ defmodule MobilizonWeb.Schema do field(:published, :datetime, description: "Datetime when the notification was published") end - @desc """ - Represents a member of a group - """ - object :member do - field(:parent, :group, description: "Of which the profile is member") - field(:person, :person, description: "Which profile is member of") - field(:role, :integer, description: "The role of this membership") - field(:approved, :boolean, description: "Whether this membership has been approved") - end - - @desc """ - Represents an actor's follower - """ - object :follower do - field(:target_actor, :actor, description: "What or who the profile follows") - field(:actor, :actor, description: "Which profile follows") - - field(:approved, :boolean, - description: "Whether the follow has been approved by the target actor" - ) - end - union :object do types([:event, :person, :group, :comment, :follower, :member, :participant]) diff --git a/lib/mobilizon_web/schema/actor.ex b/lib/mobilizon_web/schema/actor.ex new file mode 100644 index 000000000..d93ac5041 --- /dev/null +++ b/lib/mobilizon_web/schema/actor.ex @@ -0,0 +1,62 @@ +defmodule MobilizonWeb.Schema.ActorInterface do + use Absinthe.Schema.Notation + import Absinthe.Resolution.Helpers, only: [dataloader: 1] + alias Mobilizon.Actors.Actor + + import_types(MobilizonWeb.Schema.Actors.FollowerType) + import_types(MobilizonWeb.Schema.EventType) + + @desc "An ActivityPub actor" + interface :actor do + field(:url, :string, description: "The ActivityPub actor's URL") + field(:type, :actor_type, description: "The type of Actor (Person, Group,…)") + field(:name, :string, description: "The actor's displayed name") + field(:domain, :string, description: "The actor's domain if (null if it's this instance)") + field(:local, :boolean, description: "If the actor is from this instance") + field(:summary, :string, description: "The actor's summary") + field(:preferred_username, :string, description: "The actor's preferred username") + field(:keys, :string, description: "The actors RSA Keys") + + field(:manually_approves_followers, :boolean, + description: "Whether the actors manually approves followers" + ) + + field(:suspended, :boolean, description: "If the actor is suspended") + field(:avatar_url, :string, description: "The actor's avatar url") + field(:banner_url, :string, description: "The actor's banner url") + + # These one should have a privacy setting + field(:following, list_of(:follower), description: "List of followings") + field(:followers, list_of(:follower), description: "List of followers") + field(:followersCount, :integer, description: "Number of followers for this actor") + field(:followingCount, :integer, description: "Number of actors following this actor") + + # This one should have a privacy setting + field(:organized_events, list_of(:event), + resolve: dataloader(Events), + description: "A list of the events this actor has organized" + ) + + # This one is for the person itself **only** + # field(:feed, list_of(:event), description: "List of events the actor sees in his or her feed") + + # field(:memberships, list_of(:member)) + + resolve_type(fn + %Actor{type: :Person}, _ -> + :person + + %Actor{type: :Group}, _ -> + :group + end) + end + + @desc "The list of types an actor can be" + enum :actor_type do + value(:Person, description: "An ActivityPub Person") + value(:Application, description: "An ActivityPub Application") + value(:Group, description: "An ActivityPub Group") + value(:Organization, description: "An ActivityPub Organization") + value(:Service, description: "An ActivityPub Service") + end +end diff --git a/lib/mobilizon_web/schema/actors/follower.ex b/lib/mobilizon_web/schema/actors/follower.ex new file mode 100644 index 000000000..163deef79 --- /dev/null +++ b/lib/mobilizon_web/schema/actors/follower.ex @@ -0,0 +1,15 @@ +defmodule MobilizonWeb.Schema.Actors.FollowerType do + use Absinthe.Schema.Notation + + @desc """ + Represents an actor's follower + """ + object :follower do + field(:target_actor, :actor, description: "What or who the profile follows") + field(:actor, :actor, description: "Which profile follows") + + field(:approved, :boolean, + description: "Whether the follow has been approved by the target actor" + ) + end +end diff --git a/lib/mobilizon_web/schema/actors/group.ex b/lib/mobilizon_web/schema/actors/group.ex new file mode 100644 index 000000000..60a248ef6 --- /dev/null +++ b/lib/mobilizon_web/schema/actors/group.ex @@ -0,0 +1,68 @@ +defmodule MobilizonWeb.Schema.Actors.GroupType do + use Absinthe.Schema.Notation + import Absinthe.Resolution.Helpers, only: [dataloader: 1] + import_types(MobilizonWeb.Schema.Actors.MemberType) + + @desc """ + Represents a group of actors + """ + object :group do + interfaces([:actor]) + + field(:url, :string, description: "The ActivityPub actor's URL") + field(:type, :actor_type, description: "The type of Actor (Person, Group,…)") + field(:name, :string, description: "The actor's displayed name") + field(:domain, :string, description: "The actor's domain if (null if it's this instance)") + field(:local, :boolean, description: "If the actor is from this instance") + field(:summary, :string, description: "The actor's summary") + field(:preferred_username, :string, description: "The actor's preferred username") + field(:keys, :string, description: "The actors RSA Keys") + + field(:manually_approves_followers, :boolean, + description: "Whether the actors manually approves followers" + ) + + field(:suspended, :boolean, description: "If the actor is suspended") + field(:avatar_url, :string, description: "The actor's avatar url") + field(:banner_url, :string, description: "The actor's banner url") + + # These one should have a privacy setting + field(:following, list_of(:follower), description: "List of followings") + field(:followers, list_of(:follower), description: "List of followers") + field(:followersCount, :integer, description: "Number of followers for this actor") + field(:followingCount, :integer, description: "Number of actors following this actor") + + # This one should have a privacy setting + field(:organized_events, list_of(:event), + resolve: dataloader(Events), + description: "A list of the events this actor has organized" + ) + + field(:types, :group_type, description: "The type of group : Group, Community,…") + + field(:openness, :openness, + description: "Whether the group is opened to all or has restricted access" + ) + + field(:members, non_null(list_of(:member)), description: "List of group members") + end + + @desc """ + The types of Group that exist + """ + enum :group_type do + value(:group, description: "A private group of persons") + value(:community, description: "A public group of many actors") + end + + @desc """ + Describes how an actor is opened to follows + """ + enum :openness do + value(:invite_only, description: "The actor can only be followed by invitation") + + value(:moderated, description: "The actor needs to accept the following before it's effective") + + value(:open, description: "The actor is open to followings") + end +end diff --git a/lib/mobilizon_web/schema/actors/member.ex b/lib/mobilizon_web/schema/actors/member.ex new file mode 100644 index 000000000..97aef0491 --- /dev/null +++ b/lib/mobilizon_web/schema/actors/member.ex @@ -0,0 +1,13 @@ +defmodule MobilizonWeb.Schema.Actors.MemberType do + use Absinthe.Schema.Notation + + @desc """ + Represents a member of a group + """ + object :member do + field(:parent, :group, description: "Of which the profile is member") + field(:person, :person, description: "Which profile is member of") + field(:role, :integer, description: "The role of this membership") + field(:approved, :boolean, description: "Whether this membership has been approved") + end +end diff --git a/lib/mobilizon_web/schema/actors/person.ex b/lib/mobilizon_web/schema/actors/person.ex new file mode 100644 index 000000000..2ddb39120 --- /dev/null +++ b/lib/mobilizon_web/schema/actors/person.ex @@ -0,0 +1,44 @@ +defmodule MobilizonWeb.Schema.Actors.PersonType do + use Absinthe.Schema.Notation + import Absinthe.Resolution.Helpers, only: [dataloader: 1] + import_types(MobilizonWeb.Schema.UserType) + + @desc """ + Represents a person identity + """ + object :person do + interfaces([:actor]) + field(:user, :user, description: "The user this actor is associated to") + + field(:member_of, list_of(:member), description: "The list of groups this person is member of") + + field(:url, :string, description: "The ActivityPub actor's URL") + field(:type, :actor_type, description: "The type of Actor (Person, Group,…)") + field(:name, :string, description: "The actor's displayed name") + field(:domain, :string, description: "The actor's domain if (null if it's this instance)") + field(:local, :boolean, description: "If the actor is from this instance") + field(:summary, :string, description: "The actor's summary") + field(:preferred_username, :string, description: "The actor's preferred username") + field(:keys, :string, description: "The actors RSA Keys") + + field(:manually_approves_followers, :boolean, + description: "Whether the actors manually approves followers" + ) + + field(:suspended, :boolean, description: "If the actor is suspended") + field(:avatar_url, :string, description: "The actor's avatar url") + field(:banner_url, :string, description: "The actor's banner url") + + # These one should have a privacy setting + field(:following, list_of(:follower), description: "List of followings") + field(:followers, list_of(:follower), description: "List of followers") + field(:followersCount, :integer, description: "Number of followers for this actor") + field(:followingCount, :integer, description: "Number of actors following this actor") + + # This one should have a privacy setting + field(:organized_events, list_of(:event), + resolve: dataloader(Events), + description: "A list of the events this actor has organized" + ) + end +end diff --git a/lib/mobilizon_web/schema/address.ex b/lib/mobilizon_web/schema/address.ex new file mode 100644 index 000000000..476575a7e --- /dev/null +++ b/lib/mobilizon_web/schema/address.ex @@ -0,0 +1,36 @@ +defmodule MobilizonWeb.Schema.AddressType do + use Absinthe.Schema.Notation + + object :physical_address do + field(:type, :address_type) + field(:geom, :point) + field(:floor, :string) + field(:streetAddress, :string) + field(:addressLocality, :string) + field(:postalCode, :string) + field(:addressRegion, :string) + field(:addressCountry, :string) + field(:description, :string) + field(:name, :string) + end + + object :phone_address do + field(:type, :address_type) + field(:phone, :string) + field(:info, :string) + end + + object :online_address do + field(:type, :address_type) + field(:url, :string) + field(:info, :string) + end + + @desc "The list of types an address can be" + enum :address_type do + value(:physical, description: "The address is physical, like a postal address") + value(:url, description: "The address is on the Web, like an URL") + value(:phone, description: "The address is a phone number for a conference") + value(:other, description: "The address is something else") + end +end diff --git a/lib/mobilizon_web/schema/comment.ex b/lib/mobilizon_web/schema/comment.ex new file mode 100644 index 000000000..3ac004702 --- /dev/null +++ b/lib/mobilizon_web/schema/comment.ex @@ -0,0 +1,14 @@ +defmodule MobilizonWeb.Schema.CommentType do + use Absinthe.Schema.Notation + + @desc "A comment" + object :comment do + field(:uuid, :uuid) + field(:url, :string) + field(:local, :boolean) + field(:text, :string) + field(:primaryLanguage, :string) + field(:replies, list_of(:comment)) + field(:threadLanguages, non_null(list_of(:string))) + end +end diff --git a/lib/mobilizon_web/schema/custom/point.ex b/lib/mobilizon_web/schema/custom/point.ex new file mode 100644 index 000000000..7bd3cf974 --- /dev/null +++ b/lib/mobilizon_web/schema/custom/point.ex @@ -0,0 +1,38 @@ +defmodule MobilizonWeb.Schema.Custom.Point do + @moduledoc """ + The geom scalar type allows Geo.PostGIS.Geometry strings to be passed in and out. + Requires `{:geo, "~> 3.0"},` package: https://github.com/elixir-ecto/ecto + """ + use Absinthe.Schema.Notation + + scalar :point, name: "Point" do + description(""" + The `Point` scalar type represents Point geographic information compliant string data, + represented as floats separated by a semi-colon. The geodetic system is WGS 84 + """) + + serialize(&encode/1) + parse(&decode/1) + end + + @spec decode(Absinthe.Blueprint.Input.String.t()) :: {:ok, term()} | :error + @spec decode(Absinthe.Blueprint.Input.Null.t()) :: {:ok, nil} + defp decode(%Absinthe.Blueprint.Input.String{value: value}) do + with [_, _] = lonlat <- String.split(value, ";", trim: true), + [{lon, ""}, {lat, ""}] <- Enum.map(lonlat, &Float.parse(&1)) do + {:ok, %Geo.Point{coordinates: {lon, lat}, srid: 4326}} + else + _ -> :error + end + end + + defp decode(%Absinthe.Blueprint.Input.Null{}) do + {:ok, nil} + end + + defp decode(_) do + :error + end + + defp encode(%Geo.Point{coordinates: {lon, lat}, srid: 4326}), do: "#{lon};#{lat}" +end diff --git a/lib/mobilizon_web/schema/event.ex b/lib/mobilizon_web/schema/event.ex new file mode 100644 index 000000000..0ed60c52f --- /dev/null +++ b/lib/mobilizon_web/schema/event.ex @@ -0,0 +1,49 @@ +defmodule MobilizonWeb.Schema.EventType do + use Absinthe.Schema.Notation + import Absinthe.Resolution.Helpers, only: [dataloader: 1] + import_types(MobilizonWeb.Schema.AddressType) + import_types(MobilizonWeb.Schema.Events.ParticipantType) + import_types(MobilizonWeb.Schema.Events.CategoryType) + + @desc "An event" + object :event do + field(:uuid, :uuid, description: "The Event UUID") + field(:url, :string, description: "The ActivityPub Event URL") + field(:local, :boolean, description: "Whether the event is local or not") + field(:title, :string, description: "The event's title") + field(:description, :string, description: "The event's description") + field(:begins_on, :datetime, description: "Datetime for when the event begins") + field(:ends_on, :datetime, description: "Datetime for when the event ends") + field(:state, :integer, description: "State of the event") + field(:status, :integer, description: "Status of the event") + field(:public, :boolean, description: "Whether the event is public or not") + # TODO replace me with picture object + field(:thumbnail, :string, description: "A thumbnail picture for the event") + # TODO replace me with banner + field(:large_image, :string, description: "A large picture for the event") + field(:publish_at, :datetime, description: "When the event was published") + field(:physical_address, :physical_address, description: "The type of the event's address") + field(:online_address, :online_address, description: "Online address of the event") + field(:phone_address, :phone_address, description: "Phone address for the event") + + field(:organizer_actor, :person, + resolve: dataloader(Actors), + description: "The event's organizer (as a person)" + ) + + field(:attributed_to, :actor, description: "Who the event is attributed to (often a group)") + # field(:tags, list_of(:tag)) + field(:category, :category, description: "The event's category") + + field(:participants, list_of(:participant), + resolve: &Resolvers.Event.list_participants_for_event/3, + description: "The event's participants" + ) + + # field(:tracks, list_of(:track)) + # field(:sessions, list_of(:session)) + + field(:updated_at, :datetime, description: "When the event was last updated") + field(:created_at, :datetime, description: "When the event was created") + end +end diff --git a/lib/mobilizon_web/schema/events/category.ex b/lib/mobilizon_web/schema/events/category.ex new file mode 100644 index 000000000..24f31edb7 --- /dev/null +++ b/lib/mobilizon_web/schema/events/category.ex @@ -0,0 +1,11 @@ +defmodule MobilizonWeb.Schema.Events.CategoryType do + use Absinthe.Schema.Notation + + @desc "A category" + object :category do + field(:id, :id, description: "The category's ID") + field(:description, :string, description: "The category's description") + field(:picture, :picture, description: "The category's picture") + field(:title, :string, description: "The category's title") + end +end diff --git a/lib/mobilizon_web/schema/events/participant.ex b/lib/mobilizon_web/schema/events/participant.ex new file mode 100644 index 000000000..54df1f753 --- /dev/null +++ b/lib/mobilizon_web/schema/events/participant.ex @@ -0,0 +1,14 @@ +defmodule MobilizonWeb.Schema.Events.ParticipantType do + use Absinthe.Schema.Notation + + @desc "Represents a participant to an event" + object :participant do + field(:event, :event, + resolve: dataloader(Events), + description: "The event which the actor participates in" + ) + + field(:actor, :actor, description: "The actor that participates to the event") + field(:role, :integer, description: "The role of this actor at this event") + end +end diff --git a/lib/mobilizon_web/schema/user.ex b/lib/mobilizon_web/schema/user.ex new file mode 100644 index 000000000..d908c4e7e --- /dev/null +++ b/lib/mobilizon_web/schema/user.ex @@ -0,0 +1,33 @@ +defmodule MobilizonWeb.Schema.UserType do + use Absinthe.Schema.Notation + + @desc "A local user of Mobilizon" + object :user do + field(:id, non_null(:id), description: "The user's ID") + field(:email, non_null(:string), description: "The user's email") + + field(:profiles, non_null(list_of(:person)), + description: "The user's list of profiles (identities)" + ) + + field(:default_actor, non_null(:person), description: "The user's default actor") + + field(:confirmed_at, :datetime, + description: "The datetime when the user was confirmed/activated" + ) + + field(:confirmation_sent_at, :datetime, + description: "The datetime the last activation/confirmation token was sent" + ) + + field(:confirmation_token, :string, description: "The account activation/confirmation token") + + field(:reset_password_sent_at, :datetime, + description: "The datetime last reset password email was sent" + ) + + field(:reset_password_token, :string, + description: "The token sent when requesting password token" + ) + end +end