Packages

A Fair Source multi-agent runtime with deterministic agent scoring and replayable run history.

Current section

Files

Jump to
syntropy lib syntropy_web controllers api recommendation_controller.ex
Raw

lib/syntropy_web/controllers/api/recommendation_controller.ex

defmodule SyntropyWeb.Api.RecommendationController do
use SyntropyWeb, :controller
alias Syntropy.Persistence
alias SyntropyWeb.Api.{ControllerHelpers, Listing, RecommendationJSON}
@memory_scan_limit 1_000
@spec index(Plug.Conn.t(), map()) :: Plug.Conn.t()
def index(conn, params) do
case Listing.parse_opts(params, [:status, :kind, :q]) do
{:ok, opts} ->
page = recommendations_page(opts)
json(conn, %{
data: Enum.map(page.entries, &RecommendationJSON.recommendation/1),
meta: Listing.meta(page)
})
{:error, :invalid_cursor} ->
ControllerHelpers.invalid_request(conn, "Invalid cursor.", [])
end
end
@spec show(Plug.Conn.t(), map()) :: Plug.Conn.t()
def show(conn, %{"id" => recommendation_id}) do
case Syntropy.recommendation(recommendation_id) ||
Persistence.get_recommendation(recommendation_id) do
nil -> ControllerHelpers.not_found(conn, "Recommendation", recommendation_id)
recommendation -> json(conn, %{data: RecommendationJSON.recommendation(recommendation)})
end
end
@spec approve(Plug.Conn.t(), map()) :: Plug.Conn.t()
def approve(conn, %{"id" => recommendation_id}) do
recommendation_id
|> Syntropy.approve_recommendation()
|> mutation_response(conn, recommendation_id)
end
@spec reject(Plug.Conn.t(), map()) :: Plug.Conn.t()
def reject(conn, %{"id" => recommendation_id}) do
recommendation_id
|> Syntropy.reject_recommendation()
|> mutation_response(conn, recommendation_id)
end
defp recommendations_page(opts) do
if Persistence.enabled?() do
Persistence.list_recommendations(opts)
else
@memory_scan_limit
|> Syntropy.recent_recommendations()
|> Listing.filter_recommendations(opts)
|> Listing.paginate(opts, :created_at)
end
end
defp mutation_response(result, conn, recommendation_id) do
case result do
{:ok, recommendation} ->
json(conn, %{data: RecommendationJSON.recommendation(recommendation)})
{:error, :not_found} ->
ControllerHelpers.not_found(conn, "Recommendation", recommendation_id)
{:error, {:invalid_status, status}} ->
ControllerHelpers.conflict(
conn,
"invalid_status",
"Recommendation #{recommendation_id} is #{status} and can no longer change."
)
{:error, _reason} ->
ControllerHelpers.conflict(
conn,
"recommendation_not_applied",
"Recommendation #{recommendation_id} could not be applied."
)
end
end
end