From 698f78ee9a946e159d36982164c112c97d424546 Mon Sep 17 00:00:00 2001
From: Thomas Citharel <tcit@tcit.fr>
Date: Thu, 7 Apr 2022 18:37:31 +0200
Subject: [PATCH 1/2] Reorganize docs

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
---
 mix.exs | 228 ++++++++++++++------------------------------------------
 1 file changed, 54 insertions(+), 174 deletions(-)

diff --git a/mix.exs b/mix.exs
index 7fb65ae89..ad4bc3f8e 100644
--- a/mix.exs
+++ b/mix.exs
@@ -36,7 +36,6 @@ defmodule Mobilizon.Mixfile do
       ],
       unused: [
         ignore: [
-          Mobilizon.Storage.Repo,
           Mobilizon.Storage.PostgresTypes,
           Mobilizon.Factory,
           Mobilizon.Web.Router.Helpers,
@@ -268,11 +267,36 @@ defmodule Mobilizon.Mixfile do
       groups_for_modules: groups_for_modules(),
       nest_modules_by_prefix: [
         Mobilizon,
-        Mobilizon.Web,
-        Mobilizon.Service.Geospatial,
-        Mobilizon.Web.Resolvers,
+        Mobilizon.Activities,
+        Mobilizon.Actors,
+        Mobilizon.Admin,
+        Mobilizon.Discussions,
+        Mobilizon.Events,
+        Mobilizon.GraphQL,
+        Mobilizon.Medias,
+        Mobilizon.Posts,
+        Mobilizon.Reports,
+        Mobilizon.Resources,
+        Mobilizon.Todos,
+        Mobilizon.Users,
+        Mobilizon.Federation,
+        Mobilizon.Federation.ActivityPub,
+        Mobilizon.Federation.ActivityPub.Actions,
+        Mobilizon.Federation.ActivityPub.Types,
+        Mobilizon.Federation.ActivityStream,
+        Mobilizon.Federation.ActivityStream.Converter,
+        Mobilizon.GraphQL.Resolvers,
         Mobilizon.GraphQL.Schema,
-        Mobilizon.Service
+        Mobilizon.Service,
+        Mobilizon.Service.Activity,
+        Mobilizon.Service.Export,
+        Mobilizon.Service.Geospatial,
+        Mobilizon.Service.Metadata,
+        Mobilizon.Service.Workers,
+        Mobilizon.Web,
+        Mobilizon.Web.Email,
+        Mobilizon.Web.Plugs,
+        Mobilizon.Web.Upload
       ]
     ]
   end
@@ -280,171 +304,41 @@ defmodule Mobilizon.Mixfile do
   defp groups_for_modules() do
     [
       Models: [
-        Mobilizon.Actors,
-        Mobilizon.Actors.Actor,
-        Mobilizon.Actors.ActorOpenness,
-        Mobilizon.Actors.ActorType,
-        Mobilizon.Actors.MemberRole,
-        Mobilizon.Actors.Bot,
-        Mobilizon.Actors.Follower,
-        Mobilizon.Actors.Member,
-        Mobilizon.Addresses,
-        Mobilizon.Addresses.Address,
-        Mobilizon.Admin,
-        Mobilizon.Admin.ActionLog,
-        Mobilizon.Events,
-        Mobilizon.Events.Event,
-        Mobilizon.Events.FeedToken,
-        Mobilizon.Events.Participant,
-        Mobilizon.Events.Session,
-        Mobilizon.Events.Tag,
-        Mobilizon.Events.TagRelations,
-        Mobilizon.Events.Track,
-        Mobilizon.Events.EventStatus,
-        Mobilizon.Events.EventVisibility,
-        Mobilizon.Events.JoinOptions,
-        Mobilizon.Events.ParticipantRole,
-        Mobilizon.Events.Tag.TitleSlug,
-        Mobilizon.Events.Tag.TitleSlug.Type,
-        Mobilizon.Events.TagRelation,
-        Mobilizon.Medias,
-        Mobilizon.Medias.File,
-        Mobilizon.Medias.Media,
-        Mobilizon.Mention,
-        Mobilizon.Reports,
-        Mobilizon.Reports.Note,
-        Mobilizon.Reports.Report,
-        Mobilizon.Share,
-        Mobilizon.Tombstone,
-        Mobilizon.Users,
-        Mobilizon.Users.User,
-        Mobilizon.Users.UserRole,
-        Mobilizon.Federation.ActivityPub.Activity
+        ~r/Mobilizon.Actors~r/,
+        ~r/Mobilizon.Addresses/,
+        ~r/Mobilizon.Admin/,
+        ~r/Mobilizon.Events/,
+        ~r/Mobilizon.Instances/,
+        ~r/Mobilizon.Medias/,
+        ~r/Mobilizon.Mention/,
+        ~r/Mobilizon.Reports/,
+        ~r/Mobilizon.Share/,
+        ~r/Mobilizon.Tombstone/,
+        ~r/Mobilizon.Users/
       ],
-      APIs: [
-        Mobilizon.GraphQL.API.Comments,
-        Mobilizon.GraphQL.API.Events,
-        Mobilizon.GraphQL.API.Follows,
-        Mobilizon.GraphQL.API.Groups,
-        Mobilizon.GraphQL.API.Participations,
-        Mobilizon.GraphQL.API.Reports,
-        Mobilizon.GraphQL.API.Search,
-        Mobilizon.GraphQL.API.Utils
+      "GraphQL APIs": [
+        ~r/Mobilizon.GraphQL.API/
+      ],
+      Emails: [
+        ~r/Mobilizon.Web.Email/
       ],
       Web: [
-        Mobilizon.Web,
-        Mobilizon.Web.Endpoint,
-        Mobilizon.Web.Router,
-        Mobilizon.Web.Router.Helpers,
-        Mobilizon.Web.Plugs.UploadedMedia,
-        Mobilizon.Web.FallbackController,
-        Mobilizon.Web.FeedController,
-        Mobilizon.Web.PageController,
-        Mobilizon.Web.ChangesetView,
-        Mobilizon.Web.JsonLD.ObjectView,
-        Mobilizon.Web.EmailView,
-        Mobilizon.Web.ErrorView,
-        Mobilizon.Web.LayoutView,
-        Mobilizon.Web.PageView,
-        Mobilizon.Web.Auth.Context,
-        Mobilizon.Web.Auth.ErrorHandler,
-        Mobilizon.Web.Auth.Guardian,
-        Mobilizon.Web.Auth.Pipeline,
-        Mobilizon.Web.Cache,
-        Mobilizon.Web.Cache.ActivityPub,
-        Mobilizon.Web.Email,
-        Mobilizon.Web.Email.Admin,
-        Mobilizon.Web.Email.Checker,
-        Mobilizon.Web.Email.Event,
-        Mobilizon.Web.Email.Mailer,
-        Mobilizon.Web.Email.Participation,
-        Mobilizon.Web.Email.User,
-        Mobilizon.Web.Upload,
-        Mobilizon.Web.Upload.Filter,
-        Mobilizon.Web.Upload.Filter.AnonymizeFilename,
-        Mobilizon.Web.Upload.Filter.Dedupe,
-        Mobilizon.Web.Upload.Filter.Mogrify,
-        Mobilizon.Web.Upload.Filter.Optimize,
-        Mobilizon.Web.Upload.MIME,
-        Mobilizon.Web.Upload.Uploader,
-        Mobilizon.Web.Upload.Uploader.Local,
-        Mobilizon.Web.ReverseProxy
+        ~r/Mobilizon.Web/
       ],
       Geospatial: [
-        Mobilizon.Service.Geospatial,
-        Mobilizon.Service.Geospatial.Addok,
-        Mobilizon.Service.Geospatial.GoogleMaps,
-        Mobilizon.Service.Geospatial.MapQuest,
-        Mobilizon.Service.Geospatial.Mimirsbrunn,
-        Mobilizon.Service.Geospatial.Nominatim,
-        Mobilizon.Service.Geospatial.Pelias,
-        Mobilizon.Service.Geospatial.Photon,
-        Mobilizon.Service.Geospatial.Provider
+        ~r/Mobilizon.Service.Geospatial/
       ],
       Localization: [
-        Mobilizon.Cldr,
-        Mobilizon.Web.Gettext
+        ~r/Mobilizon.Cldr/,
+        ~r/Mobilizon.Web.Gettext/
       ],
       GraphQL: [
-        Mobilizon.Web.GraphQLSocket,
-        Mobilizon.GraphQL.Resolvers.Address,
-        Mobilizon.GraphQL.Resolvers.Admin,
-        Mobilizon.GraphQL.Resolvers.Comment,
-        Mobilizon.GraphQL.Resolvers.Config,
-        Mobilizon.GraphQL.Resolvers.Event,
-        Mobilizon.GraphQL.Resolvers.FeedToken,
-        Mobilizon.GraphQL.Resolvers.Group,
-        Mobilizon.GraphQL.Resolvers.Member,
-        Mobilizon.GraphQL.Resolvers.Person,
-        Mobilizon.GraphQL.Resolvers.Media,
-        Mobilizon.GraphQL.Resolvers.Report,
-        Mobilizon.GraphQL.Resolvers.Search,
-        Mobilizon.GraphQL.Resolvers.Tag,
-        Mobilizon.GraphQL.Resolvers.User,
-        Mobilizon.GraphQL.Schema,
-        Mobilizon.GraphQL.Schema.ActorInterface,
-        Mobilizon.GraphQL.Schema.Actors.ApplicationType,
-        Mobilizon.GraphQL.Schema.Actors.FollowerType,
-        Mobilizon.GraphQL.Schema.Actors.GroupType,
-        Mobilizon.GraphQL.Schema.Actors.MemberType,
-        Mobilizon.GraphQL.Schema.Actors.PersonType,
-        Mobilizon.GraphQL.Schema.AddressType,
-        Mobilizon.GraphQL.Schema.AdminType,
-        Mobilizon.GraphQL.Schema.Discussions.CommentType,
-        Mobilizon.GraphQL.Schema.ConfigType,
-        Mobilizon.GraphQL.Schema.EventType,
-        Mobilizon.GraphQL.Schema.Events.FeedTokenType,
-        Mobilizon.GraphQL.Schema.Events.ParticipantType,
-        Mobilizon.GraphQL.Schema.MediaType,
-        Mobilizon.GraphQL.Schema.ReportType,
-        Mobilizon.GraphQL.Schema.SearchType,
-        Mobilizon.GraphQL.Schema.SortType,
-        Mobilizon.GraphQL.Schema.TagType,
-        Mobilizon.GraphQL.Schema.UserType,
-        Mobilizon.GraphQL.Schema.Utils,
-        Mobilizon.GraphQL.Schema.Custom.Point,
-        Mobilizon.GraphQL.Schema.Custom.UUID
+        ~r/Mobilizon.Web.GraphQLSocket/,
+        ~r/Mobilizon.GraphQL/
       ],
       ActivityPub: [
-        Mobilizon.Federation.ActivityPub,
-        Mobilizon.Federation.ActivityPub.Audience,
-        Mobilizon.Federation.ActivityPub.Federator,
-        Mobilizon.Federation.ActivityPub.Relay,
-        Mobilizon.Federation.ActivityPub.Transmogrifier,
-        Mobilizon.Federation.ActivityPub.Visibility,
-        Mobilizon.Federation.ActivityPub.Utils,
-        Mobilizon.Federation.ActivityStream.Convertible,
-        Mobilizon.Federation.ActivityStream.Converter,
-        Mobilizon.Federation.ActivityStream.Converter.Actor,
-        Mobilizon.Federation.ActivityStream.Converter.Address,
-        Mobilizon.Federation.ActivityStream.Converter.Comment,
-        Mobilizon.Federation.ActivityStream.Converter.Event,
-        Mobilizon.Federation.ActivityStream.Converter.Flag,
-        Mobilizon.Federation.ActivityStream.Converter.Follower,
-        Mobilizon.Federation.ActivityStream.Converter.Participant,
-        Mobilizon.Federation.ActivityStream.Converter.Media,
-        Mobilizon.Federation.ActivityStream.Converter.Tombstone,
-        Mobilizon.Federation.ActivityStream.Converter.Utils,
+        ~r/Mobilizon.Federation.ActivityPub/,
+        ~r/Mobilizon.Federation.ActivityStream/,
         Mobilizon.Federation.HTTPSignatures.Signature,
         Mobilizon.Federation.WebFinger,
         Mobilizon.Federation.WebFinger.XmlBuilder,
@@ -458,21 +352,7 @@ defmodule Mobilizon.Mixfile do
         Mobilizon.Web.ActivityPub.ObjectView
       ],
       Services: [
-        Mobilizon.Service.Export.Feed,
-        Mobilizon.Service.Export.ICalendar,
-        Mobilizon.Service.Formatter,
-        Mobilizon.Service.Formatter.HTML,
-        Mobilizon.Service.Formatter.DefaultScrubbler,
-        Mobilizon.Service.Metadata,
-        Mobilizon.Service.Metadata.Actor,
-        Mobilizon.Service.Metadata.Comment,
-        Mobilizon.Service.Metadata.Event,
-        Mobilizon.Service.Metadata.Instance,
-        Mobilizon.Service.Metadata.Utils,
-        Mobilizon.Service.Statistics,
-        Mobilizon.Service.Workers.Background,
-        Mobilizon.Service.Workers.BuildSearch,
-        Mobilizon.Service.Workers.Helper
+        ~r/Mobilizon.Service/
       ],
       Tools: [
         Mobilizon.Application,

From 7a18d0b2bb2a9fd30602681b86fc2855371b6b87 Mon Sep 17 00:00:00 2001
From: Thomas Citharel <tcit@tcit.fr>
Date: Thu, 7 Apr 2022 18:37:44 +0200
Subject: [PATCH 2/2] Fix ex_docs warnings

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
---
 lib/graphql/api/search.ex                |  8 ++++----
 lib/graphql/resolvers/followers.ex       |  2 +-
 lib/graphql/resolvers/person.ex          |  6 ++++--
 lib/mobilizon/activities/activities.ex   |  4 ++--
 lib/mobilizon/actors/actors.ex           | 15 ++++++++-------
 lib/mobilizon/addresses/address.ex       |  2 +-
 lib/mobilizon/admin/admin.ex             |  2 +-
 lib/mobilizon/discussions/discussions.ex | 10 ++++++----
 lib/mobilizon/events/events.ex           | 13 +++++++------
 lib/mobilizon/events/tag.ex              |  2 +-
 lib/mobilizon/instances/instance.ex      | 10 ++++++++++
 lib/mobilizon/medias/medias.ex           |  2 +-
 lib/mobilizon/posts/posts.ex             |  4 ++--
 lib/mobilizon/resources/resources.ex     |  5 +++--
 lib/mobilizon/storage/repo.ex            |  4 +---
 lib/mobilizon/todos/todos.ex             |  4 ++--
 lib/mobilizon/users/users.ex             |  2 +-
 lib/service/export/common.ex             |  2 +-
 lib/web/email/email.ex                   |  1 +
 lib/web/views/activity_pub/actor_view.ex |  2 +-
 20 files changed, 58 insertions(+), 42 deletions(-)

diff --git a/lib/graphql/api/search.ex b/lib/graphql/api/search.ex
index 3b002b6f6..f1a8600c4 100644
--- a/lib/graphql/api/search.ex
+++ b/lib/graphql/api/search.ex
@@ -19,7 +19,7 @@ defmodule Mobilizon.GraphQL.API.Search do
   Searches actors.
   """
   @spec search_actors(map(), integer | nil, integer | nil, ActorType.t()) ::
-          {:ok, Page.t()} | {:error, String.t()}
+          {:ok, Page.t(Actor.t())} | {:error, String.t()}
   def search_actors(%{term: term} = args, page \\ 1, limit \\ 10, result_type) do
     term = String.trim(term)
 
@@ -64,7 +64,7 @@ defmodule Mobilizon.GraphQL.API.Search do
   Search events
   """
   @spec search_events(map(), integer | nil, integer | nil) ::
-          {:ok, Page.t()}
+          {:ok, Page.t(Event.t())}
   def search_events(%{term: term} = args, page \\ 1, limit \\ 10) do
     term = String.trim(term)
 
@@ -100,7 +100,7 @@ defmodule Mobilizon.GraphQL.API.Search do
   end
 
   # If the search string is an username
-  @spec process_from_username(String.t()) :: Page.t()
+  @spec process_from_username(String.t()) :: Page.t(Actor.t())
   defp process_from_username(search) do
     case ActivityPubActor.find_or_make_actor_from_nickname(search) do
       {:ok, %Actor{type: :Group} = actor} ->
@@ -118,7 +118,7 @@ defmodule Mobilizon.GraphQL.API.Search do
   end
 
   # If the search string is an URL
-  @spec process_from_url(String.t()) :: Page.t()
+  @spec process_from_url(String.t()) :: Page.t(struct())
   defp process_from_url(search) do
     case ActivityPub.fetch_object_from_url(search) do
       {:ok, object} ->
diff --git a/lib/graphql/resolvers/followers.ex b/lib/graphql/resolvers/followers.ex
index e293fd751..0fe127006 100644
--- a/lib/graphql/resolvers/followers.ex
+++ b/lib/graphql/resolvers/followers.ex
@@ -10,7 +10,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Followers do
   alias Mobilizon.Storage.Page
   alias Mobilizon.Users.User
 
-  @spec find_followers_for_group(Actor.t(), map(), map()) :: {:ok, Page.t()}
+  @spec find_followers_for_group(Actor.t(), map(), map()) :: {:ok, Page.t(Follower.t())}
   def find_followers_for_group(
         %Actor{id: group_id} = group,
         args,
diff --git a/lib/graphql/resolvers/person.ex b/lib/graphql/resolvers/person.ex
index 060ae2d42..c37554a12 100644
--- a/lib/graphql/resolvers/person.ex
+++ b/lib/graphql/resolvers/person.ex
@@ -357,7 +357,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
   @doc """
   Returns this person's group memberships
   """
-  @spec person_memberships(Actor.t(), map(), map()) :: {:ok, Page.t()} | {:error, String.t()}
+  @spec person_memberships(Actor.t(), map(), map()) ::
+          {:ok, Page.t(Member.t())} | {:error, String.t()}
   def person_memberships(%Actor{id: actor_id} = person, args, %{
         context: %{current_user: %User{} = user}
       }) do
@@ -399,7 +400,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
   @doc """
   Returns this person's group follows
   """
-  @spec person_follows(Actor.t(), map(), map()) :: {:ok, Page.t()} | {:error, String.t()}
+  @spec person_follows(Actor.t(), map(), map()) ::
+          {:ok, Page.t(Follower.t())} | {:error, String.t()}
   def person_follows(%Actor{} = person, %{group: group}, %{
         context: %{current_user: %User{} = user}
       }) do
diff --git a/lib/mobilizon/activities/activities.ex b/lib/mobilizon/activities/activities.ex
index 9d826bd73..52b7683ed 100644
--- a/lib/mobilizon/activities/activities.ex
+++ b/lib/mobilizon/activities/activities.ex
@@ -81,7 +81,7 @@ defmodule Mobilizon.Activities do
           Keyword.t(),
           integer() | nil,
           integer() | nil
-        ) :: Page.t()
+        ) :: Page.t(Activity.t())
   def list_group_activities_for_member(
         group_id,
         actor_asking_id,
@@ -107,7 +107,7 @@ defmodule Mobilizon.Activities do
           Keyword.t(),
           integer() | nil,
           integer() | nil
-        ) :: Page.t()
+        ) :: Page.t(Activity.t())
   def list_group_activities(
         group_id,
         filters \\ [],
diff --git a/lib/mobilizon/actors/actors.ex b/lib/mobilizon/actors/actors.ex
index cbf854ff6..e8054b36b 100644
--- a/lib/mobilizon/actors/actors.ex
+++ b/lib/mobilizon/actors/actors.ex
@@ -317,7 +317,7 @@ defmodule Mobilizon.Actors do
           boolean,
           integer | nil,
           integer | nil
-        ) :: Page.t()
+        ) :: Page.t(Actor.t())
   def list_actors(
         type \\ :Person,
         preferred_username \\ "",
@@ -452,7 +452,7 @@ defmodule Mobilizon.Actors do
           Keyword.t(),
           integer | nil,
           integer | nil
-        ) :: Page.t()
+        ) :: Page.t(Actor.t())
   def search_actors(
         term,
         options \\ [],
@@ -1103,7 +1103,7 @@ defmodule Mobilizon.Actors do
   Returns the paginated list of external followers for an actor.
   """
   @spec list_external_followers_for_actor_paginated(Actor.t(), integer | nil, integer | nil) ::
-          Page.t()
+          Page.t(Actor.t())
   def list_external_followers_for_actor_paginated(%Actor{id: actor_id}, page \\ nil, limit \\ nil) do
     actor_id
     |> list_external_followers_for_actor_query()
@@ -1113,7 +1113,7 @@ defmodule Mobilizon.Actors do
   @doc """
   Build a page struct for followers of an actor.
   """
-  @spec build_followers_for_actor(Actor.t(), integer | nil, integer | nil) :: Page.t()
+  @spec build_followers_for_actor(Actor.t(), integer | nil, integer | nil) :: Page.t(Follower.t())
   def build_followers_for_actor(%Actor{id: actor_id}, page \\ nil, limit \\ nil) do
     actor_id
     |> follower_actors_for_actor_query()
@@ -1135,7 +1135,7 @@ defmodule Mobilizon.Actors do
   Returns a paginated list of followers for an actor.
   """
   @spec list_paginated_followers_for_actor(Actor.t(), boolean | nil, integer | nil, integer | nil) ::
-          Page.t()
+          Page.t(Follower.t())
   def list_paginated_followers_for_actor(
         %Actor{id: actor_id},
         approved \\ nil,
@@ -1165,7 +1165,7 @@ defmodule Mobilizon.Actors do
   Returns the list of external followings for an actor.
   """
   @spec list_external_followings_for_actor_paginated(Actor.t(), integer | nil, integer | nil) ::
-          Page.t()
+          Page.t(Follower.t())
   def list_external_followings_for_actor_paginated(
         %Actor{id: actor_id},
         page \\ nil,
@@ -1179,7 +1179,8 @@ defmodule Mobilizon.Actors do
   @doc """
   Build a page struct for followings of an actor.
   """
-  @spec build_followings_for_actor(Actor.t(), integer | nil, integer | nil) :: Page.t()
+  @spec build_followings_for_actor(Actor.t(), integer | nil, integer | nil) ::
+          Page.t(Follower.t())
   def build_followings_for_actor(%Actor{id: actor_id}, page \\ nil, limit \\ nil) do
     actor_id
     |> followings_actors_for_actor_query()
diff --git a/lib/mobilizon/addresses/address.ex b/lib/mobilizon/addresses/address.ex
index 89845102a..66c7d4d3c 100644
--- a/lib/mobilizon/addresses/address.ex
+++ b/lib/mobilizon/addresses/address.ex
@@ -16,7 +16,7 @@ defmodule Mobilizon.Addresses.Address do
           locality: String.t() | nil,
           region: String.t() | nil,
           description: String.t() | nil,
-          geom: Geo.PostGIS.Geometry.t() | nil,
+          geom: Geo.Point.t() | nil,
           postal_code: String.t() | nil,
           street: String.t() | nil,
           type: String.t() | nil,
diff --git a/lib/mobilizon/admin/admin.ex b/lib/mobilizon/admin/admin.ex
index de267042d..c184bcba4 100644
--- a/lib/mobilizon/admin/admin.ex
+++ b/lib/mobilizon/admin/admin.ex
@@ -36,7 +36,7 @@ defmodule Mobilizon.Admin do
   @doc """
   Returns the list of action logs.
   """
-  @spec list_action_logs(integer | nil, integer | nil) :: Page.t()
+  @spec list_action_logs(integer | nil, integer | nil) :: Page.t(ActionLog.t())
   def list_action_logs(page \\ nil, limit \\ nil) do
     list_action_logs_query()
     |> Page.build_page(page, limit)
diff --git a/lib/mobilizon/discussions/discussions.ex b/lib/mobilizon/discussions/discussions.ex
index cfb080e27..78c06c91c 100644
--- a/lib/mobilizon/discussions/discussions.ex
+++ b/lib/mobilizon/discussions/discussions.ex
@@ -225,7 +225,7 @@ defmodule Mobilizon.Discussions do
   @doc """
   Returns a paginated list of local comments
   """
-  @spec list_local_comments(integer | nil, integer | nil) :: Page.t()
+  @spec list_local_comments(integer | nil, integer | nil) :: Page.t(Comment.t())
   def list_local_comments(page \\ nil, limit \\ nil) do
     Comment
     |> where([c], c.visibility == ^:public)
@@ -238,7 +238,8 @@ defmodule Mobilizon.Discussions do
   @doc """
   Returns the list of public comments for the actor.
   """
-  @spec list_public_comments_for_actor(Actor.t(), integer | nil, integer | nil) :: Page.t()
+  @spec list_public_comments_for_actor(Actor.t(), integer | nil, integer | nil) ::
+          Page.t(Comment.t())
   def list_public_comments_for_actor(%Actor{id: actor_id}, page \\ nil, limit \\ nil) do
     actor_id
     |> public_comments_for_actor_query()
@@ -263,7 +264,7 @@ defmodule Mobilizon.Discussions do
   @doc """
   Get all the comments contained into a discussion
   """
-  @spec get_comments_for_discussion(integer, integer | nil, integer | nil) :: Page.t()
+  @spec get_comments_for_discussion(integer, integer | nil, integer | nil) :: Page.t(Comment.t())
   def get_comments_for_discussion(discussion_id, page \\ nil, limit \\ nil) do
     Comment
     |> where([c], c.discussion_id == ^discussion_id)
@@ -326,7 +327,8 @@ defmodule Mobilizon.Discussions do
   @doc """
   Get a paginated list of discussions for a group actor
   """
-  @spec find_discussions_for_actor(Actor.t(), integer | nil, integer | nil) :: Page.t()
+  @spec find_discussions_for_actor(Actor.t(), integer | nil, integer | nil) ::
+          Page.t(Discussion.t())
   def find_discussions_for_actor(%Actor{id: actor_id}, page \\ nil, limit \\ nil) do
     Discussion
     |> where([c], c.actor_id == ^actor_id)
diff --git a/lib/mobilizon/events/events.ex b/lib/mobilizon/events/events.ex
index 6f0887f94..17fd6eac7 100644
--- a/lib/mobilizon/events/events.ex
+++ b/lib/mobilizon/events/events.ex
@@ -356,7 +356,7 @@ defmodule Mobilizon.Events do
   @doc """
   Returns the list of events.
   """
-  @spec list_events(integer | nil, integer | nil, atom, atom, boolean) :: Page.t()
+  @spec list_events(integer | nil, integer | nil, atom, atom, boolean) :: Page.t(Event.t())
   def list_events(
         page \\ nil,
         limit \\ nil,
@@ -410,7 +410,7 @@ defmodule Mobilizon.Events do
   @doc """
   Lists public events for the actor, with all associations loaded.
   """
-  @spec list_public_events_for_actor(Actor.t(), integer | nil, integer | nil) :: Page.t()
+  @spec list_public_events_for_actor(Actor.t(), integer | nil, integer | nil) :: Page.t(Event.t())
   def list_public_events_for_actor(actor, page \\ nil, limit \\ nil)
 
   def list_public_events_for_actor(%Actor{type: :Group} = group, page, limit),
@@ -521,7 +521,7 @@ defmodule Mobilizon.Events do
   @doc """
   Builds a page struct for events by their name.
   """
-  @spec build_events_for_search(map(), integer | nil, integer | nil) :: Page.t()
+  @spec build_events_for_search(map(), integer | nil, integer | nil) :: Page.t(Event.t())
   def build_events_for_search(%{term: term} = args, page \\ nil, limit \\ nil) do
     term
     |> normalize_search_string()
@@ -812,7 +812,7 @@ defmodule Mobilizon.Events do
   Default behaviour is to not return :not_approved or :not_confirmed participants
   """
   @spec list_participants_for_event(String.t(), list(atom()), integer | nil, integer | nil) ::
-          Page.t()
+          Page.t(Participant.t())
   def list_participants_for_event(
         id,
         roles \\ [],
@@ -849,7 +849,7 @@ defmodule Mobilizon.Events do
           DateTime.t() | nil,
           integer | nil,
           integer | nil
-        ) :: Page.t()
+        ) :: Page.t(Participant.t())
   def list_participations_for_user(user_id, after_datetime, before_datetime, page, limit) do
     user_id
     |> list_participations_for_user_query()
@@ -891,7 +891,8 @@ defmodule Mobilizon.Events do
   @doc """
   Returns the list of participations for an actor.
   """
-  @spec list_event_participations_for_actor(Actor.t(), integer | nil, integer | nil) :: Page.t()
+  @spec list_event_participations_for_actor(Actor.t(), integer | nil, integer | nil) ::
+          Page.t(Participant.t())
   def list_event_participations_for_actor(%Actor{id: actor_id}, page \\ nil, limit \\ nil) do
     actor_id
     |> event_participations_for_actor_query()
diff --git a/lib/mobilizon/events/tag.ex b/lib/mobilizon/events/tag.ex
index 128c2388d..a0b1e34f9 100644
--- a/lib/mobilizon/events/tag.ex
+++ b/lib/mobilizon/events/tag.ex
@@ -12,7 +12,7 @@ defmodule Mobilizon.Events.Tag do
 
   @type t :: %__MODULE__{
           title: String.t(),
-          slug: TitleSlug.Type.t(),
+          slug: String.t(),
           related_tags: [t]
         }
 
diff --git a/lib/mobilizon/instances/instance.ex b/lib/mobilizon/instances/instance.ex
index a3aceddef..82fef1279 100644
--- a/lib/mobilizon/instances/instance.ex
+++ b/lib/mobilizon/instances/instance.ex
@@ -6,6 +6,16 @@ defmodule Mobilizon.Instances.Instance do
   """
   use Ecto.Schema
 
+  @type t :: %__MODULE__{
+          event_count: non_neg_integer(),
+          person_count: non_neg_integer(),
+          group_count: non_neg_integer(),
+          followers_count: non_neg_integer(),
+          followings_count: non_neg_integer(),
+          reports_count: non_neg_integer(),
+          media_size: non_neg_integer()
+        }
+
   @primary_key {:domain, :string, []}
   schema "instances" do
     field(:event_count, :integer)
diff --git a/lib/mobilizon/medias/medias.ex b/lib/mobilizon/medias/medias.ex
index ef4d258fa..fb946e4d0 100644
--- a/lib/mobilizon/medias/medias.ex
+++ b/lib/mobilizon/medias/medias.ex
@@ -55,7 +55,7 @@ defmodule Mobilizon.Medias do
   @doc """
   List the paginated media for user
   """
-  @spec medias_for_user(integer | String.t(), integer | nil, integer | nil) :: Page.t()
+  @spec medias_for_user(integer | String.t(), integer | nil, integer | nil) :: Page.t(Media.t())
   def medias_for_user(user_id, page, limit) do
     user_id
     |> medias_for_user_query()
diff --git a/lib/mobilizon/posts/posts.ex b/lib/mobilizon/posts/posts.ex
index 28271b1e7..9bd54198f 100644
--- a/lib/mobilizon/posts/posts.ex
+++ b/lib/mobilizon/posts/posts.ex
@@ -41,14 +41,14 @@ defmodule Mobilizon.Posts do
   @doc """
   Returns the list of recent posts for a group
   """
-  @spec get_posts_for_group(Actor.t(), integer | nil, integer | nil) :: Page.t()
+  @spec get_posts_for_group(Actor.t(), integer | nil, integer | nil) :: Page.t(Post.t())
   def get_posts_for_group(%Actor{id: group_id}, page \\ nil, limit \\ nil) do
     group_id
     |> do_get_posts_for_group()
     |> Page.build_page(page, limit)
   end
 
-  @spec get_public_posts_for_group(Actor.t(), integer | nil, integer | nil) :: Page.t()
+  @spec get_public_posts_for_group(Actor.t(), integer | nil, integer | nil) :: Page.t(Post.t())
   def get_public_posts_for_group(%Actor{id: group_id}, page \\ nil, limit \\ nil) do
     group_id
     |> do_get_posts_for_group()
diff --git a/lib/mobilizon/resources/resources.ex b/lib/mobilizon/resources/resources.ex
index c83522d99..a159a3830 100644
--- a/lib/mobilizon/resources/resources.ex
+++ b/lib/mobilizon/resources/resources.ex
@@ -18,7 +18,7 @@ defmodule Mobilizon.Resources do
   @doc """
   Returns the list of recent resources for a group
   """
-  @spec get_resources_for_group(Actor.t(), integer | nil, integer | nil) :: Page.t()
+  @spec get_resources_for_group(Actor.t(), integer | nil, integer | nil) :: Page.t(Resource.t())
   def get_resources_for_group(%Actor{id: group_id}, page \\ nil, limit \\ nil) do
     Resource
     |> where(actor_id: ^group_id)
@@ -30,7 +30,8 @@ defmodule Mobilizon.Resources do
   @doc """
   Returns the list of resources for a resource folder.
   """
-  @spec get_resources_for_folder(Resource.t(), integer | nil, integer | nil) :: Page.t()
+  @spec get_resources_for_folder(Resource.t(), integer | nil, integer | nil) ::
+          Page.t(Resource.t())
   def get_resources_for_folder(resource, page \\ nil, limit \\ nil)
 
   def get_resources_for_folder(
diff --git a/lib/mobilizon/storage/repo.ex b/lib/mobilizon/storage/repo.ex
index 545b9e6c0..e57d8864a 100644
--- a/lib/mobilizon/storage/repo.ex
+++ b/lib/mobilizon/storage/repo.ex
@@ -1,7 +1,5 @@
 defmodule Mobilizon.Storage.Repo do
-  @moduledoc """
-  Mobilizon Repo.
-  """
+  @moduledoc false
 
   use Ecto.Repo,
     otp_app: :mobilizon,
diff --git a/lib/mobilizon/todos/todos.ex b/lib/mobilizon/todos/todos.ex
index 8910581bc..22cf6f1b7 100644
--- a/lib/mobilizon/todos/todos.ex
+++ b/lib/mobilizon/todos/todos.ex
@@ -22,7 +22,7 @@ defmodule Mobilizon.Todos do
   @doc """
   Returns the list of todo lists for a group.
   """
-  @spec get_todo_lists_for_group(Actor.t(), integer | nil, integer | nil) :: Page.t()
+  @spec get_todo_lists_for_group(Actor.t(), integer | nil, integer | nil) :: Page.t(TodoList.t())
   def get_todo_lists_for_group(%Actor{id: group_id, type: :Group}, page \\ nil, limit \\ nil) do
     TodoList
     |> where(actor_id: ^group_id)
@@ -34,7 +34,7 @@ defmodule Mobilizon.Todos do
   @doc """
   Returns the list of todos for a group.
   """
-  @spec get_todos_for_todo_list(TodoList.t(), integer | nil, integer | nil) :: Page.t()
+  @spec get_todos_for_todo_list(TodoList.t(), integer | nil, integer | nil) :: Page.t(Todo.t())
   def get_todos_for_todo_list(%TodoList{id: todo_list_id}, page \\ nil, limit \\ nil) do
     Todo
     |> where(todo_list_id: ^todo_list_id)
diff --git a/lib/mobilizon/users/users.ex b/lib/mobilizon/users/users.ex
index 2417f842e..a1fa208b0 100644
--- a/lib/mobilizon/users/users.ex
+++ b/lib/mobilizon/users/users.ex
@@ -358,7 +358,7 @@ defmodule Mobilizon.Users do
   Get a paginated list of all of a user's subscriptions
   """
   @spec list_user_push_subscriptions(String.t() | integer(), integer() | nil, integer() | nil) ::
-          Page.t()
+          Page.t(PushSubscription.t())
   def list_user_push_subscriptions(user_id, page \\ nil, limit \\ nil) do
     PushSubscription
     |> where([p], p.user_id == ^user_id)
diff --git a/lib/service/export/common.ex b/lib/service/export/common.ex
index 0a39b1ce6..f0dba59bb 100644
--- a/lib/service/export/common.ex
+++ b/lib/service/export/common.ex
@@ -106,7 +106,7 @@ defmodule Mobilizon.Service.Export.Common do
     actor |> fetch_identity_participations(limit) |> participations_to_events()
   end
 
-  @spec fetch_identity_participations(Actor.t(), integer()) :: Page.t()
+  @spec fetch_identity_participations(Actor.t(), integer()) :: Page.t(Participant.t())
   defp fetch_identity_participations(%Actor{} = actor, limit) do
     with %Page{} = page <- Events.list_event_participations_for_actor(actor, 1, limit) do
       page
diff --git a/lib/web/email/email.ex b/lib/web/email/email.ex
index e7adaf859..433a0134a 100644
--- a/lib/web/email/email.ex
+++ b/lib/web/email/email.ex
@@ -22,6 +22,7 @@ defmodule Mobilizon.Web.Email do
     |> put_layout({EmailView, :email})
   end
 
+  @spec add_event_attachment(Swoosh.Email.t(), Event.t()) :: Swoosh.Email.t()
   def add_event_attachment(%Swoosh.Email{} = email, %Event{id: event_id}) do
     with {:ok, %Event{} = event} <- Events.get_event_with_preload(event_id),
          {:ok, event_ics_data} <- ICalendar.export_event(event) do
diff --git a/lib/web/views/activity_pub/actor_view.ex b/lib/web/views/activity_pub/actor_view.ex
index 7f3143a52..e67e5790d 100644
--- a/lib/web/views/activity_pub/actor_view.ex
+++ b/lib/web/views/activity_pub/actor_view.ex
@@ -90,7 +90,7 @@ defmodule Mobilizon.Web.ActivityPub.ActorView do
           | :todos
           | :outbox
 
-  @spec fetch_collection(collection(), Actor.t(), integer()) :: Page.t()
+  @spec fetch_collection(collection(), Actor.t(), integer()) :: Page.t(Follower.t())
   defp fetch_collection(:following, actor, page) do
     Actors.build_followings_for_actor(actor, page)
   end