feat(telemetry): session journey view replaces raw events table

- sessions listed from client_events grouped by session id (7d window)
- timeline sheet merges page views, client events, errors, and server-fn
  activities joined by player within the session window
- vitals excluded from timelines; gap markers over 5 minutes
This commit is contained in:
2026-08-25 22:56:09 -07:00
parent 5d7747839c
commit e4d1ba720a
17 changed files with 605 additions and 400 deletions
+3 -3
View File
@@ -7,7 +7,7 @@ const TAB_ROUTES = {
usage: "/admin/telemetry/usage",
players: "/admin/telemetry/players",
functions: "/admin/telemetry/functions",
events: "/admin/telemetry/events",
sessions: "/admin/telemetry/sessions",
errors: "/admin/telemetry/errors",
} as const;
@@ -50,8 +50,8 @@ function TelemetryLayout() {
<Tabs.Tab value="functions">
<Trans>Functions</Trans>
</Tabs.Tab>
<Tabs.Tab value="events">
<Trans>Events</Trans>
<Tabs.Tab value="sessions">
<Trans>Sessions</Trans>
</Tabs.Tab>
<Tabs.Tab value="errors">
<Trans>Errors</Trans>
@@ -1,28 +0,0 @@
import { createFileRoute } from "@tanstack/react-router";
import { Suspense } from "react";
import { prefetchServerQuery } from "@/lib/tanstack-query/utils/prefetch";
import { telemetryQueries, defaultClientEventParams, ClientEventsTable } from "@/features/telemetry";
import { playerQueries } from "@/features/players";
import { ListSkeleton } from "@/components/skeletons";
export const Route = createFileRoute("/_authed/admin/telemetry/events")({
component: EventsTab,
beforeLoad: ({ context }) => {
const queryClient = context.queryClient;
prefetchServerQuery(queryClient, telemetryQueries.events(defaultClientEventParams));
prefetchServerQuery(queryClient, playerQueries.list());
},
loader: () => ({
withPadding: false,
fullWidth: true,
refresh: [telemetryQueries.events(defaultClientEventParams).queryKey],
}),
});
function EventsTab() {
return (
<Suspense fallback={<ListSkeleton rows={8} withSearch withSubtitle withTrailing="text" />}>
<ClientEventsTable />
</Suspense>
);
}
@@ -0,0 +1,25 @@
import { createFileRoute } from "@tanstack/react-router";
import { Suspense } from "react";
import { prefetchServerQuery } from "@/lib/tanstack-query/utils/prefetch";
import { telemetryQueries, SessionsList, defaultSessionParams } from "@/features/telemetry";
import { ListSkeleton } from "@/components/skeletons";
export const Route = createFileRoute("/_authed/admin/telemetry/sessions")({
component: SessionsTab,
beforeLoad: ({ context }) => {
prefetchServerQuery(context.queryClient, telemetryQueries.sessions(defaultSessionParams));
},
loader: () => ({
withPadding: false,
fullWidth: true,
refresh: [telemetryQueries.sessions(defaultSessionParams).queryKey],
}),
});
function SessionsTab() {
return (
<Suspense fallback={<ListSkeleton rows={8} withSubtitle withTrailing="text" />}>
<SessionsList />
</Suspense>
);
}