towerops/lib/towerops_web/controllers/api/v1/maintenance_windows_controller.ex
Graham McIntire a4e08b2aca Major codebase cleanup: DRY schemas, remove dead config, consolidate modules
- Created Towerops.Schema base macro (95+ schemas updated to use it)
- Created Towerops.Snmp.Reading macro (7 reading schemas consolidated)
- Created Towerops.Gaiia.BaseSchema macro (4 Gaiia schemas consolidated)
- Created Towerops.SyncLog shared module (UISP + Preseem merge)
- Created Towerops.LogFilters (3 log filter modules merged into 1)
- Created Towerops.OnCall.ChangesetHelpers (9 on-call schemas simplified)
- Created API v1 ResourceController shared helpers (7 controllers)
- Extracted ConnectionHelpers.format_connection_result (2 LiveViews)
- Removed 5 dead config keys (scopes, mib_dirs, stripe_meter_id, etc.)
- Fixed 2 pre-existing broken tests
- All 13,219 tests pass, Credo clean (0 issues)
2026-06-16 15:29:22 -05:00

119 lines
3.1 KiB
Elixir

defmodule ToweropsWeb.Api.V1.MaintenanceWindowsController do
@moduledoc """
API controller for managing maintenance windows.
All endpoints require API token authentication and operations are scoped
to the organization associated with the token.
"""
use ToweropsWeb, :controller
alias Towerops.Maintenance
alias Towerops.Maintenance.MaintenanceWindow
alias ToweropsWeb.Api.V1.ResourceController, as: Resources
@doc "GET /api/v1/maintenance_windows"
def index(conn, params) do
organization_id = conn.assigns.current_organization_id
filter = Map.get(params, "filter")
opts =
case filter do
"active" -> [filter: :active]
"upcoming" -> [filter: :upcoming]
"past" -> [filter: :past]
_ -> []
end
windows =
organization_id
|> Maintenance.list_windows(opts)
|> Enum.map(&format_window/1)
json(conn, %{maintenance_windows: windows})
end
@doc "POST /api/v1/maintenance_windows"
def create(conn, %{"maintenance_window" => window_params}) do
organization_id = conn.assigns.current_organization_id
user_id = conn.assigns.current_user.id
attrs =
window_params
|> Map.put("organization_id", organization_id)
|> Map.put("created_by_id", user_id)
Resources.created_or_error(conn, Maintenance.create_window(attrs), &format_window/1)
end
def create(conn, _params) do
Resources.missing_param(conn, "maintenance_window")
end
@doc "GET /api/v1/maintenance_windows/:id"
def show(conn, %{"id" => id}) do
organization_id = conn.assigns.current_organization_id
Resources.fetch_and_render(
conn,
MaintenanceWindow,
id,
organization_id,
&format_window/1,
"Maintenance window not found"
)
end
@doc "PATCH /api/v1/maintenance_windows/:id"
def update(conn, %{"id" => id, "maintenance_window" => window_params}) do
organization_id = conn.assigns.current_organization_id
Resources.update_and_render(
conn,
MaintenanceWindow,
id,
organization_id,
%{
context: Maintenance,
update_fn: :update_window,
params: window_params,
format_fn: &format_window/1,
not_found_msg: "Maintenance window not found"
}
)
end
def update(conn, _params) do
Resources.missing_param(conn, "maintenance_window")
end
@doc "DELETE /api/v1/maintenance_windows/:id"
def delete(conn, %{"id" => id}) do
organization_id = conn.assigns.current_organization_id
Resources.delete_and_render(
conn,
MaintenanceWindow,
id,
organization_id,
Maintenance,
:delete_window,
"Maintenance window not found"
)
end
defp format_window(window) do
%{
id: window.id,
name: window.name,
reason: window.reason,
starts_at: window.starts_at,
ends_at: window.ends_at,
recurring: window.recurring,
recurrence_rule: window.recurrence_rule,
suppress_alerts: window.suppress_alerts,
site_id: window.site_id,
device_id: window.device_id,
inserted_at: window.inserted_at
}
end
end