# `GeoGenius.ImportRun`
[🔗](https://github.com/agoodway/geo_genius/blob/main/lib/geo_genius/import_run.ex#L1)

One import run, as the `import_run_status` view reports it.

A run's state lives in PostgreSQL, never in process memory, so this struct is
a snapshot rather than a handle. `GeoGenius.status/2` returns a fresh one on
every call and `GeoGenius.await/3` polls for a newer one.

`progress` is the lease's rolling progress object, updated by heartbeats
during a phase. `stage_metrics` is the run's accumulated per-phase metrics,
updated at each phase boundary. A terminal run has no lease, so its
`progress` reads as an empty map and its `heartbeat_at` falls back to the
run's own column.

# `t`

```elixir
@type t() :: %GeoGenius.ImportRun{
  attempt: integer() | nil,
  collection_key: String.t() | nil,
  completed_at: DateTime.t() | nil,
  error: map() | nil,
  execution_started_at: DateTime.t() | nil,
  executor_id: Ecto.UUID.t() | nil,
  heartbeat_at: DateTime.t() | nil,
  manifest: map() | nil,
  owner: String.t() | nil,
  progress: map() | nil,
  release_id: Ecto.UUID.t() | nil,
  release_key: String.t() | nil,
  run_id: Ecto.UUID.t(),
  runner_backend: String.t() | nil,
  stage_metrics: map() | nil,
  started_at: DateTime.t() | nil,
  status: String.t() | nil
}
```

# `finished?`

```elixir
@spec finished?(t()) :: boolean()
```

Whether the run has reached a terminal state and will not advance again.

# `from_result`

```elixir
@spec from_result(Postgrex.Result.t()) :: [t()]
```

Maps a query result into structs.

Mapping is by column name. The view projects four text columns in a row, so a
positional mapping would transpose two of them silently the first time the
view's column order changed.

# `succeeded?`

```elixir
@spec succeeded?(t()) :: boolean()
```

Whether the run finished successfully.

---

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