From 6fc402ca1678082d749e3810eedcbda0b08987b8 Mon Sep 17 00:00:00 2001 From: neo773 Date: Thu, 17 Jul 2025 22:38:27 +0530 Subject: [PATCH 1/4] feat: add profile json route --- .../controllers/api/user_controller.ex | 91 +++++++++++++++++++ lib/algora_web/router.ex | 1 + 2 files changed, 92 insertions(+) create mode 100644 lib/algora_web/controllers/api/user_controller.ex diff --git a/lib/algora_web/controllers/api/user_controller.ex b/lib/algora_web/controllers/api/user_controller.ex new file mode 100644 index 000000000..b7cd94d9e --- /dev/null +++ b/lib/algora_web/controllers/api/user_controller.ex @@ -0,0 +1,91 @@ +defmodule AlgoraWeb.API.UserController do + use AlgoraWeb, :controller + + alias Algora.Accounts + alias Algora.Payments + alias Algora.Reviews + alias Algora.Workspace + + def show(conn, %{"user_handle" => handle}) do + with {:ok, user} <- Accounts.fetch_developer_by(handle: handle) do + transactions = Payments.list_received_transactions(user.id, limit: 10) + enriched_transactions = enrich_transactions(transactions) + + reviews = Reviews.list_reviews(reviewee_id: user.id, limit: 10) + + contributions = Workspace.list_user_contributions([user.id], limit: 20, display_all: true) + + json(conn, %{ + id: user.id, + name: user.name, + handle: user.handle, + bio: user.bio, + + contributions: Enum.map(contributions, &contribution_to_json/1), + total_stars: total_stars(contributions), + total_contributions: total_contributions(contributions), + + transactions: Enum.map(enriched_transactions, &transaction_to_json/1), + reviews: Enum.map(reviews, &review_to_json/1) + }) + else + _ -> + send_resp(conn, 404, Jason.encode!(%{error: "User not found"})) + end + end + + defp enrich_transactions(transactions) do + Enum.map(transactions, fn tx -> + project = + case tx.ticket.repository do + nil -> tx.sender + repo -> repo.user + end + + Map.put(tx, :project, project) + end) + end + + defp transaction_to_json(tx) do + %{ + id: tx.id, + amount: tx.amount, + succeeded_at: tx.succeeded_at, + sender: tx.sender, + project: tx.project + } + end + + defp review_to_json(review) do + %{ + id: review.id, + reviewer_id: review.reviewer_id, + body: review.body, + inserted_at: review.inserted_at + } + end + + defp contribution_to_json(contribution) do + %{ + repository: %{ + id: contribution.repository.id, + name: contribution.repository.name, + stargazers_count: contribution.repository.stargazers_count, + user: contribution.repository.user + }, + contribution_count: contribution.contribution_count + } + end + + defp total_stars(contributions) do + contributions + |> Enum.map(& &1.repository.stargazers_count) + |> Enum.sum() + end + + defp total_contributions(contributions) do + contributions + |> Enum.map(& &1.contribution_count) + |> Enum.sum() + end +end diff --git a/lib/algora_web/router.ex b/lib/algora_web/router.ex index 3a42f8a2a..2800c8d96 100644 --- a/lib/algora_web/router.ex +++ b/lib/algora_web/router.ex @@ -138,6 +138,7 @@ defmodule AlgoraWeb.Router do scope "/api", AlgoraWeb.API do pipe_through :api post "/store_session", StoreSessionController, :create + get "/profile/:user_handle", UserController, :show # Legacy tRPC endpoints scope "/trpc" do From 15ec361b6c9401f6d80f6dfcdfead62607ccc161 Mon Sep 17 00:00:00 2001 From: neo773 Date: Thu, 17 Jul 2025 22:41:53 +0530 Subject: [PATCH 2/4] chore: rename to ProfileController --- .../api/{user_controller.ex => profile_controller.ex} | 2 +- lib/algora_web/router.ex | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename lib/algora_web/controllers/api/{user_controller.ex => profile_controller.ex} (98%) diff --git a/lib/algora_web/controllers/api/user_controller.ex b/lib/algora_web/controllers/api/profile_controller.ex similarity index 98% rename from lib/algora_web/controllers/api/user_controller.ex rename to lib/algora_web/controllers/api/profile_controller.ex index b7cd94d9e..ddcd31038 100644 --- a/lib/algora_web/controllers/api/user_controller.ex +++ b/lib/algora_web/controllers/api/profile_controller.ex @@ -1,4 +1,4 @@ -defmodule AlgoraWeb.API.UserController do +defmodule AlgoraWeb.API.ProfileController do use AlgoraWeb, :controller alias Algora.Accounts diff --git a/lib/algora_web/router.ex b/lib/algora_web/router.ex index 2800c8d96..53a8577d9 100644 --- a/lib/algora_web/router.ex +++ b/lib/algora_web/router.ex @@ -138,7 +138,7 @@ defmodule AlgoraWeb.Router do scope "/api", AlgoraWeb.API do pipe_through :api post "/store_session", StoreSessionController, :create - get "/profile/:user_handle", UserController, :show + get "/profile/:user_handle", ProfileController, :show # Legacy tRPC endpoints scope "/trpc" do From 0abe123c5c25df684a360d007d48268028a15013 Mon Sep 17 00:00:00 2001 From: neo773 Date: Thu, 17 Jul 2025 22:46:52 +0530 Subject: [PATCH 3/4] make limit configurable --- .../controllers/api/profile_controller.ex | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/lib/algora_web/controllers/api/profile_controller.ex b/lib/algora_web/controllers/api/profile_controller.ex index ddcd31038..5cf6065ba 100644 --- a/lib/algora_web/controllers/api/profile_controller.ex +++ b/lib/algora_web/controllers/api/profile_controller.ex @@ -6,14 +6,14 @@ defmodule AlgoraWeb.API.ProfileController do alias Algora.Reviews alias Algora.Workspace - def show(conn, %{"user_handle" => handle}) do + def show(conn, %{"user_handle" => handle} = params) do + limit = parse_limit(params["limit"]) + with {:ok, user} <- Accounts.fetch_developer_by(handle: handle) do - transactions = Payments.list_received_transactions(user.id, limit: 10) + transactions = Payments.list_received_transactions(user.id, limit: limit) enriched_transactions = enrich_transactions(transactions) - - reviews = Reviews.list_reviews(reviewee_id: user.id, limit: 10) - - contributions = Workspace.list_user_contributions([user.id], limit: 20, display_all: true) + reviews = Reviews.list_reviews(reviewee_id: user.id, limit: limit) + contributions = Workspace.list_user_contributions([user.id], limit: limit, display_all: true) json(conn, %{ id: user.id, @@ -34,6 +34,15 @@ defmodule AlgoraWeb.API.ProfileController do end end + defp parse_limit(limit) when is_binary(limit) do + case Integer.parse(limit) do + {num, _} when num > 0 and num <= 100 -> num + _ -> 10 + end + end + + defp parse_limit(_), do: 10 + defp enrich_transactions(transactions) do Enum.map(transactions, fn tx -> project = From 27a7aa896a28859f82d2156ca95e03ea22b876f1 Mon Sep 17 00:00:00 2001 From: neo773 Date: Thu, 17 Jul 2025 22:49:32 +0530 Subject: [PATCH 4/4] update max limit --- lib/algora_web/controllers/api/profile_controller.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/algora_web/controllers/api/profile_controller.ex b/lib/algora_web/controllers/api/profile_controller.ex index 5cf6065ba..7cde1e440 100644 --- a/lib/algora_web/controllers/api/profile_controller.ex +++ b/lib/algora_web/controllers/api/profile_controller.ex @@ -36,7 +36,7 @@ defmodule AlgoraWeb.API.ProfileController do defp parse_limit(limit) when is_binary(limit) do case Integer.parse(limit) do - {num, _} when num > 0 and num <= 100 -> num + {num, _} when num > 0 and num <= 1000 -> num _ -> 10 end end