Ecto query implementations for the Threadline public API.
All functions require an explicit :repo option and return plain lists of
Ecto structs. DB errors propagate as exceptions, consistent with Ecto.Repo.all/2.
Timeline filters
timeline/2, timeline_query/1, and Threadline.Export accept the same
filter keyword list. Only these keys are allowed: :repo, :table, :actor_ref,
:from, :to. Unknown keys raise ArgumentError (breaking vs pre-1.0 callers
that relied on silent ignores — see CHANGELOG when upgrading).
Use timeline_repo!/2 to resolve :repo from filters and opts with the same
messages as export entrypoints.
See also
Threadline.Export— CSV / JSON export using the same filter vocabulary.
Summary
Functions
Returns AuditTransaction records for a given actor, ordered by
occurred_at descending.
Query returning one row per matching change with change + transaction columns
for export (Threadline.Export).
Returns AuditChange records for a given schema record, ordered by
captured_at descending.
Returns AuditChange records across tables, filtered by the given options,
ordered by captured_at descending, then id descending.
Builds the shared AuditChange query used by timeline/2 and export.
Resolves Ecto.Repo for timeline/2, export, and related APIs.
Validates that filters contains only timeline filter keys.
Functions
Returns AuditTransaction records for a given actor, ordered by
occurred_at descending.
For anonymous actors, returns all anonymous transactions (no actor_id distinction — all anonymous transactions are equivalent by design, per ACTR-03).
Options
:repo— requiredEcto.Repomodule
Example
Threadline.actor_history(actor_ref, repo: MyApp.Repo)
@spec export_changes_query(keyword()) :: Ecto.Query.t()
Query returning one row per matching change with change + transaction columns
for export (Threadline.Export).
Validates filters, then reuses timeline_query/1 and extends with select.
Returns AuditChange records for a given schema record, ordered by
captured_at descending.
Options
:repo— requiredEcto.Repomodule
Example
Threadline.history(MyApp.User, user.id, repo: MyApp.Repo)Each AuditChange loads all table columns mapped on the schema, including
changed_from when the database column is populated (no narrowing select).
Returns AuditChange records across tables, filtered by the given options,
ordered by captured_at descending, then id descending.
Options
:table— string or atom; filters bytable_name:actor_ref—%ActorRef{}; filters by actor via joinedaudit_transactions:from—DateTime; inclusive lower bound oncaptured_at:to—DateTime; inclusive upper bound oncaptured_at:repo— requiredEcto.Repomodule (infiltersoropts; seeThreadline.Export)
Example
Threadline.timeline(table: "users", from: ~U[2026-01-01 00:00:00Z], repo: MyApp.Repo)See also
Threadline.Export— CSV / JSON export using the same filter vocabulary.Threadline.export_csv/2andThreadline.export_json/2— top-level delegators.
@spec timeline_query(keyword()) :: Ecto.Query.t()
Builds the shared AuditChange query used by timeline/2 and export.
Does not call validate_timeline_filters!/1 — callers must validate first
when accepting external filter lists.
Resolves Ecto.Repo for timeline/2, export, and related APIs.
Checks opts first, then filters. Raises ArgumentError if missing or not an atom module.
@spec validate_timeline_filters!(keyword()) :: :ok
Validates that filters contains only timeline filter keys.
Allowed keys: :repo, :table, :actor_ref, :from, :to.
Returns :ok or raises ArgumentError.