defmodule DaProductAppWeb.OtaConfigurationController do use DaProductAppWeb, :controller require Logger alias DaProductApp.TerminalManagement alias DaProductApp.TerminalManagement.OtaService @doc """ Create and send OTA configuration to a device. POST /api/ota/configuration Body: { "device_serial": "38250416780001", "merchant_config": { "merchant_id": "900890089008000", "terminal_id": "90080002", "mqtt_ip": "testapp.ariticapp.com", "mqtt_port": 1883, "http_ip": "demo.ctrmv.com", "http_port": 4001, "product_key": "pFppbioOCKlo5c8E", "product_secret": "sj2AJl102397fQAV", "username": "user001", "keepalive_time": 300, "play_language": 1, "heartbeat_interval": 300 } } """ def create(conn, %{"device_serial" => device_serial, "merchant_config" => merchant_config}) do case OtaService.send_merchant_config_update(device_serial, merchant_config) do {:ok, message} -> conn |> put_status(200) |> json(%{status: "success", message: message}) {:error, reason} -> Logger.error("Failed to send OTA configuration: #{reason}") conn |> put_status(422) |> json(%{status: "error", message: reason}) end end @doc """ Get OTA configuration status for a device. GET /api/ota/configuration/:device_serial """ def show(conn, %{"device_serial" => device_serial}) do case OtaService.get_latest_ota_config(device_serial) do nil -> conn |> put_status(404) |> json(%{status: "error", message: "No OTA configuration found for device"}) config -> conn |> put_status(200) |> json(%{ status: "success", data: %{ id: config.id, request_id: config.request_id, device_serial: config.device_serial, merchant_id: config.merchant_id, terminal_id: config.terminal_id, status: config.status, sent_at: config.sent_at, acknowledged_at: config.acknowledged_at, error_message: config.error_message, heartbeat_interval: config.heartbeat_interval } }) end end @doc """ List all OTA configurations with optional filtering. GET /api/ota/configurations """ def index(conn, params) do configs = TerminalManagement.list_ota_configurations(params) config_data = Enum.map(configs, fn config -> %{ id: config.id, request_id: config.request_id, device_serial: config.device_serial, merchant_id: config.merchant_id, terminal_id: config.terminal_id, status: config.status, sent_at: config.sent_at, acknowledged_at: config.acknowledged_at, error_message: config.error_message, inserted_at: config.inserted_at } end) conn |> put_status(200) |> json(%{status: "success", data: config_data}) end @doc """ Retry failed OTA configuration. POST /api/ota/configuration/:id/retry """ def retry(conn, %{"id" => id}) do case TerminalManagement.get_ota_configuration!(id) do config when config.status in ["failed", "pending"] -> case OtaService.send_ota_configuration(config) do {:ok, message} -> conn |> put_status(200) |> json(%{status: "success", message: message}) {:error, reason} -> conn |> put_status(422) |> json(%{status: "error", message: reason}) end config -> conn |> put_status(422) |> json(%{ status: "error", message: "Configuration is in #{config.status} status and cannot be retried" }) end rescue Ecto.NoResultsError -> conn |> put_status(404) |> json(%{status: "error", message: "OTA configuration not found"}) end end