defmodule SyntropyWeb.Api.ClusterJSON do @moduledoc false @spec report(map()) :: map() def report(cluster_report) do %{ status: cluster_report.status, local_node_id: cluster_report.local_node_id, local_node_name: cluster_report.local_node_name, expected_peers: cluster_report.expected_peers, connected_peers: cluster_report.connected_peers, unavailable_nodes: Enum.map(cluster_report.unavailable_nodes, &unavailable_node/1), abandoned_task_incidents: Enum.map(cluster_report.abandoned_task_incidents, &abandoned_task_incident/1), nodes: Enum.map(cluster_report.nodes, &cluster_node/1) } end defp cluster_node(node_export) do %{ node_id: node_export.node_id, node_name: node_export.node_name, services: node_export.services, active_tasks: Enum.map(node_export.active_tasks, &active_task/1) } end defp active_task(task) do %{ task_id: task.task_id, coordinator_node_id: task.coordinator_node_id, started_at: maybe_iso8601(task.started_at), selected_agents: task.selected_agents } end defp unavailable_node(node) do %{ node_id: node.node_id, node_name: node.node_name, status: node.status, reason: node.reason, last_seen_at: maybe_iso8601(node.last_seen_at), lost_at: maybe_iso8601(node.lost_at) } end defp abandoned_task_incident(incident) do %{ task_id: incident.task_id, node_id: incident.node_id, node_name: incident.node_name, coordinator_node_id: incident.coordinator_node_id, started_at: maybe_iso8601(incident.started_at), last_seen_at: maybe_iso8601(incident.last_seen_at), lost_at: maybe_iso8601(incident.lost_at), selected_agents: incident.selected_agents } end defp maybe_iso8601(nil), do: nil defp maybe_iso8601(%DateTime{} = value), do: DateTime.to_iso8601(value) end