Skip to content

Commit 63cca4b

Browse files
authored
Merge branch 'dev' into dashboard/changelog
2 parents d1e4bd2 + 13542cf commit 63cca4b

2 files changed

Lines changed: 23 additions & 49 deletions

File tree

apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/clickhouse-migration/page-client.tsx

Lines changed: 22 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,26 @@
11
"use client";
22

3+
import { Alert, Button, Card, CardContent, CardHeader, CardTitle, Input, Typography } from "@/components/ui";
34
import { ClickhouseMigrationRequest, ClickhouseMigrationResponse } from "@stackframe/stack-shared/dist/interface/admin-interface";
4-
import { Button, Card, CardContent, CardHeader, CardTitle, Input, Typography, Alert } from "@/components/ui";
5+
import { notFound } from "next/navigation";
56
import React from "react";
67
import { PageLayout } from "../page-layout";
78
import { useAdminApp } from "../use-admin-app";
8-
import { notFound } from "next/navigation";
99

1010
type MigrationCursor = {
1111
createdAtMillis: number,
1212
id: string,
1313
};
1414

1515
type MigrationSnapshot = {
16-
totalEvents: number,
17-
processedEvents: number,
18-
remainingEvents: number,
1916
migratedEvents: number,
20-
skippedExistingEvents: number,
2117
insertedRows: number,
22-
progress: number,
2318
nextCursor: MigrationCursor | null,
2419
};
2520

