rename mixan to OPENPANEL!

This commit is contained in:
Carl-Gerhard Lindesvärd
2024-03-11 13:40:46 +01:00
parent 6d4f9010d4
commit e6c0bc2ec8
201 changed files with 1193 additions and 1047 deletions

View File

@@ -1,19 +1,19 @@
import { logger, logInfo, noop } from '@/utils/logger';
import { getClientIp, parseIp } from '@/utils/parseIp';
import { getReferrerWithQuery, parseReferrer } from '@/utils/parseReferrer';
import { isUserAgentSet, parseUserAgent } from '@/utils/parseUserAgent';
import { isSameDomain, parsePath } from '@/utils/url';
import type { FastifyReply, FastifyRequest } from 'fastify';
import { omit } from 'ramda';
import { v4 as uuid } from 'uuid';
import { logger, logInfo, noop } from "@/utils/logger";
import { getClientIp, parseIp } from "@/utils/parseIp";
import { getReferrerWithQuery, parseReferrer } from "@/utils/parseReferrer";
import { isUserAgentSet, parseUserAgent } from "@/utils/parseUserAgent";
import { isSameDomain, parsePath } from "@/utils/url";
import type { FastifyReply, FastifyRequest } from "fastify";
import { omit } from "ramda";
import { v4 as uuid } from "uuid";
import { generateDeviceId, getTime, toISOString } from '@mixan/common';
import type { IServiceCreateEventPayload } from '@mixan/db';
import { createEvent, getEvents, getSalts } from '@mixan/db';
import type { JobsOptions } from '@mixan/queue';
import { eventsQueue } from '@mixan/queue';
import { findJobByPrefix } from '@mixan/queue/src/utils';
import type { PostEventPayload } from '@mixan/sdk';
import { generateDeviceId, getTime, toISOString } from "@openpanel/common";
import type { IServiceCreateEventPayload } from "@openpanel/db";
import { createEvent, getEvents, getSalts } from "@openpanel/db";
import type { JobsOptions } from "@openpanel/queue";
import { eventsQueue } from "@openpanel/queue";
import { findJobByPrefix } from "@openpanel/queue/src/utils";
import type { PostEventPayload } from "@openpanel/sdk";
const SESSION_TIMEOUT = 1000 * 60 * 30;
const SESSION_END_TIMEOUT = SESSION_TIMEOUT + 1000;
@@ -55,7 +55,7 @@ export async function postEvent(
request: FastifyRequest<{
Body: PostEventPayload;
}>,
reply: FastifyReply
reply: FastifyReply,
) {
const contextLogger = createContextLogger(request);
let deviceId: string | null = null;
@@ -65,23 +65,23 @@ export async function postEvent(
// replace thing is just for older sdks when we didn't have `__`
// remove when kiddokitchen app (24.09.02) is not used anymore
return (
((properties[name] || properties[name.replace('__', '')]) as
((properties[name] || properties[name.replace("__", "")]) as
| string
| null
| undefined) ?? undefined
);
};
const profileId = body.profileId ?? '';
const profileId = body.profileId ?? "";
const createdAt = new Date(body.timestamp);
const url = getProperty('__path');
const url = getProperty("__path");
const { path, hash, query } = parsePath(url);
const referrer = isSameDomain(getProperty('__referrer'), url)
const referrer = isSameDomain(getProperty("__referrer"), url)
? null
: parseReferrer(getProperty('__referrer'));
: parseReferrer(getProperty("__referrer"));
const utmReferrer = getReferrerWithQuery(query);
const ip = getClientIp(request)!;
const origin = request.headers.origin!;
const ua = request.headers['user-agent']!;
const ua = request.headers["user-agent"]!;
const uaInfo = parseUserAgent(ua);
const salts = await getSalts();
const currentDeviceId = generateDeviceId({
@@ -101,66 +101,66 @@ export async function postEvent(
if (isServerEvent) {
const [event] = await withTiming(
'Get last event (server-event)',
"Get last event (server-event)",
getEvents(
`SELECT * FROM events WHERE name = 'screen_view' AND profile_id = '${profileId}' AND project_id = '${projectId}' ORDER BY created_at DESC LIMIT 1`
)
`SELECT * FROM events WHERE name = 'screen_view' AND profile_id = '${profileId}' AND project_id = '${projectId}' ORDER BY created_at DESC LIMIT 1`,
),
);
eventsQueue.add('event', {
type: 'createEvent',
eventsQueue.add("event", {
type: "createEvent",
payload: {
name: body.name,
deviceId: event?.deviceId || '',
sessionId: event?.sessionId || '',
deviceId: event?.deviceId || "",
sessionId: event?.sessionId || "",
profileId,
projectId,
properties: Object.assign(
{},
omit(['__path', '__referrer'], properties),
omit(["__path", "__referrer"], properties),
{
hash,
query,
}
},
),
createdAt,
country: event?.country ?? '',
city: event?.city ?? '',
region: event?.region ?? '',
continent: event?.continent ?? '',
os: event?.os ?? '',
osVersion: event?.osVersion ?? '',
browser: event?.browser ?? '',
browserVersion: event?.browserVersion ?? '',
device: event?.device ?? '',
brand: event?.brand ?? '',
model: event?.model ?? '',
country: event?.country ?? "",
city: event?.city ?? "",
region: event?.region ?? "",
continent: event?.continent ?? "",
os: event?.os ?? "",
osVersion: event?.osVersion ?? "",
browser: event?.browser ?? "",
browserVersion: event?.browserVersion ?? "",
device: event?.device ?? "",
brand: event?.brand ?? "",
model: event?.model ?? "",
duration: 0,
path: event?.path ?? '',
referrer: event?.referrer ?? '',
referrerName: event?.referrerName ?? '',
referrerType: event?.referrerType ?? '',
path: event?.path ?? "",
referrer: event?.referrer ?? "",
referrerName: event?.referrerName ?? "",
referrerType: event?.referrerType ?? "",
profile: undefined,
meta: undefined,
},
});
return reply.status(200).send('');
return reply.status(200).send("");
}
const [geo, sessionEndJobCurrentDeviceId, sessionEndJobPreviousDeviceId] =
await withTiming(
'Get geo and jobs from queue',
"Get geo and jobs from queue",
Promise.all([
parseIp(ip),
findJobByPrefix(
eventsQueue,
`sessionEnd:${projectId}:${currentDeviceId}:`
`sessionEnd:${projectId}:${currentDeviceId}:`,
),
findJobByPrefix(
eventsQueue,
`sessionEnd:${projectId}:${previousDeviceId}:`
`sessionEnd:${projectId}:${previousDeviceId}:`,
),
])
]),
);
const createSessionStart =
@@ -178,9 +178,9 @@ export async function postEvent(
deviceId = currentDeviceId;
// Queue session end
eventsQueue.add(
'event',
"event",
{
type: 'createSessionEnd',
type: "createSessionEnd",
payload: {
deviceId,
},
@@ -188,27 +188,27 @@ export async function postEvent(
{
delay: SESSION_END_TIMEOUT,
jobId: `sessionEnd:${projectId}:${deviceId}:${Date.now()}`,
}
},
);
}
const [[sessionStartEvent], prevEventJob] = await withTiming(
'Get session start event',
"Get session start event",
Promise.all([
getEvents(
`SELECT * FROM events WHERE name = 'session_start' AND device_id = '${deviceId}' AND project_id = '${projectId}' ORDER BY created_at DESC LIMIT 1`
`SELECT * FROM events WHERE name = 'session_start' AND device_id = '${deviceId}' AND project_id = '${projectId}' ORDER BY created_at DESC LIMIT 1`,
),
findJobByPrefix(eventsQueue, `event:${projectId}:${deviceId}:`),
])
]),
);
const payload: Omit<IServiceCreateEventPayload, 'id'> = {
const payload: Omit<IServiceCreateEventPayload, "id"> = {
name: body.name,
deviceId,
profileId,
projectId,
sessionId: createSessionStart ? uuid() : sessionStartEvent?.sessionId ?? '',
properties: Object.assign({}, omit(['__path', '__referrer'], properties), {
sessionId: createSessionStart ? uuid() : sessionStartEvent?.sessionId ?? "",
properties: Object.assign({}, omit(["__path", "__referrer"], properties), {
hash,
query,
}),
@@ -227,27 +227,27 @@ export async function postEvent(
duration: 0,
path: path,
referrer: referrer?.url,
referrerName: referrer?.name ?? utmReferrer?.name ?? '',
referrerType: referrer?.type ?? utmReferrer?.type ?? '',
referrerName: referrer?.name ?? utmReferrer?.name ?? "",
referrerType: referrer?.type ?? utmReferrer?.type ?? "",
profile: undefined,
meta: undefined,
};
const isDelayed = prevEventJob ? await prevEventJob?.isDelayed() : false;
if (isDelayed && prevEventJob && prevEventJob.data.type === 'createEvent') {
if (isDelayed && prevEventJob && prevEventJob.data.type === "createEvent") {
const prevEvent = prevEventJob.data.payload;
const duration = getTime(payload.createdAt) - getTime(prevEvent.createdAt);
contextLogger.add('prevEvent', prevEvent);
contextLogger.add("prevEvent", prevEvent);
// Set path from prev screen_view event if current event is not a screen_view
if (payload.name != 'screen_view') {
if (payload.name != "screen_view") {
payload.path = prevEvent.path;
}
if (payload.name === 'screen_view') {
if (payload.name === "screen_view") {
if (duration < 0) {
contextLogger.send('duration is wrong', {
contextLogger.send("duration is wrong", {
payload,
duration,
});
@@ -255,21 +255,21 @@ export async function postEvent(
// Skip update duration if it's wrong
// Seems like request is not in right order
await withTiming(
'Update previous job with duration',
"Update previous job with duration",
prevEventJob.updateData({
type: 'createEvent',
type: "createEvent",
payload: {
...prevEvent,
duration,
},
})
}),
);
}
await withTiming('Promote previous job', prevEventJob.promote());
await withTiming("Promote previous job", prevEventJob.promote());
}
} else if (payload.name !== 'screen_view') {
contextLogger.send('no previous job', {
} else if (payload.name !== "screen_view") {
contextLogger.send("no previous job", {
prevEventJob,
payload,
});
@@ -278,23 +278,23 @@ export async function postEvent(
if (createSessionStart) {
// We do not need to queue session_start
await withTiming(
'Create session start event',
"Create session start event",
createEvent({
...payload,
name: 'session_start',
name: "session_start",
// @ts-expect-error
createdAt: toISOString(getTime(payload.createdAt) - 100),
})
}),
);
}
const options: JobsOptions = {};
if (payload.name === 'screen_view') {
if (payload.name === "screen_view") {
options.delay = SESSION_TIMEOUT;
options.jobId = `event:${projectId}:${deviceId}:${Date.now()}`;
}
contextLogger.send('event is queued', {
contextLogger.send("event is queued", {
ip,
origin,
ua,
@@ -312,14 +312,14 @@ export async function postEvent(
// Queue current event
eventsQueue
.add(
'event',
"event",
{
type: 'createEvent',
type: "createEvent",
payload,
},
options
options,
)
.catch(noop('Failed to queue event'));
.catch(noop("Failed to queue event"));
reply.status(202).send(deviceId);
}