Skip to content

Commit 0a3cf7a

Browse files
mikecaoclaude
andcommitted
Rename session recording to session replay across the codebase.
Renames all files, components, database schema, API routes, hooks, messages, and build config from "recording" to "replay" terminology. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 72b5c65 commit 0a3cf7a

File tree

34 files changed

+138
-144
lines changed

34 files changed

+138
-144
lines changed
Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
-- AlterTable
2-
ALTER TABLE "website" ADD COLUMN "recording_enabled" BOOLEAN NOT NULL DEFAULT false;
3-
ALTER TABLE "website" ADD COLUMN "recording_config" JSONB;
2+
ALTER TABLE "website" ADD COLUMN "replay_enabled" BOOLEAN NOT NULL DEFAULT false;
3+
ALTER TABLE "website" ADD COLUMN "replay_config" JSONB;
44

55
-- CreateTable
6-
CREATE TABLE "session_recording" (
7-
"recording_id" UUID NOT NULL,
6+
CREATE TABLE "session_replay" (
7+
"replay_id" UUID NOT NULL,
88
"website_id" UUID NOT NULL,
99
"session_id" UUID NOT NULL,
1010
"chunk_index" INTEGER NOT NULL,
@@ -14,12 +14,12 @@ CREATE TABLE "session_recording" (
1414
"ended_at" TIMESTAMPTZ(6) NOT NULL,
1515
"created_at" TIMESTAMPTZ(6) DEFAULT CURRENT_TIMESTAMP,
1616

17-
CONSTRAINT "session_recording_pkey" PRIMARY KEY ("recording_id")
17+
CONSTRAINT "session_replay_pkey" PRIMARY KEY ("replay_id")
1818
);
1919

2020
-- CreateIndex
21-
CREATE INDEX "session_recording_website_id_idx" ON "session_recording"("website_id");
22-
CREATE INDEX "session_recording_session_id_idx" ON "session_recording"("session_id");
23-
CREATE INDEX "session_recording_website_id_session_id_idx" ON "session_recording"("website_id", "session_id");
24-
CREATE INDEX "session_recording_website_id_created_at_idx" ON "session_recording"("website_id", "created_at");
25-
CREATE INDEX "session_recording_session_id_chunk_index_idx" ON "session_recording"("session_id", "chunk_index");
21+
CREATE INDEX "session_replay_website_id_idx" ON "session_replay"("website_id");
22+
CREATE INDEX "session_replay_session_id_idx" ON "session_replay"("session_id");
23+
CREATE INDEX "session_replay_website_id_session_id_idx" ON "session_replay"("website_id", "session_id");
24+
CREATE INDEX "session_replay_website_id_created_at_idx" ON "session_replay"("website_id", "created_at");
25+
CREATE INDEX "session_replay_session_id_chunk_index_idx" ON "session_replay"("session_id", "chunk_index");

prisma/schema.prisma

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ model Website {
7575
updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamptz(6)
7676
deletedAt DateTime? @map("deleted_at") @db.Timestamptz(6)
7777
78-
recordingEnabled Boolean @default(false) @map("recording_enabled")
79-
recordingConfig Json? @map("recording_config")
78+
replayEnabled Boolean @default(false) @map("replay_enabled")
79+
replayConfig Json? @map("replay_config")
8080
8181
user User? @relation("user", fields: [userId], references: [id])
8282
createUser User? @relation("createUser", fields: [createdBy], references: [id])
@@ -86,7 +86,7 @@ model Website {
8686
revenue Revenue[]
8787
segments Segment[]
8888
sessionData SessionData[]
89-
sessionRecordings SessionRecording[]
89+
sessionReplays SessionReplay[]
9090
9191
@@index([userId])
9292
@@index([teamId])
@@ -355,8 +355,8 @@ model Share {
355355
@@map("share")
356356
}
357357

358-
model SessionRecording {
359-
id String @id() @map("recording_id") @db.Uuid
358+
model SessionReplay {
359+
id String @id() @map("replay_id") @db.Uuid
360360
websiteId String @map("website_id") @db.Uuid
361361
sessionId String @map("session_id") @db.Uuid
362362
chunkIndex Int @map("chunk_index") @db.Integer
@@ -373,5 +373,5 @@ model SessionRecording {
373373
@@index([websiteId, sessionId])
374374
@@index([websiteId, createdAt])
375375
@@index([sessionId, chunkIndex])
376-
@@map("session_recording")
376+
@@map("session_replay")
377377
}

rollup.recorder.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export default {
1515
commonjs(),
1616
replace({
1717
__COLLECT_API_HOST__: process.env.COLLECT_API_HOST || '',
18-
__COLLECT_RECORDING_ENDPOINT__: process.env.COLLECT_RECORDING_ENDPOINT || '/api/record',
18+
__COLLECT_REPLAY_ENDPOINT__: process.env.COLLECT_REPLAY_ENDPOINT || '/api/record',
1919
delimiters: ['', ''],
2020
preventAssignment: true,
2121
}),

src/app/(main)/websites/[websiteId]/recordings/RecordingsDataTable.tsx

Lines changed: 0 additions & 15 deletions
This file was deleted.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { DataGrid } from '@/components/common/DataGrid';
2+
import { useReplaysQuery } from '@/components/hooks';
3+
import { ReplaysTable } from './ReplaysTable';
4+
5+
export function ReplaysDataTable({ websiteId }: { websiteId: string }) {
6+
const queryResult = useReplaysQuery(websiteId);
7+
8+
return (
9+
<DataGrid query={queryResult} allowPaging allowSearch>
10+
{({ data }) => {
11+
return <ReplaysTable data={data} websiteId={websiteId} />;
12+
}}
13+
</DataGrid>
14+
);
15+
}

src/app/(main)/websites/[websiteId]/recordings/RecordingsPage.tsx renamed to src/app/(main)/websites/[websiteId]/replays/ReplaysPage.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
import { Column } from '@umami/react-zen';
33
import { WebsiteControls } from '@/app/(main)/websites/[websiteId]/WebsiteControls';
44
import { Panel } from '@/components/common/Panel';
5-
import { RecordingsDataTable } from './RecordingsDataTable';
5+
import { ReplaysDataTable } from './ReplaysDataTable';
66

7-
export function RecordingsPage({ websiteId }: { websiteId: string }) {
7+
export function ReplaysPage({ websiteId }: { websiteId: string }) {
88
return (
99
<Column gap="3">
1010
<WebsiteControls websiteId={websiteId} />
1111
<Panel>
12-
<RecordingsDataTable websiteId={websiteId} />
12+
<ReplaysDataTable websiteId={websiteId} />
1313
</Panel>
1414
</Column>
1515
);

src/app/(main)/websites/[websiteId]/recordings/RecordingsTable.tsx renamed to src/app/(main)/websites/[websiteId]/replays/ReplaysTable.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ function formatDuration(ms: number) {
1313
return `${minutes}:${secs.toString().padStart(2, '0')}`;
1414
}
1515

16-
export function RecordingsTable({ websiteId, ...props }: DataTableProps & { websiteId: string }) {
16+
export function ReplaysTable({ websiteId, ...props }: DataTableProps & { websiteId: string }) {
1717
const { formatMessage, labels } = useMessages();
1818
const { formatValue } = useFormat();
1919

@@ -52,7 +52,7 @@ export function RecordingsTable({ websiteId, ...props }: DataTableProps & { webs
5252
</DataColumn>
5353
<DataColumn id="play" label="" width="80px">
5454
{(row: any) => (
55-
<Link href={`/websites/${websiteId}/recordings/${row.id}`}>
55+
<Link href={`/websites/${websiteId}/replays/${row.id}`}>
5656
<Button variant="quiet">
5757
<Icon>
5858
<Play />

src/app/(main)/websites/[websiteId]/recordings/[sessionId]/RecordingPlayback.tsx renamed to src/app/(main)/websites/[websiteId]/replays/[sessionId]/ReplayPlayback.tsx

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,42 +3,36 @@ import { Column, Row, Text } from '@umami/react-zen';
33
import { SessionInfo } from '@/app/(main)/websites/[websiteId]/sessions/SessionInfo';
44
import { Avatar } from '@/components/common/Avatar';
55
import { LoadingPanel } from '@/components/common/LoadingPanel';
6-
import { useMessages, useRecordingQuery, useWebsiteSessionQuery } from '@/components/hooks';
7-
import { RecordingPlayer } from './RecordingPlayer';
6+
import { useMessages, useReplayQuery, useWebsiteSessionQuery } from '@/components/hooks';
7+
import { ReplayPlayer } from './ReplayPlayer';
88

9-
export function RecordingPlayback({
10-
websiteId,
11-
sessionId,
12-
}: {
13-
websiteId: string;
14-
sessionId: string;
15-
}) {
16-
const { data: recording, isLoading, error } = useRecordingQuery(websiteId, sessionId);
9+
export function ReplayPlayback({ websiteId, sessionId }: { websiteId: string; sessionId: string }) {
10+
const { data: replay, isLoading, error } = useReplayQuery(websiteId, sessionId);
1711
const { data: session } = useWebsiteSessionQuery(websiteId, sessionId);
1812
const { formatMessage, labels } = useMessages();
1913

2014
return (
2115
<LoadingPanel
22-
data={recording}
16+
data={replay}
2317
isLoading={isLoading}
2418
error={error}
2519
loadingIcon="spinner"
2620
loadingPlacement="absolute"
2721
>
28-
{recording && (
22+
{replay && (
2923
<Column gap="6">
3024
{session && (
3125
<Row alignItems="center" gap="4">
3226
<Avatar seed={sessionId} size={48} />
3327
<Column>
34-
<Text weight="bold">{formatMessage(labels.recording)}</Text>
28+
<Text weight="bold">{formatMessage(labels.replay)}</Text>
3529
<Text color="muted">
36-
{recording.eventCount} {formatMessage(labels.events).toLowerCase()}
30+
{replay.eventCount} {formatMessage(labels.events).toLowerCase()}
3731
</Text>
3832
</Column>
3933
</Row>
4034
)}
41-
<RecordingPlayer events={recording.events} />
35+
<ReplayPlayer events={replay.events} />
4236
{session && <SessionInfo data={session} />}
4337
</Column>
4438
)}

src/app/(main)/websites/[websiteId]/recordings/[sessionId]/RecordingPlayer.tsx renamed to src/app/(main)/websites/[websiteId]/replays/[sessionId]/ReplayPlayer.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Column } from '@umami/react-zen';
33
import { useEffect, useRef, useState } from 'react';
44
import 'rrweb-player/dist/style.css';
55

6-
export function RecordingPlayer({ events }: { events: any[] }) {
6+
export function ReplayPlayer({ events }: { events: any[] }) {
77
const containerRef = useRef<HTMLDivElement>(null);
88
const playerRef = useRef<any>(null);
99
const [loaded, setLoaded] = useState(false);
@@ -17,14 +17,14 @@ export function RecordingPlayer({ events }: { events: any[] }) {
1717
typeCounts[e.type] = (typeCounts[e.type] || 0) + 1;
1818
});
1919
const timestamps = events.map((e: any) => e.timestamp).filter(Boolean);
20-
console.log('[RecordingPlayer] Events:', events.length, 'Types:', typeCounts);
20+
console.log('[ReplayPlayer] Events:', events.length, 'Types:', typeCounts);
2121
console.log(
22-
'[RecordingPlayer] Time range:',
22+
'[ReplayPlayer] Time range:',
2323
timestamps.length
2424
? `${Math.min(...timestamps)} - ${Math.max(...timestamps)} (${Math.max(...timestamps) - Math.min(...timestamps)}ms)`
2525
: 'no timestamps',
2626
);
27-
console.log('[RecordingPlayer] First 3 events:', events.slice(0, 3));
27+
console.log('[ReplayPlayer] First 3 events:', events.slice(0, 3));
2828

2929
// Dynamically import rrweb-player to avoid SSR issues
3030
import('rrweb-player').then(mod => {

src/app/(main)/websites/[websiteId]/recordings/[sessionId]/page.tsx renamed to src/app/(main)/websites/[websiteId]/replays/[sessionId]/page.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { Metadata } from 'next';
2-
import { RecordingPlayback } from './RecordingPlayback';
2+
import { ReplayPlayback } from './ReplayPlayback';
33

44
export default async function ({
55
params,
@@ -8,9 +8,9 @@ export default async function ({
88
}) {
99
const { websiteId, sessionId } = await params;
1010

11-
return <RecordingPlayback websiteId={websiteId} sessionId={sessionId} />;
11+
return <ReplayPlayback websiteId={websiteId} sessionId={sessionId} />;
1212
}
1313

1414
export const metadata: Metadata = {
15-
title: 'Recording Playback',
15+
title: 'Session Replay',
1616
};

0 commit comments

Comments
 (0)