defmodule Microwaveprop.Beacons do @moduledoc """ The Beacons context. Beacon records are public (anyone can read) but only admin users can create/update/delete them — that gating is enforced by the router's live_session for the form views. """ import Ecto.Query, warn: false alias Microwaveprop.Accounts.User alias Microwaveprop.Beacons.Beacon alias Microwaveprop.Repo @topic "beacons" @doc """ Subscribes to beacon change notifications. Messages: * `{:created, %Beacon{}}` * `{:updated, %Beacon{}}` * `{:deleted, %Beacon{}}` """ def subscribe_beacons do Phoenix.PubSub.subscribe(Microwaveprop.PubSub, @topic) end defp broadcast(message) do Phoenix.PubSub.broadcast(Microwaveprop.PubSub, @topic, message) end @doc "Returns all beacons ordered by frequency." def list_beacons do Repo.all(from b in Beacon, order_by: [asc: b.frequency_mhz, asc: b.callsign]) end @doc "Gets a single beacon. Raises if not found." def get_beacon!(id), do: Repo.get!(Beacon, id) @doc """ Creates a beacon. The user is recorded on the row as the creator. """ def create_beacon(%User{} = user, attrs) do %Beacon{user_id: user.id} |> Beacon.changeset(attrs) |> Repo.insert() |> broadcast_if_ok(:created) end @doc "Updates a beacon." def update_beacon(%Beacon{} = beacon, attrs) do beacon |> Beacon.changeset(attrs) |> Repo.update() |> broadcast_if_ok(:updated) end @doc "Deletes a beacon." def delete_beacon(%Beacon{} = beacon) do case Repo.delete(beacon) do {:ok, beacon} -> broadcast({:deleted, beacon}) {:ok, beacon} other -> other end end @doc "Returns an `%Ecto.Changeset{}` for tracking beacon changes." def change_beacon(%Beacon{} = beacon, attrs \\ %{}) do Beacon.changeset(beacon, attrs) end defp broadcast_if_ok({:ok, beacon} = result, type) do broadcast({type, beacon}) result end defp broadcast_if_ok(other, _type), do: other end