fix: change order keys for clickhouse tables

* wip

* rename

* fix: minor things before merging new order keys

* fix: add maintenance mode

* fix: update order by for session and events

* fix: remove properties from sessions and final migration test

* fix: set end date on migrations

* fix: comments
This commit is contained in:
Carl-Gerhard Lindesvärd
2025-12-16 12:48:51 +01:00
committed by GitHub
parent 3b61b28290
commit d7c6e88adc
18 changed files with 463 additions and 46 deletions

View File

@@ -1,6 +1,7 @@
import type { FastifyReply, FastifyRequest } from 'fastify';
import { assocPath, pathOr, pick } from 'ramda';
import { HttpError } from '@/utils/errors';
import { generateId, slug } from '@openpanel/common';
import { generateDeviceId, parseUserAgent } from '@openpanel/common/server';
import { getProfileById, getSalts, upsertProfile } from '@openpanel/db';
@@ -187,9 +188,16 @@ export async function handler(
break;
}
case 'identify': {
const payload = request.body.payload;
const geo = await getGeoLocation(ip);
if (!payload.profileId) {
throw new HttpError('Missing profileId', {
status: 400,
});
}
await identify({
payload: request.body.payload,
payload,
projectId,
geo,
ua,

View File

@@ -17,5 +17,6 @@ export function useAppContext() {
apiUrl: params.apiUrl,
dashboardUrl: params.dashboardUrl,
isSelfHosted: params.isSelfHosted,
isMaintenance: params.isMaintenance ?? false,
};
}

View File

@@ -34,6 +34,7 @@ interface MyRouterContext {
apiUrl: string;
dashboardUrl: string;
isSelfHosted: boolean;
isMaintenance: boolean;
}
export const Route = createRootRouteWithContext<MyRouterContext>()({

View File

@@ -1,5 +1,10 @@
import { FullPageEmptyState } from '@/components/full-page-empty-state';
import { Sidebar } from '@/components/sidebar';
import { Button, LinkButton, buttonVariants } from '@/components/ui/button';
import { useAppContext } from '@/hooks/use-app-context';
import { cn } from '@/utils/cn';
import { Outlet, createFileRoute, redirect } from '@tanstack/react-router';
import { ConstructionIcon } from 'lucide-react';
export const Route = createFileRoute('/_app')({
beforeLoad: async ({ context }) => {
@@ -11,6 +16,28 @@ export const Route = createFileRoute('/_app')({
});
function AppLayout() {
const { isMaintenance } = useAppContext();
if (isMaintenance) {
return (
<FullPageEmptyState
icon={ConstructionIcon}
className="min-h-screen"
title="Maintenance mode"
description="We are currently performing maintenance on the system. Please check back later."
>
<a
href="https://status.openpanel.dev/"
className={cn(buttonVariants())}
target="_blank"
rel="noopener noreferrer"
>
Check out our status page
</a>
</FullPageEmptyState>
);
}
return (
<div className="flex h-screen w-full">
<Sidebar />

View File

@@ -8,6 +8,7 @@ export const getServerEnvs = createServerFn().handler(async () => {
process.env.DASHBOARD_URL || process.env.NEXT_PUBLIC_DASHBOARD_URL,
),
isSelfHosted: process.env.SELF_HOSTED !== undefined,
isMaintenance: process.env.MAINTENANCE === '1',
};
return envs;

View File

@@ -117,7 +117,7 @@ export async function bootWorkers() {
const worker = new GroupWorker<EventsQueuePayloadIncomingEvent['payload']>({
queue,
concurrency,
logger: queueLogger,
logger: process.env.NODE_ENV === 'production' ? queueLogger : undefined,
blockingTimeoutSec: Number.parseFloat(
process.env.EVENT_BLOCKING_TIMEOUT_SEC || '1',
),

View File

@@ -1,6 +1,10 @@
import { TABLE_NAMES, chQuery } from '@openpanel/db';
export async function ping() {
if (process.env.DISABLE_PING) {
return;
}
const [res] = await chQuery<{ count: number }>(
`SELECT COUNT(*) as count FROM ${TABLE_NAMES.events}`,
);

View File

@@ -96,7 +96,6 @@ export async function createSessionEnd(
...payload,
properties: {
...payload.properties,
...(session?.properties ?? {}),
__bounce: session.is_bounce,
},
name: 'session_end',

View File

@@ -319,7 +319,6 @@ describe('incomingEvent', () => {
utm_content: '',
utm_medium: '',
revenue: 0,
properties: {},
project_id: projectId,
device_id: 'last-device-123',
profile_id: 'profile-123',