# `PgFlow.SchemaCheck`
[🔗](https://github.com/agoodway/pgflow/blob/v0.7.0/lib/pgflow/schema_check.ex#L1)

Verifies that a database matches the pgflow schema contract expected by this
library release.

`mix pgflow.check_schema` checks installed core/helpers versions, function
signatures, queue constraints, and the eight-field `step_task_record` layout.
Worker startup uses `runtime_checks/1` for the 0.17.2 signatures, absence of
the legacy claim and compile overloads, field names and types, and the
helpers version floor before reserving messages. `warnings/2` reports
advisory findings about pgmq notify triggers, such as triggers that are not
deferred to commit or that have no throttle row, without failing the check.

# `run`

```elixir
@spec run(module()) :: :ok | {:error, [String.t()]}
```

Runs all schema compatibility checks against `repo`.

Returns `:ok` when every check passes, or `{:error, messages}` with one
human-readable message per failed check.

# `runtime_checks`

```elixir
@spec runtime_checks(module()) :: :ok | {:error, term()}
```

Checks the claim and startup protocol before any worker reserves messages.
Connectivity failures retain their original error; incompatible schemas
return `{:error, {:schema_incompatible, object}}`.

# `warnings`

```elixir
@spec warnings(module(), keyword()) :: [String.t()]
```

Runs advisory checks against `repo` and returns one human-readable message
per finding, or `[]` when nothing needs attention.

Advisory findings describe state that pgflow repairs at runtime or that
only affects notifications, so they do not fail `run/1`. Every check
inspects only the `trigger_notify_queue_insert_listeners` triggers on the
queues `PgFlow.FlowStarter` enables notify for (each flow's
`lower(flow_slug)` queue), so a database used only with the `:polling`
signal strategy (no triggers) reports nothing, and neither does a custom
step `queue_name` that pgflow never manages. The checks report:

  * a trigger that is not `DEFERRABLE INITIALLY DEFERRED` (`:deferred`
    only), for example after `ALTER EXTENSION pgmq UPDATE` recreated it
  * a trigger whose queue has no `pgmq.notify_insert_throttle` row, so it
    sends no NOTIFY
  * a trigger on a partitioned queue table that pgmq's
    `notify_queue_listeners()` cannot resolve to its queue (pgmq releases
    before 1.13.1), so it sends no NOTIFY

## Options

  * `:notify_trigger` - the `PgFlow.Config` `:notify_trigger` setting.
    `:pgmq_default` skips the deferred-trigger check, since immediate
    triggers are then expected. Default: `:deferred`.

---

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