Skip to content

Commit

Permalink
Extend project table and API with hidden info
Browse files Browse the repository at this point in the history
Add hidden_since and hidden_reason to the database and the API
Add includeHidden: true flag to the allProjects API
  • Loading branch information
IvanIvanoff committed Aug 13, 2024
1 parent 6d09913 commit ed31d7b
Show file tree
Hide file tree
Showing 8 changed files with 186 additions and 2 deletions.
4 changes: 3 additions & 1 deletion lib/sanbase/project/list/selector/project_list_selector.ex
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ defmodule Sanbase.Project.ListSelector do
order_by = Transform.args_to_order_by(args)
pagination = Transform.args_to_pagination(args)
filters_combinator = Transform.args_to_filters_combinator(args)
include_hidden = Map.get(args, :include_hidden, false)

base_slugs = base_slugs(base_projects_selector)

Expand All @@ -105,7 +106,8 @@ defmodule Sanbase.Project.ListSelector do
pagination: pagination,
min_volume: Map.get(args, :min_volume),
included_slugs: included_slugs,
ordered_slugs: ordered_slugs
ordered_slugs: ordered_slugs,
include_hidden: include_hidden
]

{:ok, opts}
Expand Down
20 changes: 20 additions & 0 deletions lib/sanbase/project/project.ex
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ defmodule Sanbase.Project do
field(:slug, :string)
field(:coinmarketcap_id, :string)
field(:is_hidden, :boolean, default: false)
field(:hidden_since, :utc_datetime)
field(:hidden_reason, :string)

field(:description, :string)
field(:long_description, :string)
Expand Down Expand Up @@ -123,6 +125,8 @@ defmodule Sanbase.Project do
:github_link,
:infrastructure_id,
:is_hidden,
:hidden_since,
:hidden_reason,
:linkedin_link,
:logo_url,
:long_description,
Expand All @@ -149,6 +153,22 @@ defmodule Sanbase.Project do
|> cast_assoc(:market_segments)
|> cast_assoc(:ecosystems)
|> unique_constraint(:slug)
|> maybe_add_hidden_since()
end

defp maybe_add_hidden_since(changeset) do
case changeset.changes do
%{is_hidden: true} ->
changeset
|> put_change(:hidden_since, DateTime.utc_now() |> DateTime.truncate(:second))

%{is_hiden: false} ->
changeset
|> put_change(:hidden_since, nil)

_ ->
changeset
end
end

defdelegate roi_usd(project), to: Project.Roi
Expand Down
2 changes: 2 additions & 0 deletions lib/sanbase_web/generic_admin/project.ex
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ defmodule SanbaseWeb.GenericAdmin.Project do
:infrastructure,
:token_decimals,
:is_hidden,
:hidden_reason,
:telegram_chat_id,
:logo_url,
:dark_logo_url,
Expand Down Expand Up @@ -61,6 +62,7 @@ defmodule SanbaseWeb.GenericAdmin.Project do
:infrastructure,
:token_decimals,
:is_hidden,
:hidden_reason,
:telegram_chat_id,
:logo_url,
:dark_logo_url,
Expand Down
2 changes: 2 additions & 0 deletions lib/sanbase_web/graphql/schema/queries/project_queries.ex
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ defmodule SanbaseWeb.Graphql.Schema.ProjectQueries do
arg(:page_size, :integer)
arg(:min_volume, :integer)

arg(:include_hidden, :boolean, default_value: false)

middleware(ProjectPermissions)
cache_resolve(&ProjectListResolver.all_projects/3)
end
Expand Down
26 changes: 26 additions & 0 deletions lib/sanbase_web/graphql/schema/types/project_types.ex
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,32 @@ defmodule SanbaseWeb.Graphql.ProjectTypes do
field(:long_description, :string)
field(:token_decimals, :integer)

@desc ~s"""
Shows if a project is marked as hidden.
Hidden projects are excluded from lists of projects
like allProjects and screeners that are filtered by a condition.
Hidden projects can be accessed when directly queried via project or projectBySlug,
or by passing the `includeHiddenProjects: true` flag to `allProjects`.
"""
field(:is_hidden, non_null(:boolean))

@desc ~s"""
If the project is hidden, this field shows the datetime since which the project
is hidden.
Not all hidden projects have a hidden_since field. The projects that are hidden
before August 2024 don't have their hidden_since stored.
"""
field(:hidden_since, :datetime)

