analytics/lib/plausible_web/plugins/api/controllers/shared_links.ex
hq1 0007c0c108
Plugins API: 2nd pass with Goals resource + SharedLinks schema changes (#3396)
* Remove "Context" namespace level

* Change Goal string representation

* Alias Schemas in Plugin API Test Case template

* Update schema & tests for SharedLink resource

* Update Goals interface

- make it possible to create revenue goals
- extract "for site" query to a standalone function

* Fixup typespecs

* Alias Errors module in OpenAPI controllers

* Add missing goals test

* Implement Goals Plugins API resource

* Add extra test to confirm changeset error propagation

* Mute credo

* Fix typos

* Handle changeset traversal in `Errors`

* Use upserts in `Goals.find_or_create`

* Extract touch_site! to Site.Cache, address credo, improve code docs

* Apply formatting

* Remove unused inner join

* Update test/plausible_web/plugins/api/controllers/goals_test.exs

Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>

* Update test/plausible_web/plugins/api/controllers/goals_test.exs

Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>

* Update test/plausible_web/plugins/api/controllers/goals_test.exs

Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>

* Update test/plausible_web/plugins/api/controllers/goals_test.exs

Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>

* Update test/plausible_web/plugins/api/controllers/goals_test.exs

Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>

* Update error message on revenue goal currency clash

* Remove unused code

---------

Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
2023-10-05 11:54:18 +02:00

112 lines
3.4 KiB
Elixir

defmodule PlausibleWeb.Plugins.API.Controllers.SharedLinks do
@moduledoc """
Controller for the Shared Link resource under Plugins API
"""
use PlausibleWeb, :plugins_api_controller
operation(:index,
summary: "Retrieve Shared Links",
parameters: [
limit: [in: :query, type: :integer, description: "Maximum entries per page", example: 10],
after: [
in: :query,
type: :string,
description: "Cursor value to seek after - generated internally"
],
before: [
in: :query,
type: :string,
description: "Cursor value to seek before - generated internally"
]
],
responses: %{
ok: {"Shared Links response", "application/json", Schemas.SharedLink.ListResponse},
unauthorized: {"Unauthorized", "application/json", Schemas.Unauthorized}
}
)
@spec index(Plug.Conn.t(), %{}) :: Plug.Conn.t()
def index(conn, _params) do
{:ok, pagination} =
API.SharedLinks.get_shared_links(conn.assigns.authorized_site, conn.query_params)
conn
|> put_view(Views.SharedLink)
|> render("index.json", %{pagination: pagination})
end
operation(:create,
summary: "Get or create Shared Link",
request_body: {"Shared Link params", "application/json", Schemas.SharedLink.CreateRequest},
responses: %{
created: {"Shared Link", "application/json", Schemas.SharedLink},
unauthorized: {"Unauthorized", "application/json", Schemas.Unauthorized},
unprocessable_entity:
{"Unprocessable entity", "application/json", Schemas.UnprocessableEntity}
}
)
@spec create(Plug.Conn.t(), map()) :: Plug.Conn.t()
def create(
%{
private: %{
open_api_spex: %{
body_params: %Schemas.SharedLink.CreateRequest{
shared_link: %{name: name} = shared_link
}
}
}
} = conn,
_params
) do
site = conn.assigns.authorized_site
{:ok, shared_link} = API.SharedLinks.get_or_create(site, name, shared_link[:password])
conn
|> put_view(Views.SharedLink)
|> put_status(:created)
|> put_resp_header("location", shared_links_url(base_uri(), :get, shared_link.id))
|> render("shared_link.json", shared_link: shared_link, authorized_site: site)
end
operation(:get,
summary: "Retrieve Shared Link by ID",
parameters: [
id: [
in: :path,
type: :integer,
description: "Shared Link ID",
example: 123,
required: true
]
],
responses: %{
created: {"Shared Link", "application/json", Schemas.SharedLink},
not_found: {"NotFound", "application/json", Schemas.NotFound},
unauthorized: {"Unauthorized", "application/json", Schemas.Unauthorized},
unprocessable_entity:
{"Unprocessable entity", "application/json", Schemas.UnprocessableEntity}
}
)
@spec get(Plug.Conn.t(), map()) :: Plug.Conn.t()
def get(%{private: %{open_api_spex: %{params: %{id: id}}}} = conn, _params) do
site = conn.assigns.authorized_site
case API.SharedLinks.get(site, id) do
nil ->
conn
|> put_view(Views.Error)
|> put_status(:not_found)
|> render("404.json")
shared_link ->
conn
|> put_view(Views.SharedLink)
|> put_status(:ok)
|> render("shared_link.json", shared_link: shared_link, authorized_site: site)
end
end
end