# `PhoenixGenApi.ConfigReceiver`
[🔗](https://github.com/ohhi-vn/phoenix_gen_api/blob/main/lib/phoenix_gen_api/config_cache/config_receiver.ex#L1)

A server-side GenServer that receives pushed configs from remote nodes.

Remote nodes can push their service configurations to the server/gateway node
using this module. The receiver validates the pushed data, stores it in
`ConfigDb`, and optionally registers the service with `ConfigPuller` for
auto-pull.

## Push Mechanism

When a remote node pushes a `PushConfig`, the receiver:

  1. Validates the `PushConfig` struct
  2. Compares the `config_version` with the locally stored version
  3. If the version matches (and `:force` is not set), the push is skipped
  4. If new or forced:
     - Validates all `FunConfig` items
     - Enforces the service name on each `FunConfig`
     - Ensures each `FunConfig` has a version (defaults to `"0.0.0"`)
     - Stores them in `ConfigDb` via `ConfigDb.batch_add/1`
     - Stores the `PushConfig` in state
     - If the `PushConfig` has `module`/`function` for auto-pull, registers
       it with `ConfigPuller` via `ConfigPuller.add/1`

## Atomicity

The push operation is atomic — either all configs are stored or none. If
validation fails for the `PushConfig` or any `FunConfig` item, the entire
push is rejected.

## Important Notes

- This module runs on the **server/gateway** node (not `client_mode`)
- It should NOT be started when `client_mode: true`

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `delete_pushed_service`

```elixir
@spec delete_pushed_service(String.t() | atom()) :: :ok
```

Removes a pushed service from the receiver's state.

Also removes the service from `ConfigPuller` if it was registered for
auto-pull.

# `get_all_pushed_services`

```elixir
@spec get_all_pushed_services() :: %{required(String.t() | atom()) =&gt; String.t()}
```

Returns a map of all pushed services and their config versions.

# `get_pushed_config`

```elixir
@spec get_pushed_config(String.t() | atom()) ::
  PhoenixGenApi.Structs.PushConfig.t() | nil
```

Returns the `PushConfig` for a given service name, or `nil`.

# `push`

```elixir
@spec push(PhoenixGenApi.Structs.PushConfig.t() | map()) ::
  {:ok, :accepted} | {:ok, :skipped, term()} | {:error, term()}
```

Receives a `PushConfig` struct (or map that can be decoded into one).

Validates the `PushConfig`, checks the version, and stores the configs
if the version is new. If the `config_version` matches what is already
stored, the push is skipped.

## Returns

  - `{:ok, :accepted}` - New configs were stored successfully
  - `{:ok, :skipped, reason}` - Push was skipped (e.g., version matches)
  - `{:error, reason}` - Validation failure

# `push`

```elixir
@spec push(
  PhoenixGenApi.Structs.PushConfig.t() | map(),
  keyword()
) :: {:ok, :accepted} | {:ok, :skipped, term()} | {:error, term()}
```

Same as `push/1` but with options.

## Options

  - `:force` - Force push even if version matches (default: `false`)

# `start_link`

Starts the `ConfigReceiver` GenServer.

# `verify`

```elixir
@spec verify(String.t() | atom(), String.t()) ::
  {:ok, :matched} | {:ok, :mismatch, String.t()} | {:error, :not_found}
```

Verifies that the server has the given service and `config_version`.

## Parameters

  - `service` - The service name (string or atom)
  - `config_version` - The config version string to verify

## Returns

  - `{:ok, :matched}` - Version matches what is stored
  - `{:ok, :mismatch, stored_version}` - Version differs from what is stored
  - `{:error, :not_found}` - Service is not known

---

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