defmodule Localiser.Web.Controllers.FloorController do use Phoenix.Controller, formats: [:json] use OpenApiSpex.ControllerSpecs alias Localiser.Domain.Floors alias Localiser.Web.Schemas tags ["Floors"] security [%{"bearerAuth" => []}] operation :index, summary: "List all floors", responses: [ ok: {"Floor list", "application/json", %OpenApiSpex.Schema{type: :array, items: Schemas.Floor}}, unauthorized: {"Unauthorized", "application/json", Schemas.Error} ] operation :show, summary: "Get a floor", parameters: [id: [in: :path, type: :integer, required: true]], responses: [ ok: {"Floor", "application/json", Schemas.Floor}, unauthorized: {"Unauthorized", "application/json", Schemas.Error} ] operation :create, summary: "Create a floor", request_body: {"Floor params", "application/json", Schemas.FloorParams, required: true}, responses: [ created: {"Created floor", "application/json", Schemas.Floor}, unauthorized: {"Unauthorized", "application/json", Schemas.Error}, unprocessable_entity: {"Validation errors", "application/json", Schemas.ValidationErrors} ] operation :update, summary: "Update a floor", parameters: [id: [in: :path, type: :integer, required: true]], request_body: {"Floor params", "application/json", Schemas.FloorUpdateParams}, responses: [ ok: {"Updated floor", "application/json", Schemas.Floor}, unauthorized: {"Unauthorized", "application/json", Schemas.Error}, unprocessable_entity: {"Validation errors", "application/json", Schemas.ValidationErrors} ] operation :delete, summary: "Delete a floor (also deletes all rooms and unenrols sensors)", parameters: [id: [in: :path, type: :integer, required: true]], responses: [ no_content: "Deleted", unauthorized: {"Unauthorized", "application/json", Schemas.Error} ] def index(conn, _params) do json(conn, Enum.map(Floors.list_floors(), &render_floor/1)) end def show(conn, %{"id" => id}) do floor = Floors.get_floor!(id) json(conn, render_floor(floor)) end def create(conn, params) do case Floors.create_floor(params) do {:ok, floor} -> conn |> put_status(:created) |> json(render_floor(floor)) {:error, changeset} -> conn |> put_status(:unprocessable_entity) |> json(%{errors: format_errors(changeset)}) end end def update(conn, %{"id" => id} = params) do floor = Floors.get_floor!(id) attrs = Map.drop(params, ["id"]) case Floors.update_floor(floor, attrs) do {:ok, updated} -> json(conn, render_floor(updated)) {:error, changeset} -> conn |> put_status(:unprocessable_entity) |> json(%{errors: format_errors(changeset)}) end end def delete(conn, %{"id" => id}) do floor = Floors.get_floor!(id) {:ok, _} = Floors.delete_floor(floor) send_resp(conn, :no_content, "") end defp render_floor(floor) do %{ id: floor.id, name: floor.name, width: floor.width, height: floor.height } end defp format_errors(changeset) do Ecto.Changeset.traverse_errors(changeset, fn {msg, opts} -> Enum.reduce(opts, msg, fn {key, val}, acc -> String.replace(acc, "%{#{key}}", to_string(val)) end) end) end end