towerops/lib/towerops/devices/backup_requests.ex

100 lines
2.5 KiB
Elixir

defmodule Towerops.Devices.BackupRequests do
@moduledoc """
Context for managing MikroTik device backup request tracking.
"""
import Ecto.Query
alias Towerops.Devices.BackupRequest
alias Towerops.Repo
@doc """
Creates a new backup request for a device.
"""
def create_request(device_id, job_id, source \\ "daily_cron") do
attrs = %{
device_id: device_id,
job_id: job_id,
requested_at: DateTime.utc_now(),
status: "pending",
source: source
}
%BackupRequest{}
|> BackupRequest.changeset(attrs)
|> Repo.insert()
end
@doc """
Gets a backup request by job_id.
Returns nil if not found.
"""
def get_request_by_job_id(job_id) do
Repo.one(from(r in BackupRequest, where: r.job_id == ^job_id))
end
@doc """
Updates a backup request status and sets completed_at.
"""
def update_request_status(request_id, status, error_message) do
request = Repo.get!(BackupRequest, request_id)
attrs = %{
status: status,
completed_at: DateTime.utc_now(),
error_message: error_message
}
request
|> BackupRequest.changeset(attrs)
|> Repo.update()
end
@doc """
Marks all pending requests older than cutoff as timeout.
Returns count of updated requests.
"""
def mark_timed_out_requests(cutoff) do
{count, _} =
Repo.update_all(from(r in BackupRequest, where: r.status == "pending", where: r.requested_at < ^cutoff),
set: [status: "timeout", completed_at: DateTime.utc_now(), error_message: "Request timed out"]
)
count
end
@doc """
Returns summary of backup request statuses since given datetime.
"""
def summary_since(since) do
result =
from(r in BackupRequest,
where: r.requested_at >= ^since,
group_by: r.status,
select: {r.status, count(r.id)}
)
|> Repo.all()
|> Map.new()
%{
success: Map.get(result, "success", 0),
failed: Map.get(result, "failed", 0),
timeout: Map.get(result, "timeout", 0),
pending: Map.get(result, "pending", 0)
}
end
@doc """
Lists devices with failed or timeout requests since given datetime.
Returns list of maps with device_id, status, and error_message.
"""
def list_failed_devices_since(since) do
Repo.all(
from(r in BackupRequest,
where: r.requested_at >= ^since,
where: r.status in ["failed", "timeout"],
select: %{device_id: r.device_id, status: r.status, error_message: r.error_message}
)
)
end
end