# `SquatchMail.Web.Live.TrailLog`
[🔗](https://github.com/Axio-Intelligence/Squatch-Mail/blob/v0.1.1/lib/squatch_mail/web/live/trail_log.ex#L1)

The Trail Log — SquatchMail's default landing page (`squatch_mail_dashboard`
mounted at `/`), showing the live activity feed: stat strip, filters, and
the sent-email activity table.

## One LiveView, four pages

This module also serves the sidebar's three archive pages, distinguished by
`live_action` (see `@pages`):

  * `:index` — the Trail Log itself (`/`): recent activity, 7-day default
    range, stat strip.
  * `:sightings` — the Sightings archive (`/sightings`): every email on
    record, all-time default range.
  * `:bounces` / `:complaints` — the same table locked to status
    `"bounced"` / `"complained"` (`/bounces`, `/complaints`). The status
    filter is forced and its select hidden; a hand-typed `?status=` param
    can't unlock it.

They share everything that matters — the URL-driven filters, the
telemetry-driven refresh, pagination, and the activity table — so they're
per-action page configs rather than three near-identical modules.

## Filters live in the URL

Every filter (status, search, date range) is a query param, patched via
`push_patch/2` from `handle_event/3` and re-read in `handle_params/3` — the
same pattern `SquatchMail.Web.Live.Suppressions` uses. This is what lets
`SquatchMail.Web.ActivityExportController`'s CSV export and the "back to
Trail Log" link from the Sighting inspector both reconstruct the exact
filter set a user was looking at, just from the URL.

## Live updates

Rather than push every new email/event straight into the assigns from a
telemetry handler (telemetry handlers run in the *emitting* process, not
this LiveView's — attaching a handler here would execute in the wrong
process and race with everything else), `mount/3` attaches a handler that
simply forwards `[:squatch_mail, :email, :recorded]` telemetry events to
this LiveView's own process via `send/2`, debounced so a burst of events
collapses into a single reload. A 30s poll (`:timer.send_interval/2`) is
the fallback for whatever telemetry might miss (host restarts the handler
attachment, a handler exception detaches it, etc.) The handler is detached
in `terminate/2` — leaving it attached would leak a reference to a dead
LiveView process on every mount.

# `filters_from_params`

```elixir
@spec filters_from_params(map()) :: map()
```

Builds `Tracker.list_emails/1`-shaped filters from Trail Log's query
params. Public and shared with `SquatchMail.Web.ActivityExportController`
so the CSV export always matches whatever's on screen — the archive pages'
"Export CSV" links spell their locked status and effective range out as
explicit query params (see `export_query/2`), so this 1-arity form (Trail
Log defaults) is all the controller ever needs.

---

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