Dozor
Replays

List & filters

The Replays tab (/replays) shows every session captured by the SDK across the active org's projects, newest first. Sessions stay until they hit the retention cutoff — 7 days by default — at which point the daily cron deletes them.

Empty list? No sessions land here until the SDK posts at least one batch. Fastest way to populate it without integrating into a real app: paste an API key into the Playground, click around for ~30 seconds, refresh.

KPI strip

Four cards above the list, scoped to the active org:

CardSource
Total sessionsAll sessions in the active org (so capped at ~7 days by retention)
Total durationSUM(session.duration)
Avg durationAVG(session.duration), rounded
Active todaySessions created in the last 24 hours (rolling window, not calendar day)

Single GET /api/sessions/summary query — one round-trip with COUNT … FILTER (...) conditional aggregation, not four separate queries.

Columns

ColumnContent
SessionThe SDK-side externalId (a UUID), linked to the player at /replays/[id]
UserDisplay name resolved via the 4-step chain; empty dash for anonymous sessions
ProjectBadge with the project's label
Eventsrrweb event count denormalised on Session for fast list rendering
DurationMM:SS recording length. Sortable — click the header to toggle desc/asc
DateRelative timestamp (e.g. "3 minutes ago"); hover for the full timestamp. Sortable

The right-most column is a per-row kebab menu visible only to OWNER / ADMIN — currently just Delete (see below).

Filters

Three filter affordances:

  • Search — free-text input, matches against session and user fields server-side.
  • Project — multi-select popover scoped to the active org.
  • Date range — popover with two presets: Today and the retention-wide window, whose label tracks SESSION_RETENTION_DAYS (currently Last 7 days). The retention-wide preset is the default — its lower bound is the retention window, so by default you see everything the database still holds. Narrower fixed presets (e.g. "Last 30 days") are deliberately omitted: they'd advertise a range older than retention that no longer exists.

All filters serialise into the URL as query params; default values are elided to keep links clean. A filtered URL is shareable — pasting it into a teammate's browser gives them the same view, subject to RBAC (they only see orgs they're a member of).

Pagination

Cursor-based by id (not offset), so list position stays stable as new sessions land — page 2 doesn't shift down when someone records on page 1. The cursor is the last row's id passed back via ?cursor=; the server resolves the next page with cursor: { id }, skip: 1.

keepPreviousData on the TanStack query keeps the previous page on screen while the next page loads — no flicker on filter / sort / pagination change.

Deleting a session

OWNER + ADMIN. Click the kebab icon () at the end of the row → Delete → confirmation dialog → Delete. The session row, its event batches, and its markers are removed from the database. No soft-delete. The session is gone.

The capability is double-validated — UI hides the kebab menu for VIEWERs, and DELETE /api/sessions/[id] checks requireMember(..., "ADMIN") regardless.

See also

On this page