@desc ~s"""
If the project is hidden, this field can contain the reason why the project is
hidden.
"""
field(:hidden_reason, :string)

@desc ~s"""
A full list of all the ecosystem this project contributes to
in one or more ways:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
defmodule Sanbase.Repo.Migrations.ExtendProjectsTableHiddenInfo do
use Ecto.Migration

def change do
alter table(:project) do
add(:hidden_since, :utc_datetime)
add(:hidden_reason, :text)
end
end
end
5 changes: 4 additions & 1 deletion priv/repo/structure.sql
Original file line number Diff line number Diff line change
Expand Up @@ -2902,7 +2902,9 @@ CREATE TABLE public.project (
ecosystem character varying(255),
ecosystem_full_path character varying(255),
multichain_project_group_key character varying(255) DEFAULT NULL::character varying,
deployed_on_ecosystem_id bigint
deployed_on_ecosystem_id bigint,
hidden_since timestamp(0) without time zone,
hidden_reason text
);


Expand Down Expand Up @@ -9559,3 +9561,4 @@ INSERT INTO public."schema_migrations" (version) VALUES (20240531121027);
INSERT INTO public."schema_migrations" (version) VALUES (20240723122118);
INSERT INTO public."schema_migrations" (version) VALUES (20240725122924);
INSERT INTO public."schema_migrations" (version) VALUES (20240805115620);
INSERT INTO public."schema_migrations" (version) VALUES (20240809122904);
119 changes: 119 additions & 0 deletions test/sanbase_web/graphql/projects/project_hidden_api_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
defmodule SanbaseWeb.Graphql.ProjectHiddenApiTest do
use SanbaseWeb.ConnCase, async: false

import Sanbase.Factory
import SanbaseWeb.Graphql.TestHelpers

test "all projects", %{conn: conn} do
p1 = insert(:random_erc20_project)
p2 = insert(:random_erc20_project)
p3 = insert(:random_erc20_project, is_hidden: true)

# Without includeHidden flag.
projects = all_projects(conn)
assert length(projects) == 2

slugs = projects |> Enum.map(& &1["slug"])

assert p1.slug in slugs
assert p2.slug in slugs
refute p3.slug in slugs

# With includeHidden: true flag
projects = all_projects_including_hidden(conn)
assert length(projects) == 3

slugs = projects |> Enum.map(& &1["slug"])
assert p1.slug in slugs
assert p2.slug in slugs
assert p3.slug in slugs
end

test "project by slug", %{conn: conn} do
p1 = insert(:random_erc20_project)
p2 = insert(:random_erc20_project)

assert {:ok, _} =
Sanbase.Project.changeset(p2, %{is_hidden: true, hidden_reason: "duplicate"})
|> Sanbase.Repo.update()

# not a hidden project
project = project_by_slug(conn, %{slug: p1.slug})

assert project == %{
"hiddenReason" => nil,
"hiddenSince" => nil,
"isHidden" => false,
"slug" => p1.slug
}

# hidden project
project = project_by_slug(conn, %{slug: p2.slug})

assert %{
"hiddenReason" => "duplicate",
"hiddenSince" => dt,
"isHidden" => true,
"slug" => slug
} = project

assert slug == p2.slug

assert Sanbase.TestUtils.datetime_close_to(
DateTime.utc_now(),
Sanbase.DateTimeUtils.from_iso8601!(dt),
1,
:seconds
)
end

defp project_by_slug(conn, args) do
query = """
{
projectBySlug(#{map_to_args(args)}){
slug
isHidden
hiddenSince
hiddenReason
}
}
"""

conn
|> post("/graphql", query_skeleton(query))
|> json_response(200)
|> get_in(["data", "projectBySlug"])
end

defp all_projects(conn) do
query = """
{
allProjects{
slug
isHidden
}
}
"""

conn
|> post("/graphql", query_skeleton(query))
|> json_response(200)
|> get_in(["data", "allProjects"])
end

defp all_projects_including_hidden(conn) do
query = """
{
allProjects(includeHidden: true){
slug
isHidden
}
}
"""

conn
|> post("/graphql", query_skeleton(query))
|> json_response(200)
|> get_in(["data", "allProjects"])
end
end

0 comments on commit ed31d7b

Please sign in to comment.