2621
const normalizeResponse = (response: ClickhouseMigrationResponse): MigrationSnapshot => ({
27-
totalEvents: response.total_events,
28-
processedEvents: response.processed_events,
29-
remainingEvents: response.remaining_events,
3022
migratedEvents: response.migrated_events,
31-
skippedExistingEvents: response.skipped_existing_events,
3223
insertedRows: response.inserted_rows,
33-
progress: response.progress,
3424
nextCursor: response.next_cursor ? {
3525
createdAtMillis: response.next_cursor.created_at_millis,
3626
id: response.next_cursor.id,
@@ -46,13 +36,16 @@ export default function PageClient() {
4636
const [minCreatedAt, setMinCreatedAt] = React.useState("");
4737
const [maxCreatedAt, setMaxCreatedAt] = React.useState("");
4838
const [limit, setLimit] = React.useState(1000);
49-
const [stats, setStats] = React.useState<MigrationSnapshot | null>(null);
5039
const [cursor, setCursor] = React.useState<MigrationCursor | null>(null);
5140
const [running, setRunning] = React.useState(false);
5241
const runningRef = React.useRef(false);
5342
const cursorRef = React.useRef<MigrationCursor | null>(null);
5443
const timeWindowRef = React.useRef<{ minCreatedAtMillis: number, maxCreatedAtMillis: number } | null>(null);
5544
const [error, setError] = React.useState<string | null>(null);
45+
const [totalMigratedEvents, setTotalMigratedEvents] = React.useState(0);
46+
const [totalInsertedRows, setTotalInsertedRows] = React.useState(0);
47+
const [batchCount, setBatchCount] = React.useState(0);
48+
const [done, setDone] = React.useState(false);
5649

5750
const parseCreatedAtMillis = React.useCallback((value: string | undefined) => {
5851
if (!value) return null;
@@ -87,7 +80,9 @@ export default function PageClient() {
8780
const runBatch = React.useCallback(async () => {
8881
const response = await adminInterface.migrateEventsToClickhouse(buildRequestBody());
8982
const snapshot = normalizeResponse(response);
90-
setStats(snapshot);
83+
setTotalMigratedEvents(prev => prev + snapshot.migratedEvents);
84+
setTotalInsertedRows(prev => prev + snapshot.insertedRows);
85+
setBatchCount(prev => prev + 1);
9186
cursorRef.current = snapshot.nextCursor;
9287
setCursor(snapshot.nextCursor);
9388
return snapshot;
@@ -103,8 +98,11 @@ export default function PageClient() {
10398
cursorRef.current = null;
10499
timeWindowRef.current = null;
105100
setCursor(null);
106-
setStats(null);
107101
setError(null);
102+
setTotalMigratedEvents(0);
103+
setTotalInsertedRows(0);
104+
setBatchCount(0);
105+
setDone(false);
108106
}, [stopMigration]);
109107

110108
const startMigration = React.useCallback(async () => {
@@ -128,6 +126,7 @@ export default function PageClient() {
128126
while (runningRef.current) {
129127
const snapshot = await runBatch();
130128
if (!snapshot.nextCursor) {
129+
setDone(true);
131130
stopMigration();
132131
break;
133132
}
@@ -138,8 +137,6 @@ export default function PageClient() {
138137
}
139138
}, [maxCreatedAt, minCreatedAt, parseCreatedAtMillis, runBatch, stopMigration]);
140139

141-
const progressPercent = Math.min(100, Math.max(0, Math.round((stats?.progress ?? 0) * 100)));
142-
143140
if (stackAdminApp.projectId !== "internal") {
144141
return notFound();
145142
}
@@ -186,7 +183,7 @@ export default function PageClient() {
186183
<Input
187184
type="number"
188185
min={1}
189-
max={1000}
186+
max={100_000}
190187
value={limit}
191188
onChange={(e) => {
192189
setLimit(Number(e.target.value) || 0);
@@ -225,40 +222,22 @@ export default function PageClient() {
225222
<CardTitle>Status</CardTitle>
226223
</CardHeader>
227224
<CardContent className="space-y-3">
228-
<div className="h-3 w-full rounded-full bg-muted">
229-
<div
230-
className="h-3 rounded-full bg-gradient-to-r from-blue-500 to-emerald-500"
231-
style={{ width: `${progressPercent}%` }}
232-
/>
233-
</div>
234-
<div className="flex items-center justify-between">
235-
<Typography variant="secondary">Progress</Typography>
236-
<Typography type="label">{progressPercent}%</Typography>
237-
</div>
238225
<div className="grid grid-cols-2 gap-3 text-sm">
239226
<div>
240-
<Typography variant="secondary">Processed</Typography>
241-
<Typography type="label">{stats?.processedEvents ?? 0}</Typography>
242-
</div>
243-
<div>
244-
<Typography variant="secondary">Remaining</Typography>
245-
<Typography type="label">{stats?.remainingEvents ?? 0}</Typography>
227+
<Typography variant="secondary">Events migrated</Typography>
228+
<Typography type="label">{totalMigratedEvents.toLocaleString()}</Typography>
246229
</div>
247230
<div>
248-
<Typography variant="secondary">Migrated this run</Typography>
249-
<Typography type="label">{stats?.migratedEvents ?? 0}</Typography>
231+
<Typography variant="secondary">Rows inserted</Typography>
232+
<Typography type="label">{totalInsertedRows.toLocaleString()}</Typography>
250233
</div>
251234
<div>
252-
<Typography variant="secondary">Inserted rows</Typography>
253-
<Typography type="label">{stats?.insertedRows ?? 0}</Typography>
235+
<Typography variant="secondary">Batches completed</Typography>
236+
<Typography type="label">{batchCount.toLocaleString()}</Typography>
254237
</div>
255238
<div>
256-
<Typography variant="secondary">Total in scope</Typography>
257-
<Typography type="label">{stats?.totalEvents ?? 0}</Typography>
258-
</div>
259-
<div className="">
260239
<Typography variant="secondary">State</Typography>
261-
<Typography type="label">{running ? "Running" : "Idle"}</Typography>
240+
<Typography type="label">{done ? "Done" : running ? "Running" : "Idle"}</Typography>
262241
</div>
263242
</div>
264243
</CardContent>

packages/stack-shared/src/interface/admin-interface.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ import { KnownErrors } from "../known-errors";
33
import { branchConfigSourceSchema } from "../schema-fields";
44
import { AccessToken, InternalSession, RefreshToken } from "../sessions";
55
import { Result } from "../utils/results";
6+
import type { AnalyticsQueryOptions, AnalyticsQueryResponse } from "./crud/analytics";
67
import { EmailOutboxCrud } from "./crud/email-outbox";
78
import { InternalEmailsCrud } from "./crud/emails";
89
import { InternalApiKeysCrud } from "./crud/internal-api-keys";
910
import { ProjectPermissionDefinitionsCrud } from "./crud/project-permissions";
1011
import { ProjectsCrud } from "./crud/projects";
1112
import { SvixTokenCrud } from "./crud/svix-token";
12-
import type { AnalyticsQueryOptions, AnalyticsQueryResponse } from "./crud/analytics";
1313
import { TeamPermissionDefinitionsCrud } from "./crud/team-permissions";
1414
import type { Transaction, TransactionType } from "./crud/transactions";
1515
import { ServerAuthApplicationOptions, StackServerInterface } from "./server-interface";
@@ -56,13 +56,8 @@ export type ClickhouseMigrationRequest = {
5656
};
5757

5858
export type ClickhouseMigrationResponse = {
59-
total_events: number,
60-
processed_events: number,
61-
remaining_events: number,
6259
migrated_events: number,
63-
skipped_existing_events: number,
6460
inserted_rows: number,
65-
progress: number,
6661
next_cursor: {
6762
created_at_millis: number,
6863
id: string,

0 commit comments

Comments
 (0)