defmodule MoundHuntersWeb.ApiController do @moduledoc """ API endpoints for sharing geometries. """ import Plug.Conn require Logger @doc """ Create a new shared geometry. POST /api/share Body: {"geojson": {...}} Returns: {"id": "abc12345"} """ def create_share(conn) do with {:ok, body, conn} <- read_body(conn), {:ok, params} <- Jason.decode(body), geojson when is_map(geojson) <- params["geojson"], geojson_str <- Jason.encode!(geojson), {:ok, %{id: id}} <- MoundHunters.Repo.create_geometry(geojson_str) do conn |> put_resp_content_type("application/json") |> put_resp_header("cache-control", "no-cache") |> send_resp(200, Jason.encode!(%{id: id})) else {:error, :invalid_json} -> send_error(conn, 400, "Invalid JSON") nil -> send_error(conn, 400, "Missing geojson field") {:error, reason} -> Logger.error("Failed to create geometry: #{inspect(reason)}") send_error(conn, 500, "Failed to create geometry") _ -> send_error(conn, 400, "Invalid request") end end @doc """ Get a shared geometry by ID. GET /api/share/:id Returns: {"geojson": {...}} """ def get_share(conn) do geometry_id = conn.path_params["id"] case MoundHunters.Repo.get_geometry(geometry_id) do {:ok, geometry} -> geojson = Jason.decode!(geometry.geojson) conn |> put_resp_content_type("application/json") |> put_resp_header("cache-control", "no-cache") |> send_resp(200, Jason.encode!(%{geojson: geojson})) {:error, :not_found} -> send_error(conn, 404, "Geometry not found") {:error, reason} -> Logger.error("Failed to get geometry: #{inspect(reason)}") send_error(conn, 500, "Failed to retrieve geometry") end end defp send_error(conn, status, message) do conn |> put_private(:error_message, message) |> put_resp_content_type("application/json") |> send_resp(status, Jason.encode!(%{error: message})) end end