# `StatifierPersistence.Ecto`
[🔗](https://github.com/riddler/statifier_persistence/blob/v0.25.1/lib/statifier_persistence/ecto.ex#L2)

Compile-time Ecto configuration on the host's own module (ADR-0002).

A host declares its persistence module once:

    defmodule MyApp.Persistence do
      use StatifierPersistence.Ecto, repo: MyApp.Repo
    end

and gets, with zero further options: the resolved configuration
readable via `MyApp.Persistence.__statifier_persistence__/1`, and
four Ecto schema modules - `MyApp.Persistence.Chart`,
`MyApp.Persistence.Position`, `MyApp.Persistence.Execution`,
`MyApp.Persistence.Input` - over the `statifier_charts` /
`statifier_positions` / `statifier_executions` / `statifier_inputs`
tables
with UXID string primary keys (`chart_` / `pos_` / `exec_` / `input_`
prefixes).

Every knob is compile-time, on this `use`, never in application env
(ADR-0002 decision 3), and the migrations helper consumes the same
resolved configuration so schemas and DDL cannot disagree. See
`StatifierPersistence.Ecto.Config` for the options (`:key`,
`:table_prefix`, `:tables`, `:prefix`, `:blob_type`,
`:leading_columns`).

The engine identity columns (`content_hash`, `session_id`, `execution_id`)
are stored verbatim as strings and are never touched by the
configured key scheme - ADR-0002 decision 1.

The chart schema also carries `retired_at` and `retired_by`, the two
tombstone columns V07 adds (ADR-0012 decision 6). Both are `nil` on
every chart that has not been retired, which is every chart until a
host asks for one to be; a row carrying a `retired_at` has had its
`identity_blob` and `chart_blob` nulled, and both chart doors answer
for it with the retired arm rather than with its bytes.

The execution schema also carries `ended_at`, the column V08 adds:
`NULL` until the row takes its first terminal write with the column
in place, then that write's time, never moved or cleared afterwards
(`StatifierPersistence.Executions.ended?/1` names where that and the
status can disagree).

The execution schema also carries `metadata`, the optional opaque map of
host identities ADR-0006 grants, as a `jsonb` column (V02 of the
migrations helper). It holds identities only, never personal data:
`:blob_type` does not reach it, so anything filed there is at rest in
the clear no matter how the blob columns are configured.

`:blob_type` reaches the payload columns and nothing else:
`identity_blob`, `chart_blob`, `position_blob`, `outcome_blob`, and
`input_blob` on the inputs table (ADR-0010 decision 4). A host
wanting encryption at rest for those columns passes a custom
`Ecto.Type` or `Ecto.ParameterizedType` there and gets it applied
with zero further wiring. The identity and lookup columns
(`content_hash`, `session_id`, `execution_id`, `status`, `failure`, and
the input log's `seq` and `door`) stay plain regardless - the identity guard and the unique indexes
depend on reading them back verbatim, and `metadata` stays `jsonb`
regardless for the same reason: it is the column a host queries
(ADR-0006 decision 3).

The inputs table is ADR-0010's per-execution input log: one row per input
the interpreter saw, carrying the execution it belongs to, its dense
zero-based `seq`, the public `door` it entered by, and the opaque
`input_blob`. A `nil` `input_blob` is decision 6's closed marker. The
log holds document payload - an event's `data` is the host's own
values - which is why `:blob_type` reaches `input_blob` and why
turning the log on is a data-retention decision rather than a
debugging switch (`StatifierPersistence.Storage.Adapter`'s moduledoc).

---

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