The Sessions & files screen is a read-only view over the QuickDesk audit trail. Every remote-control connection and every file transfer that passes through a ClutchCall QuickDesk device writes a row to the quickdesk_audit table in ClickHouse. The console renders two projections of that table: Nothing on this screen mutates state. It is an audit surface: if a row is missing or a session looks wrong, the cause is upstream in what the device reported, not in the view.

Two event families: connection lifecycle and file transfer

The audit table mixes two kinds of events, and the two cards separate them. Connection lifecycle events mark the start and the end of a remote-control session. Both carry the same session_id. The sessions procedure groups on that id and pairs the opening event with the closing one, so each console row is a session, not a raw event. A session that has an opening event but no closing event is still returned — see Sessions that never close. File transfer events are standalone. Each row is one transfer operation, tagged with a direction (send or recv) and carrying the list of files it moved plus the filesystem path involved. There is no open/close pairing here: one event is one complete record. The console tags send transfers with a warning tone so that outbound movement off a device is visually distinct from inbound. Both families are scoped to a device (device_id) and, where the remote end identified itself, to a peer (peer_id for transfers, ip for sessions).

Field reference for an audit row

Session rows

adminQuickdesk.sessions returns one object per reconstructed session: device_id and session_id together identify a row uniquely — the console keys its table on the pair, so the same session_id observed against two devices produces two rows. The console formats durationSec as 12s, 4m 07s, or 1h 23m depending on magnitude, and shows a live tag instead of a duration whenever live is set.

File transfer rows

adminQuickdesk.files returns one object per transfer event: numFiles and files are independent fields, and they can disagree. numFiles is the count the device reported; files is the per-file detail, which may be empty even when the count is non-zero. The console treats them as separate: it always prints the count, and prints the comma-joined name list only when files is non-empty. The aggregate byte size shown next to the count is computed in the console, not stored: it is the sum of the second element of every pair in files. Because of that, the byte total reflects only the files that appear in files. If per-file detail is missing, the size is suppressed rather than shown as zero. Do not treat that total as an authoritative transfer volume — treat files as the authority, and read the total as a convenience sum of it.

How a session is reconstructed from open and close events

A session row in the console is derived, not stored:
  1. The device emits a connection event when a remote-control session starts. It carries session_id, device_id, and the peer ip.
  2. The device emits a matching close event when the session ends, carrying the same session_id.
  3. adminQuickdesk.sessions groups the events by session_id and emits one row: opened from the first event, durationSec from the difference between the two.
  4. If step 2 never happened, the row comes back with live: true and durationSec: null.
This has a consequence worth internalising: the live flag means “no close event has been recorded”, not “a connection is currently established”. It is an inference from absence. The next section covers why the two are not the same thing.

Sessions that never close

A session can sit in the live state indefinitely. The common causes:
  • The close event was never emitted. A device that loses power, is hard-killed, or drops its network link mid-session has no opportunity to report the close. The open event is already durable in the audit table; the pair never completes.
  • The close event was emitted but not delivered. If the audit write fails or is dropped in transit, the same asymmetry results.
  • The session genuinely is still open. A long-running unattended session looks identical to the two cases above.
Because these are indistinguishable from the audit table alone, the console does not try to distinguish them — it reports exactly what the trail says. To tell a stale live row from a real one, cross-check the device’s current connection state on the device screen rather than inferring it from this table. A stale live row never resolves on its own. The close event is not back-filled, so the row stays live for as long as it remains inside the query window, and then falls out of the view.

Query windows, row caps, and retention

The console calls both procedures with fixed arguments: Three things follow from this. The windows differ by card on purpose. Sessions are an operational signal — you look at them to understand what happened recently — so the window is short. File transfers are a compliance signal, where “what left this machine last month” is the question, so the window is longer. A transfer that happened three weeks ago appears in Files shared but its parent session will already have aged out of Sessions. The row cap truncates silently. Each table returns at most 200 rows. The screen has no pagination and no “showing N of M” indicator, so a busy fleet will fill both tables to the cap and you will be looking at a prefix of the trail, not the whole of it. When a table is exactly full, assume there is more. Neither number is a retention policy. days bounds the query, not the data. Rows older than the window still exist in quickdesk_audit; they are simply not requested. How long they actually survive is a property of the quickdesk_audit table in your ClickHouse deployment — its TTL and partition-dropping configuration — and not something this screen sets or reports. If you need a guaranteed retention period for an audit or compliance requirement, verify it against the table definition in your deployment, not against what this screen displays.

Exporting the trail outside the console

Two routes out, depending on what you need. Call the procedures directly. Both adminQuickdesk.sessions and adminQuickdesk.files accept limit and days as inputs. The console hardcodes 200/7 and 200/30, but a caller is free to pass different values:
You get the same reconstructed shapes documented above — pre-paired sessions, pre-grouped transfers — which is usually what you want for reporting, since you do not have to re-implement the open/close pairing. Note that there is no cursor or offset parameter, so limit is a hard ceiling on a single call rather than a page size. Query ClickHouse directly. The underlying rows live in quickdesk_audit. Reading that table yourself is the route for anything the procedures do not express: arbitrary time ranges beyond a single call’s limit, joins against your own inventory data, unpaired-event analysis, or scheduled extracts into a warehouse. You are then working with raw events rather than reconstructed sessions, so you own the grouping on session_id.
  • Telemetry — the other operational data streams, including the ClickHouse CDR pipeline this trail sits alongside.
  • Authentication — the API key scopes that gate the adminQuickdesk procedures.