# `MishkaCmsCore.Activity.Sources.EventLog`
[🔗](https://github.com/mishka-group/mishka_cms_core/blob/v0.0.1/lib/mishka_cms_core/activity/sources/event_log.ex#L5)

Activity source backed by `AshEvents.EventLog` resources (a centralized,
durable event log per extension, e.g. `MishkaDocument.EventLog`). Auto-discovers
every event-log resource across all configured domains via
`MishkaCmsCore.Activity.Discovery.event_logs/0` — no per-extension wiring.

Each event row normalizes to the shared entry shape: the `:resource` column
becomes the label, `:action_type` drives the badge/severity/icon, `:occurred_at`
the timestamp, `:record_id` the source id, `:actor_id` the user, and the
`site_id` is read from the row's `metadata`/`data` for tenant scoping.

Read uses the universal `:read` action rather than a log's own named reads
(such as `MishkaDocument.EventLog`'s `:tenant_read`), so heterogeneous logs
work. A resource-scoped feed (`scope.resources`) filters rows by the
`:resource` column — so an
AshEvents-tracked resource (e.g. `MishkaDocument.Workspace`) appears in a feed
scoped to it, while a feed scoped to a non-AshEvents resource (the runtime
resources, which use PaperTrail) simply matches nothing. `in_scope?/2` applies
the same `:resource` filter to live broadcasts (the topic is global).

See `MishkaCmsCore.Activity.Behaviours.Source` for the behaviour contract.

# `entry_from_record`

Build an entry map from an event-log RECORD (or any map carrying its fields) — the live-broadcast
and in-memory paths, and the document event log's own table, which draws the same rows through the
same timeline and so has to phrase them the same way.

Reads `:id`, `:record_id`, `:occurred_at`, `:actor_id`, `:resource`, `:action_type`, `:metadata`
and `:data`; a caller handing it a plain map has to carry those.

# `entry_from_row`

Build an entry map from a unified `MishkaCmsCore.Activity.Query` SQL row (the
DB-side merge path), reusing the same label/severity/badge/message derivation
as the live and in-memory paths.

---

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