Host-router macros for mounting Cairnloop's operator surfaces.
Cairnloop is host-owned: you mount its operations endpoints and operator dashboard into
your router, under your pipelines, so auth, session, layout, and route placement stay
yours. See cairnloop_operations/1 and cairnloop_dashboard/2.
Summary
Functions
Mounts the Cairnloop operator dashboard (inbox, conversations, knowledge base, settings, and
the audit-log timeline) under path as a single Phoenix.LiveView live_session.
Mounts the operations endpoints a host needs for monitoring (OPS-01, OPS-02)
Functions
Mounts the Cairnloop operator dashboard (inbox, conversations, knowledge base, settings, and
the audit-log timeline) under path as a single Phoenix.LiveView live_session.
Wrap it in your own scope so auth/session/layout stay host-owned — Cairnloop does not embed
auth:
scope "/support" do
pipe_through [:browser, :require_admin]
cairnloop_dashboard "/",
on_mount: [{MyAppWeb.UserAuth, :ensure_admin}],
session: {MyAppWeb.UserAuth, :cairnloop_session, []}
endOperator identity (host_user_id)
Cairnloop uses the host_user_id value in the live session as the operator's identity — it
is the actor recorded on governed audit events and the scope key for operator search. Provide it
through the :session option, and use the MFA form so each request carries the actually
signed-in operator:
def cairnloop_session(conn) do
%{"host_user_id" => to_string(conn.assigns.current_user.id)}
endA static session: %{"host_user_id" => "demo_operator"} map is fine for a single-operator demo,
but it is frozen at compile time and is identical for every request — ship it and your audit log
attributes every operator's actions to one placeholder id. See the
Auth & Operator Identity guide for the full pattern.
Any option other than the Cairnloop-specific ones below is forwarded verbatim to
Phoenix.LiveView.Router.live_session/3 (e.g. :session, :on_mount, :root_layout,
:layout).
Options
:live_session_name(atom/0) - Name of the generatedlive_session. Override when mounting the dashboard more than once in a single host router, so the twolive_sessionnames do not collide. The default value is:cairnloop_dashboard.
Mounts the operations endpoints a host needs for monitoring (OPS-01, OPS-02):
GET /health→Cairnloop.Web.HealthPlug(liveness/readiness probe, 200 JSON).GET /metrics→Cairnloop.Web.MetricsPlug(Prometheus text; 501 until:telemetry_metrics_prometheus_coreis added).
Call it from your host router, typically outside any authentication pipeline so infrastructure can reach the probes:
scope "/" do
cairnloop_operations()
endOptions
:health_path(String.t/0) - Path the/healthliveness probe is mounted at. The default value is"/health".:metrics_path(String.t/0) - Path the/metricsPrometheus scrape endpoint is mounted at. The default value is"/metrics".