Basic Understanding of Live Form

I am trying to get a basic for to do my bidding.
I am very much a beginnner so many things are a bit cloudy.
I have a heex template below:

<main class="px-4 py-20 sm:px-6 lg:px-8">
  <.form for={@form} phx-change="validate" phx-submit="Go">
    <div class="p-2">
      <div>
        <.input
          name="version"
          field={@form[:version_id]}
          options={@versions}
          type="select"
          phx-change="select-version"
          value=""
          label="Select a Version"
        />
      </div>

      <div>
        <.input
          name="customer"
          field={@form[:customer_id]}
          options={[]}
          type="select"
          phx-change="select-customer"
          value=""
          label="Select a Customer:"
        />
      </div>
      <div>
        <.button>
          Go
        </.button>
      </div>
    </div>
  </.form>
  <pre><%= inspect assigns, pretty: true %></pre>
</main>

There are two <selects one is dependent on the other.
So the value selected from versions will populate the other selector with a list of customers that belong to that version.

The related code looks like this at the moment.

defmodule CustomerbuilderWeb.MainLive.Index do
  use CustomerbuilderWeb, :live_view

  alias Customerbuilder.Builder

  @impl true
  def mount(_params, _session, socket) do

    {:ok,
     socket
     |> assign(:versions, get_versions())
     |> clear_form()}
  end

  @impl true
  def handle_event("select-version", %{"id" => id}, socket) do
    {:noreply, stream(socket, :version_collection, id)}
  end

  @impl true
  def handle_event("select-customer", %{"id" => id}, socket) do
    {:noreply, stream(socket, :version_collection, id)}
  end

  def assign_form(socket, changeset) do
    assign(socket, :form, to_form(changeset))
  end

  def clear_form(socket) do
    form =
      socket.assigns
      |> to_form()

    assign(socket, :form, form)
  end

  defp get_versions() do
    for version <- Builder.list_version(), do: {version.name, version.id}
  end
end

Once the version and customer is set the Go button will take those values and send a POST request to an api (using HTTPPoison?) to kick off a build.

Then a kind of polling to api monitor the progress of the build to update the UI, which I haven’t even started.

a map with atom keys was given to a form. Maps are always considered parameters                                                      and therefore must have string keys, got: %{versions: [{"Version-8.6.2",1}, {"Version-8.6.1", 2}, {"Version-8.5.3", 3},

I am very grateful for any interest here.