add funnels
This commit is contained in:
@@ -4,6 +4,7 @@ CREATE TABLE openpanel.events (
|
||||
`device_id` String,
|
||||
`profile_id` String,
|
||||
`project_id` String,
|
||||
`session_id` String,
|
||||
`path` String,
|
||||
`referrer` String,
|
||||
`referrer_name` String,
|
||||
@@ -56,9 +57,9 @@ ORDER BY
|
||||
ALTER TABLE
|
||||
events
|
||||
ADD
|
||||
COLUMN device_id String
|
||||
COLUMN session_id String
|
||||
AFTER
|
||||
name;
|
||||
project_id;
|
||||
|
||||
ALTER TABLE
|
||||
events DROP COLUMN id;
|
||||
@@ -69,4 +70,4 @@ CREATE TABLE ba (
|
||||
`b` String
|
||||
) ENGINE MergeTree
|
||||
ORDER BY
|
||||
(a, b) SETTINGS index_granularity = 8192;
|
||||
(a, b) SETTINGS index_granularity = 8192;
|
||||
@@ -0,0 +1,2 @@
|
||||
-- AlterEnum
|
||||
ALTER TYPE "ChartType" ADD VALUE 'funnel';
|
||||
@@ -98,6 +98,7 @@ enum ChartType {
|
||||
metric
|
||||
area
|
||||
map
|
||||
funnel
|
||||
}
|
||||
|
||||
model Dashboard {
|
||||
|
||||
101
packages/db/scripts/test-funnel.ts
Normal file
101
packages/db/scripts/test-funnel.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
import { createEvent } from '../src/services/event.service';
|
||||
|
||||
function c(name: string, createdAt: Date, session_id: string) {
|
||||
return createEvent({
|
||||
name,
|
||||
deviceId: '',
|
||||
profileId: '',
|
||||
projectId: '',
|
||||
sessionId: session_id,
|
||||
properties: {},
|
||||
createdAt,
|
||||
country: '',
|
||||
city: '',
|
||||
region: '',
|
||||
continent: '',
|
||||
os: '',
|
||||
osVersion: '',
|
||||
browser: '',
|
||||
browserVersion: '',
|
||||
device: '',
|
||||
brand: '',
|
||||
model: '',
|
||||
duration: 0,
|
||||
path: '/',
|
||||
referrer: '',
|
||||
referrerName: '',
|
||||
referrerType: '',
|
||||
profile: undefined,
|
||||
meta: undefined,
|
||||
});
|
||||
}
|
||||
|
||||
async function main() {
|
||||
// Level 5
|
||||
const s = Math.random().toString(36).substring(7);
|
||||
await c('session_start', new Date('2024-02-24 10:10:00'), s);
|
||||
|
||||
// // Level 2
|
||||
// s = 's2';
|
||||
// await c('session_start', new Date('2024-02-24 10:10:00'), '');
|
||||
// await c('a', new Date('2024-02-24 10:10:00'), s);
|
||||
// await c('b', new Date('2024-02-24 10:10:02'), s);
|
||||
|
||||
// // Level 5
|
||||
// s = 's3';
|
||||
// await c('session_start', new Date('2024-02-24 10:10:00'), '');
|
||||
// await c('a', new Date('2024-02-24 10:10:00'), s);
|
||||
// await c('b', new Date('2024-02-24 10:10:02'), s);
|
||||
// await c('c', new Date('2024-02-24 10:10:03'), s);
|
||||
// await c('d', new Date('2024-02-24 10:10:04'), s);
|
||||
// await c('f', new Date('2024-02-24 10:10:10'), s);
|
||||
|
||||
// // Level 4
|
||||
// s = 's4';
|
||||
// await c('session_start', new Date('2024-02-24 10:10:00'), '');
|
||||
// await c('a', new Date('2024-02-24 10:10:00'), s);
|
||||
// await c('b', new Date('2024-02-24 10:10:02'), s);
|
||||
// await c('c', new Date('2024-02-24 10:10:03'), s);
|
||||
// await c('d', new Date('2024-02-24 10:10:04'), s);
|
||||
|
||||
// // Level 3
|
||||
// s = 's5';
|
||||
// await c('session_start', new Date('2024-02-24 10:10:00'), '');
|
||||
// await c('a', new Date('2024-02-24 10:10:00'), s);
|
||||
// await c('b', new Date('2024-02-24 10:10:02'), s);
|
||||
// await c('c', new Date('2024-02-24 10:10:03'), s);
|
||||
|
||||
// // Level 3
|
||||
// s = 's6';
|
||||
// await c('session_start', new Date('2024-02-24 10:10:00'), '');
|
||||
// await c('a', new Date('2024-02-24 10:10:00'), s);
|
||||
// await c('b', new Date('2024-02-24 10:10:02'), s);
|
||||
// await c('c', new Date('2024-02-24 10:10:03'), s);
|
||||
|
||||
// // Level 2
|
||||
// s = 's7';
|
||||
// await c('session_start', new Date('2024-02-24 10:10:00'), '');
|
||||
// await c('a', new Date('2024-02-24 10:10:00'), s);
|
||||
// await c('b', new Date('2024-02-24 10:10:02'), s);
|
||||
|
||||
// // Level 5
|
||||
// s = 's8';
|
||||
// await c('session_start', new Date('2024-02-24 10:10:00'), '');
|
||||
// await c('a', new Date('2024-02-24 10:10:00'), s);
|
||||
// await c('b', new Date('2024-02-24 10:10:02'), s);
|
||||
// await c('c', new Date('2024-02-24 10:10:03'), s);
|
||||
// await c('d', new Date('2024-02-24 10:10:04'), s);
|
||||
// await c('f', new Date('2024-02-24 10:10:10'), s);
|
||||
|
||||
// // Level 4
|
||||
// s = 's9';
|
||||
// await c('session_start', new Date('2024-02-24 10:10:00'), '');
|
||||
// await c('a', new Date('2024-02-24 10:10:00'), s);
|
||||
// await c('b', new Date('2024-02-24 10:10:02'), s);
|
||||
// await c('c', new Date('2024-02-24 10:10:03'), s);
|
||||
// await c('d', new Date('2024-02-24 10:10:04'), s);
|
||||
|
||||
process.exit();
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -24,6 +24,7 @@ export interface IClickhouseEvent {
|
||||
device_id: string;
|
||||
profile_id: string;
|
||||
project_id: string;
|
||||
session_id: string;
|
||||
path: string;
|
||||
referrer: string;
|
||||
referrer_name: string;
|
||||
@@ -56,6 +57,7 @@ export function transformEvent(
|
||||
deviceId: event.device_id,
|
||||
profileId: event.profile_id,
|
||||
projectId: event.project_id,
|
||||
sessionId: event.session_id,
|
||||
properties: event.properties,
|
||||
createdAt: convertClickhouseDateToJs(event.created_at),
|
||||
country: event.country,
|
||||
@@ -84,6 +86,7 @@ export interface IServiceCreateEventPayload {
|
||||
deviceId: string;
|
||||
profileId: string;
|
||||
projectId: string;
|
||||
sessionId: string;
|
||||
properties: Record<string, unknown> & {
|
||||
hash?: string;
|
||||
query?: Record<string, unknown>;
|
||||
@@ -162,7 +165,7 @@ export async function createEvent(
|
||||
);
|
||||
|
||||
const exists = await getProfileById(payload.profileId);
|
||||
if (!exists) {
|
||||
if (!exists && payload.profileId !== '') {
|
||||
const { firstName, lastName } = randomSplitName();
|
||||
await upsertProfile({
|
||||
id: payload.profileId,
|
||||
@@ -198,6 +201,7 @@ export async function createEvent(
|
||||
device_id: payload.deviceId,
|
||||
profile_id: payload.profileId,
|
||||
project_id: payload.projectId,
|
||||
session_id: payload.sessionId,
|
||||
properties: toDots(omit(['_path'], payload.properties)),
|
||||
path: payload.path ?? '',
|
||||
created_at: formatClickhouseDate(payload.createdAt),
|
||||
|
||||
@@ -6,6 +6,10 @@ import { createSqlBuilder } from '../sql-builder';
|
||||
import { getEventFiltersWhereClause } from './chart.service';
|
||||
|
||||
export async function getProfileById(id: string) {
|
||||
if (id === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
const [profile] = await chQuery<IClickhouseProfile>(
|
||||
`SELECT * FROM profiles WHERE id = '${id}' ORDER BY created_at DESC LIMIT 1`
|
||||
);
|
||||
|
||||
@@ -14,7 +14,7 @@ export function createSqlBuilder() {
|
||||
|
||||
const sb: SqlBuilderObject = {
|
||||
where: {},
|
||||
from: 'openpanel.events',
|
||||
from: 'events',
|
||||
select: {},
|
||||
groupBy: {},
|
||||
orderBy: {},
|
||||
|
||||
Reference in New Issue
Block a user