From c744c362c85dbd472541c5102f373730c1893ec1 Mon Sep 17 00:00:00 2001 From: buttercat1791 Date: Mon, 9 Mar 2026 22:23:27 -0500 Subject: [PATCH 1/6] Add Credo to deps --- mix.exs | 3 ++- mix.lock | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/mix.exs b/mix.exs index c8ad929..e211f23 100644 --- a/mix.exs +++ b/mix.exs @@ -62,7 +62,8 @@ defmodule GcIndexRelay.MixProject do {:dns_cluster, "~> 0.2.0"}, {:bandit, "~> 1.5"}, {:lib_secp256k1, "~> 0.7.1"}, - {:phoenix_swagger, "~> 0.8"} + {:phoenix_swagger, "~> 0.8"}, + {:credo, "~> 1.7", only: [:dev, :test], runtime: false} ] end diff --git a/mix.lock b/mix.lock index 317d2b3..e7fbfd1 100644 --- a/mix.lock +++ b/mix.lock @@ -1,6 +1,8 @@ %{ "bandit": {:hex, :bandit, "1.10.1", "6b1f8609d947ae2a74da5bba8aee938c94348634e54e5625eef622ca0bbbb062", [:mix], [{:hpax, "~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}, {:plug, "~> 1.18", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:thousand_island, "~> 1.0", [hex: :thousand_island, repo: "hexpm", optional: false]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "4b4c35f273030e44268ace53bf3d5991dfc385c77374244e2f960876547671aa"}, + "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, "cc_precompiler": {:hex, :cc_precompiler, "0.1.11", "8c844d0b9fb98a3edea067f94f616b3f6b29b959b6b3bf25fee94ffe34364768", [:mix], [{:elixir_make, "~> 0.7", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "3427232caf0835f94680e5bcf082408a70b48ad68a5f5c0b02a3bea9f3a075b9"}, + "credo": {:hex, :credo, "1.7.17", "f92b6aa5b26301eaa5a35e4d48ebf5aa1e7094ac00ae38f87086c562caf8a22f", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "1eb5645c835f0b6c9b5410f94b5a185057bcf6d62a9c2b476da971cde8749645"}, "db_connection": {:hex, :db_connection, "2.9.0", "a6a97c5c958a2d7091a58a9be40caf41ab496b0701d21e1d1abff3fa27a7f371", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "17d502eacaf61829db98facf6f20808ed33da6ccf495354a41e64fe42f9c509c"}, "decimal": {:hex, :decimal, "2.3.0", "3ad6255aa77b4a3c4f818171b12d237500e63525c2fd056699967a3e7ea20f62", [:mix], [], "hexpm", "a4d66355cb29cb47c3cf30e71329e58361cfcb37c34235ef3bf1d7bf3773aeac"}, "dns_cluster": {:hex, :dns_cluster, "0.2.0", "aa8eb46e3bd0326bd67b84790c561733b25c5ba2fe3c7e36f28e88f384ebcb33", [:mix], [], "hexpm", "ba6f1893411c69c01b9e8e8f772062535a4cf70f3f35bcc964a324078d8c8240"}, From 309e9ce318d54545e4d4d52b72d2778e15d7807e Mon Sep 17 00:00:00 2001 From: buttercat1791 Date: Mon, 9 Mar 2026 22:29:45 -0500 Subject: [PATCH 2/6] Fix Credo readability issues --- lib/gc_index_relay/nostr.ex | 10 ++++++---- lib/gc_index_relay/nostr/event.ex | 2 +- lib/gc_index_relay/nostr/filter.ex | 5 +++++ test/gc_index_relay/nostr/pub_event_test.exs | 4 ++-- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/lib/gc_index_relay/nostr.ex b/lib/gc_index_relay/nostr.ex index b5beb2c..3cea006 100644 --- a/lib/gc_index_relay/nostr.ex +++ b/lib/gc_index_relay/nostr.ex @@ -73,10 +73,12 @@ defmodule GcIndexRelay.Nostr do """ @spec delete_event(PubEvent.t()) :: {:ok, Ecto.Schema.t()} | {:error, Ecto.Changeset.t()} def delete_event(event) when is_struct(event, PubEvent) do - with {:ok, binary_id} <- Base.decode16(event.id, case: :lower) do - Repo.delete(%Event{id: binary_id}) - else - _ -> {:error, :not_found} + case Base.decode16(event.id, case: :lower) do + {:ok, binary_id} -> + Repo.delete(%Event{id: binary_id}) + + _ -> + {:error, :not_found} end end end diff --git a/lib/gc_index_relay/nostr/event.ex b/lib/gc_index_relay/nostr/event.ex index 0193451..7a590fa 100644 --- a/lib/gc_index_relay/nostr/event.ex +++ b/lib/gc_index_relay/nostr/event.ex @@ -36,7 +36,7 @@ defmodule GcIndexRelay.Nostr.Event do |> cast_assoc(:tags, with: &Tag.changeset/2) |> validate_required([:id, :pubkey, :created_at, :kind, :sig]) |> validate_number(:kind, greater_than_or_equal_to: 0) - |> validate_number(:kind, less_than: 40000) + |> validate_number(:kind, less_than: 40_000) |> unique_constraint(:id, name: :events_pkey) end end diff --git a/lib/gc_index_relay/nostr/filter.ex b/lib/gc_index_relay/nostr/filter.ex index e64e7ed..4815f7b 100644 --- a/lib/gc_index_relay/nostr/filter.ex +++ b/lib/gc_index_relay/nostr/filter.ex @@ -1,4 +1,9 @@ defmodule GcIndexRelay.Nostr.Filter do + @moduledoc """ + An implementation of Nostr filters, including a struct representation and parsing and validation + functions. + """ + alias GcIndexRelay.Nostr.Event alias GcIndexRelay.Repo alias GcIndexRelay.Nostr.Tag diff --git a/test/gc_index_relay/nostr/pub_event_test.exs b/test/gc_index_relay/nostr/pub_event_test.exs index 8b10cc2..0bd18f8 100644 --- a/test/gc_index_relay/nostr/pub_event_test.exs +++ b/test/gc_index_relay/nostr/pub_event_test.exs @@ -65,14 +65,14 @@ defmodule GcIndexRelay.Nostr.PubEventTest do id: Base.decode16!(String.duplicate("ab", 32), case: :lower), pubkey: Base.decode16!(String.duplicate("cd", 32), case: :lower), created_at: ~U[2021-12-20 17:46:40Z], - kind: 30023, + kind: 30_023, content: "long-form content", sig: Base.decode16!(String.duplicate("ef", 64), case: :lower), tags: [] } assert {:ok, pub_event} = PubEvent.from_db(event) - assert pub_event.kind == 30023 + assert pub_event.kind == 30_023 assert pub_event.content == "long-form content" end From d3f6d88380861964a940f8eb46f826502c42a6d8 Mon Sep 17 00:00:00 2001 From: buttercat1791 Date: Mon, 9 Mar 2026 22:41:01 -0500 Subject: [PATCH 3/6] Follow Credo refactor recommendations --- .../controllers/filter_controller.ex | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/lib/gc_index_relay_web/controllers/filter_controller.ex b/lib/gc_index_relay_web/controllers/filter_controller.ex index a6a79bc..781717a 100644 --- a/lib/gc_index_relay_web/controllers/filter_controller.ex +++ b/lib/gc_index_relay_web/controllers/filter_controller.ex @@ -74,10 +74,10 @@ defmodule GcIndexRelayWeb.FilterController do @spec validate_required_params(map()) :: {:ok, map()} | {:error, String.t()} def validate_required_params(params) do - if not Map.has_key?(params, "limit") do - {:error, "The filter must specify a limit."} - else + if Map.has_key?(params, "limit") do {:ok, params} + else + {:error, "The filter must specify a limit."} end end @@ -141,11 +141,7 @@ defmodule GcIndexRelayWeb.FilterController do |> Enum.reduce_while({:ok, %{}}, fn {key, value}, {:ok, acc} -> case parse_param(key, value) do {:ok, parsed_value} -> - out_key = - if byte_size(key) == 1 and - ((key >= "a" and key <= "z") or (key >= "A" and key <= "Z")), - do: "#" <> key, - else: key + out_key = parse_tag(key) {:cont, {:ok, Map.put(acc, out_key, parsed_value)}} @@ -155,6 +151,16 @@ defmodule GcIndexRelayWeb.FilterController do end) end + # Parse filter keys that represent tags. Note that only single-letter keys are treated as tags; + # all other keys are passed through unchanged. + @spec parse_tag(String.t()) :: String.t() + defp parse_tag(key) do + if byte_size(key) == 1 and + ((key >= "a" and key <= "z") or (key >= "A" and key <= "Z")), + do: "#" <> key, + else: key + end + # Parse individual parameter based on its key @spec parse_param(String.t(), String.t()) :: {:ok, any()} | {:error, String.t()} defp parse_param("ids", value), do: {:ok, String.split(value, ",")} From aa7314b193a7841f4fcbf59200f4050a4b4e3c05 Mon Sep 17 00:00:00 2001 From: buttercat1791 Date: Mon, 9 Mar 2026 22:43:14 -0500 Subject: [PATCH 4/6] Fix Credo warning --- test/gc_index_relay_web/controllers/filter_controller_test.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/gc_index_relay_web/controllers/filter_controller_test.exs b/test/gc_index_relay_web/controllers/filter_controller_test.exs index d20130e..8b66944 100644 --- a/test/gc_index_relay_web/controllers/filter_controller_test.exs +++ b/test/gc_index_relay_web/controllers/filter_controller_test.exs @@ -145,7 +145,7 @@ defmodule GcIndexRelayWeb.FilterControllerTest do conn = post(conn, ~p"/api/events/filter", %{"limit" => 10}) assert %{"data" => events} = json_response(conn, 200) - assert length(events) >= 1 + assert not Enum.empty?(events) assert length(events) <= 10 end From f0041a582238e158d170d00f68d8a28e89a8e975 Mon Sep 17 00:00:00 2001 From: buttercat1791 Date: Mon, 9 Mar 2026 23:34:50 -0500 Subject: [PATCH 5/6] Fix unit test config --- config/config.exs | 1 - config/runtime.exs | 2 +- config/test.exs | 5 ++++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/config/config.exs b/config/config.exs index 3b6757a..fe07fa4 100644 --- a/config/config.exs +++ b/config/config.exs @@ -11,7 +11,6 @@ config :gc_index_relay, ecto_repos: [GcIndexRelay.Repo], generators: [timestamp_type: :utc_datetime] - # Configure the endpoint config :gc_index_relay, GcIndexRelayWeb.Endpoint, url: [host: "localhost"], diff --git a/config/runtime.exs b/config/runtime.exs index 7cfcba9..f38c3cb 100644 --- a/config/runtime.exs +++ b/config/runtime.exs @@ -24,7 +24,7 @@ config :gc_index_relay, GcIndexRelayWeb.Endpoint, http: [port: String.to_integer(System.get_env("PORT", "4000"))] config :gc_index_relay, GcIndexRelay.Repo, - hostname: System.get_env("POSTGRES_HOST"), + hostname: System.get_env("POSTGRES_HOST") || "localhost", port: String.to_integer(System.get_env("POSTGRES_PORT") || "5432"), username: System.get_env("POSTGRES_USER"), password: System.get_env("POSTGRES_PASSWORD"), diff --git a/config/test.exs b/config/test.exs index 6e8d5ce..8c5450e 100644 --- a/config/test.exs +++ b/config/test.exs @@ -1,6 +1,6 @@ import Config -config :gc_index_relay, :start_repo, true +config :gc_index_relay, :start_repo, System.get_env("REQUIRE_DB") == "true" # Configure your database # @@ -11,6 +11,9 @@ config :gc_index_relay, GcIndexRelay.Repo, username: System.get_env("POSTGRES_USER"), password: System.get_env("POSTGRES_PASSWORD"), database: "#{System.get_env("POSTGRES_DB")}#{System.get_env("MIX_TEST_PARTITION")}", + hostname: "localhost", + port: 5432, + show_sensitive_data_on_connection_error: true, pool: Ecto.Adapters.SQL.Sandbox, pool_size: System.schedulers_online() * 2 From a001d4168e46789f2abf05d7ae8a9e2039eb20a5 Mon Sep 17 00:00:00 2001 From: buttercat1791 Date: Mon, 9 Mar 2026 23:34:58 -0500 Subject: [PATCH 6/6] Update precommit task with Credo --- mix.exs | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/mix.exs b/mix.exs index e211f23..ba31d74 100644 --- a/mix.exs +++ b/mix.exs @@ -78,7 +78,6 @@ defmodule GcIndexRelay.MixProject do setup: ["deps.get", "ecto.setup"], "ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"], "ecto.reset": ["ecto.drop", "ecto.setup"], - test: test_alias(), "test.unit": ["test --only unit"], "test.integration": [ "ecto.create --quiet", @@ -89,19 +88,9 @@ defmodule GcIndexRelay.MixProject do "compile --warnings-as-errors", "deps.unlock --unused", "format", - "test.integration" + "credo", + "test.unit" ] ] end - - # Conditionally set up database for tests - # Set REQUIRE_DB=true to run database migrations before tests - # Or use mix test.integration for integration tests with database - defp test_alias do - if System.get_env("REQUIRE_DB") == "true" do - ["test.integration"] - else - ["test"] - end - end end