diff --git a/lib/towerops_web/controllers/api/v1/sites_controller.ex b/lib/towerops_web/controllers/api/v1/sites_controller.ex deleted file mode 100644 index 1f7aa29e..00000000 --- a/lib/towerops_web/controllers/api/v1/sites_controller.ex +++ /dev/null @@ -1,235 +0,0 @@ -defmodule ToweropsWeb.Api.V1.SitesController do - @moduledoc """ - API controller for managing sites. - - All endpoints require API token authentication and operations are scoped - to the organization associated with the token. - """ - use ToweropsWeb, :controller - - import ToweropsWeb.Api.ErrorHelpers, only: [translate_errors: 1] - - alias Towerops.Sites - alias Towerops.Sites.Site - alias ToweropsWeb.ScopedResource - - @doc """ - GET /api/v1/sites - - Lists all sites for the authenticated organization. - - Response: - { - "sites": [ - { - "id": "uuid", - "name": "Main Office", - "location": "New York, NY", - "snmp_community": "public", - "inserted_at": "2026-01-15T19:44:25Z" - } - ] - } - """ - def index(conn, _params) do - organization_id = conn.assigns.current_organization_id - - sites = - organization_id - |> Sites.list_organization_sites() - |> Enum.map(&format_site/1) - - json(conn, %{sites: sites}) - end - - @doc """ - POST /api/v1/sites - - Creates a new site for the authenticated organization. - - Request body: - { - "site": { - "name": "Main Office", - "location": "New York, NY", - "snmp_community": "public" # optional - } - } - - Response: - { - "id": "uuid", - "name": "Main Office", - "location": "New York, NY", - "snmp_community": "public", - "inserted_at": "2026-01-15T19:44:25Z" - } - """ - def create(conn, %{"site" => site_params}) do - organization_id = conn.assigns.current_organization_id - attrs = Map.put(site_params, "organization_id", organization_id) - - case Sites.create_site(attrs) do - {:ok, site} -> - conn - |> put_status(:created) - |> json(format_site(site)) - - {:error, %Ecto.Changeset{} = changeset} -> - conn - |> put_status(:unprocessable_entity) - |> json(%{errors: translate_errors(changeset)}) - end - end - - def create(conn, _params) do - conn - |> put_status(:bad_request) - |> json(%{error: "Missing 'site' parameter"}) - end - - @doc """ - GET /api/v1/sites/:id - - Gets a single site by ID. - - Response: - { - "id": "uuid", - "name": "Main Office", - "location": "New York, NY", - "snmp_community": "public", - "inserted_at": "2026-01-15T19:44:25Z" - } - """ - def show(conn, %{"id" => id}) do - organization_id = conn.assigns.current_organization_id - - case ScopedResource.fetch(Site, id, organization_id) do - {:ok, site} -> - json(conn, format_site(site)) - - {:error, :forbidden} -> - conn - |> put_status(:forbidden) - |> json(%{error: "Access denied to this site"}) - - {:error, :not_found} -> - conn - |> put_status(:not_found) - |> json(%{error: "Site not found"}) - end - end - - @doc """ - PATCH /api/v1/sites/:id - - Updates a site. - - Request body: - { - "site": { - "name": "Updated Name", - "location": "Boston, MA" - } - } - - Response: - { - "id": "uuid", - "name": "Updated Name", - "location": "Boston, MA", - "snmp_community": "public", - "inserted_at": "2026-01-15T19:44:25Z" - } - """ - def update(conn, %{"id" => id, "site" => site_params}) do - organization_id = conn.assigns.current_organization_id - - case ScopedResource.fetch(Site, id, organization_id) do - {:ok, site} -> - case Sites.update_site(site, site_params) do - {:ok, updated_site} -> - json(conn, format_site(updated_site)) - - {:error, %Ecto.Changeset{} = changeset} -> - conn - |> put_status(:unprocessable_entity) - |> json(%{errors: translate_errors(changeset)}) - end - - {:error, :forbidden} -> - conn - |> put_status(:forbidden) - |> json(%{error: "Access denied to this site"}) - - {:error, :not_found} -> - conn - |> put_status(:not_found) - |> json(%{error: "Site not found"}) - end - end - - def update(conn, _params) do - conn - |> put_status(:bad_request) - |> json(%{error: "Missing 'site' parameter"}) - end - - @doc """ - DELETE /api/v1/sites/:id - - Deletes a site. - - Response: - { - "success": true - } - """ - def delete(conn, %{"id" => id}) do - organization_id = conn.assigns.current_organization_id - - case ScopedResource.fetch(Site, id, organization_id) do - {:ok, site} -> - case Sites.delete_site(site) do - {:ok, _site} -> - json(conn, %{success: true}) - - {:error, %Ecto.Changeset{} = changeset} -> - conn - |> put_status(:unprocessable_entity) - |> json(%{errors: translate_errors(changeset)}) - end - - {:error, :forbidden} -> - conn - |> put_status(:forbidden) - |> json(%{error: "Access denied to this site"}) - - {:error, :not_found} -> - conn - |> put_status(:not_found) - |> json(%{error: "Site not found"}) - end - end - - defp format_site(site) do - %{ - id: site.id, - name: site.name, - description: site.description, - location: site.location, - address: site.address, - latitude: site.latitude, - longitude: site.longitude, - display_order: site.display_order, - snmp_community: site.snmp_community, - snmp_version: site.snmp_version, - snmp_port: site.snmp_port, - snmp_transport: site.snmp_transport, - agent_token_id: site.agent_token_id, - parent_site_id: site.parent_site_id, - inserted_at: site.inserted_at - } - end -end