# `AshPhoenixGenApi.Transformers.DefineDomainSupporter`
[🔗](https://github.com/ohhi-vn/ash_phoenix_gen_api/blob/v1.0.3/lib/ash_phoenix_gen_api/transformers/define_domain_supporter.ex#L1)

Transformer that generates the PhoenixGenApi supporter module for an Ash domain.

This transformer reads the domain-level `gen_api` DSL configuration and generates
a module that aggregates `FunConfig` structs from all resources in the domain
that have the `AshPhoenixGenApi.Resource` extension configured.

The generated supporter module implements the PhoenixGenApi client config interface,
allowing gateway nodes to pull API configurations from service nodes.

## Generated Module

Given a domain configuration like:

    defmodule MyApp.Chat do
      use Ash.Domain,
        extensions: [AshPhoenixGenApi.Domain]

      gen_api do
        service "chat"
        nodes {ClusterHelper, :get_nodes, [:chat]}
        supporter_module MyApp.Chat.GenApiSupporter
        version "0.0.1"
      end

      resources do
        resource MyApp.Chat.DirectMessage
        resource MyApp.Chat.GroupMessage
      end
    end

This transformer generates:

    defmodule MyApp.Chat.GenApiSupporter do
      @moduledoc """
      Auto-generated PhoenixGenApi supporter module for MyApp.Chat.

      Aggregates FunConfigs from all resources in the domain that have
      the AshPhoenixGenApi.Resource extension configured.

      ## Functions

      - `get_config/1` - Returns `{:ok, fun_configs()}` for PhoenixGenApi pull
      - `get_config_version/1` - Returns `{:ok, version}` for version checking
      - `fun_configs/0` - Returns the aggregated list of FunConfig structs
      - `list_request_types/0` - Returns all available request type strings
      - `get_fun_config/1` - Returns a specific FunConfig by request_type
      """

      alias PhoenixGenApi.Structs.FunConfig

      require Logger

      @doc """
      Support for remote pull general api config.
      Returns {:ok, list_of_fun_configs}
      """
      def get_config(remote_id) do
        Logger.info("Get config from remote: #{inspect(remote_id)}")
        {:ok, fun_configs()}
      end

      @doc """
      Support for remote pull general api config version.
      """
      def get_config_version(remote_id) do
        Logger.info("Get config version from remote: #{inspect(remote_id)}")
        {:ok, "0.0.1"}
      end

      @doc """
      Return list of %FunConfig{} for all APIs in this domain.
      """
      def fun_configs do
        MyApp.Chat.DirectMessage.__ash_phoenix_gen_api_fun_configs__() ++
          MyApp.Chat.GroupMessage.__ash_phoenix_gen_api_fun_configs__()
      end

      @doc """
      Get a specific function configuration by request_type.
      """
      def get_fun_config(request_type) do
        fun_configs()
        |> Enum.find(&(&1.request_type == request_type))
      end

      @doc """
      Get all available request types.
      """
      def list_request_types do
        fun_configs()
        |> Enum.map(& &1.request_type)
      end
    end

## Push Configuration Functions

When `push_nodes` is configured, the generated supporter module also includes
functions for actively pushing configuration to gateway nodes:

    gen_api do
      service "chat"
      supporter_module MyApp.Chat.GenApiSupporter
      version "0.0.1"
      push_nodes [:"gateway1@host", :"gateway2@host"]
      # Or use an MFA tuple for runtime resolution:
      # push_nodes {ClusterHelper, :get_gateway_nodes, []}
    end

This adds the following functions to the generated supporter module:

    # Builds a PushConfig struct from the domain configuration
    def build_push_config do
      # Resolves nodes at runtime (calls MFA if configured)
      # Returns %PushConfig{service: "chat", nodes: [...], ...}
    end

    # Pushes config to a specific gateway node
    def push_to_gateway(server_node, opts \ [])

    # Pushes config on application startup (with enhanced logging)
    def push_on_startup(server_node, opts \ [])

    # Verifies config version on a gateway node
    def verify_on_gateway(server_node, opts \ [])

    # Resolves push_nodes at runtime (handles MFA tuples, lists, :local, nil)
    def resolve_push_nodes

    # Pushes config to all configured push_nodes
    def push_to_configured_nodes(opts \ [])

## Configuration

The `define_supporter?` option controls whether the supporter module is
auto-generated. Set it to `false` if you want to define the module manually
(e.g., when you need to add custom logic or merge configs from non-Ash sources).

When `define_supporter?` is `false`, you can still use
`AshPhoenixGenApi.Domain.Info.fun_configs/1` to get the aggregated FunConfigs
and build your own supporter module.

# `after?`

Runs after the DefineFunConfigs transformer so that resource FunConfigs
are already generated.

# `after_compile?`

# `before?`

Does not need to run before any specific transformer.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
