fixes
This commit is contained in:
@@ -74,7 +74,6 @@ const extraReferrers = {
|
|||||||
'rytr.me': { type: 'ai', name: 'Rytr' },
|
'rytr.me': { type: 'ai', name: 'Rytr' },
|
||||||
'notion.ai': { type: 'ai', name: 'Notion AI' },
|
'notion.ai': { type: 'ai', name: 'Notion AI' },
|
||||||
'grammarly.com': { type: 'ai', name: 'Grammarly' },
|
'grammarly.com': { type: 'ai', name: 'Grammarly' },
|
||||||
'bing.com': { type: 'ai', name: 'Bing AI' },
|
|
||||||
'grok.com': { type: 'ai', name: 'Grok' },
|
'grok.com': { type: 'ai', name: 'Grok' },
|
||||||
'x.ai': { type: 'ai', name: 'xAI' },
|
'x.ai': { type: 'ai', name: 'xAI' },
|
||||||
'aistudio.google.com': { type: 'ai', name: 'Google AI Studio' },
|
'aistudio.google.com': { type: 'ai', name: 'Google AI Studio' },
|
||||||
|
|||||||
@@ -167,8 +167,12 @@ export function getChartSql({
|
|||||||
const anyBreakdownOnGroup = breakdowns.some((breakdown) =>
|
const anyBreakdownOnGroup = breakdowns.some((breakdown) =>
|
||||||
breakdown.name.startsWith('group.')
|
breakdown.name.startsWith('group.')
|
||||||
);
|
);
|
||||||
|
const anyMetricOnGroup = !!event.property?.startsWith('group.');
|
||||||
const needsGroupArrayJoin =
|
const needsGroupArrayJoin =
|
||||||
anyFilterOnGroup || anyBreakdownOnGroup || event.segment === 'group';
|
anyFilterOnGroup ||
|
||||||
|
anyBreakdownOnGroup ||
|
||||||
|
anyMetricOnGroup ||
|
||||||
|
event.segment === 'group';
|
||||||
|
|
||||||
if (needsGroupArrayJoin) {
|
if (needsGroupArrayJoin) {
|
||||||
addCte(
|
addCte(
|
||||||
@@ -453,8 +457,12 @@ export function getAggregateChartSql({
|
|||||||
const anyBreakdownOnGroup = breakdowns.some((breakdown) =>
|
const anyBreakdownOnGroup = breakdowns.some((breakdown) =>
|
||||||
breakdown.name.startsWith('group.')
|
breakdown.name.startsWith('group.')
|
||||||
);
|
);
|
||||||
|
const anyMetricOnGroup = !!event.property?.startsWith('group.');
|
||||||
const needsGroupArrayJoin =
|
const needsGroupArrayJoin =
|
||||||
anyFilterOnGroup || anyBreakdownOnGroup || event.segment === 'group';
|
anyFilterOnGroup ||
|
||||||
|
anyBreakdownOnGroup ||
|
||||||
|
anyMetricOnGroup ||
|
||||||
|
event.segment === 'group';
|
||||||
|
|
||||||
if (needsGroupArrayJoin) {
|
if (needsGroupArrayJoin) {
|
||||||
addCte(
|
addCte(
|
||||||
|
|||||||
@@ -676,6 +676,7 @@ export async function getEventList(options: GetEventListOptions) {
|
|||||||
export async function getEventsCount({
|
export async function getEventsCount({
|
||||||
projectId,
|
projectId,
|
||||||
profileId,
|
profileId,
|
||||||
|
groupId,
|
||||||
events,
|
events,
|
||||||
filters,
|
filters,
|
||||||
startDate,
|
startDate,
|
||||||
@@ -687,6 +688,10 @@ export async function getEventsCount({
|
|||||||
sb.where.profileId = `profile_id = ${sqlstring.escape(profileId)}`;
|
sb.where.profileId = `profile_id = ${sqlstring.escape(profileId)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (groupId) {
|
||||||
|
sb.where.groupId = `has(groups, ${sqlstring.escape(groupId)})`;
|
||||||
|
}
|
||||||
|
|
||||||
if (startDate && endDate) {
|
if (startDate && endDate) {
|
||||||
sb.where.created_at = `toDate(created_at) BETWEEN toDate('${formatClickhouseDate(startDate)}') AND toDate('${formatClickhouseDate(endDate)}')`;
|
sb.where.created_at = `toDate(created_at) BETWEEN toDate('${formatClickhouseDate(startDate)}') AND toDate('${formatClickhouseDate(endDate)}')`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ export async function getGroupList({
|
|||||||
WHERE ${conditions.join(' AND ')}
|
WHERE ${conditions.join(' AND ')}
|
||||||
ORDER BY created_at DESC
|
ORDER BY created_at DESC
|
||||||
LIMIT ${take}
|
LIMIT ${take}
|
||||||
OFFSET ${cursor ?? 0}
|
OFFSET ${Math.max(0, (cursor ?? 0) * take)}
|
||||||
`);
|
`);
|
||||||
return rows.map(transformGroup);
|
return rows.map(transformGroup);
|
||||||
}
|
}
|
||||||
@@ -194,15 +194,19 @@ export async function updateGroup(
|
|||||||
if (!existing) {
|
if (!existing) {
|
||||||
throw new Error(`Group ${id} not found`);
|
throw new Error(`Group ${id} not found`);
|
||||||
}
|
}
|
||||||
|
const mergedProperties = {
|
||||||
|
...(existing.properties ?? {}),
|
||||||
|
...(data.properties ?? {}),
|
||||||
|
};
|
||||||
|
const normalizedProperties = toDots(
|
||||||
|
mergedProperties as Record<string, unknown>
|
||||||
|
);
|
||||||
const updated = {
|
const updated = {
|
||||||
id,
|
id,
|
||||||
projectId,
|
projectId,
|
||||||
type: data.type ?? existing.type,
|
type: data.type ?? existing.type,
|
||||||
name: data.name ?? existing.name,
|
name: data.name ?? existing.name,
|
||||||
properties: (data.properties ?? existing.properties) as Record<
|
properties: normalizedProperties,
|
||||||
string,
|
|
||||||
string
|
|
||||||
>,
|
|
||||||
createdAt: existing.createdAt,
|
createdAt: existing.createdAt,
|
||||||
};
|
};
|
||||||
await writeGroupToCh(updated);
|
await writeGroupToCh(updated);
|
||||||
@@ -314,7 +318,7 @@ export async function getGroupMemberProfiles({
|
|||||||
take: number;
|
take: number;
|
||||||
search?: string;
|
search?: string;
|
||||||
}): Promise<{ data: IServiceProfile[]; count: number }> {
|
}): Promise<{ data: IServiceProfile[]; count: number }> {
|
||||||
const offset = Math.max(0, cursor ?? 0);
|
const offset = Math.max(0, (cursor ?? 0) * take);
|
||||||
const searchCondition = search?.trim()
|
const searchCondition = search?.trim()
|
||||||
? `AND (email ILIKE ${sqlstring.escape(`%${search.trim()}%`)} OR first_name ILIKE ${sqlstring.escape(`%${search.trim()}%`)} OR last_name ILIKE ${sqlstring.escape(`%${search.trim()}%`)})`
|
? `AND (email ILIKE ${sqlstring.escape(`%${search.trim()}%`)} OR first_name ILIKE ${sqlstring.escape(`%${search.trim()}%`)} OR last_name ILIKE ${sqlstring.escape(`%${search.trim()}%`)})`
|
||||||
: '';
|
: '';
|
||||||
|
|||||||
@@ -277,10 +277,7 @@ export class OpenPanel {
|
|||||||
const mergedGroups = [...new Set([...this.groups, ...queuedGroups])];
|
const mergedGroups = [...new Set([...this.groups, ...queuedGroups])];
|
||||||
return {
|
return {
|
||||||
...item.payload,
|
...item.payload,
|
||||||
profileId:
|
profileId: item.payload.profileId ?? this.profileId,
|
||||||
'profileId' in item.payload
|
|
||||||
? (item.payload.profileId ?? this.profileId)
|
|
||||||
: this.profileId,
|
|
||||||
groups: mergedGroups.length > 0 ? mergedGroups : undefined,
|
groups: mergedGroups.length > 0 ? mergedGroups : undefined,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -291,11 +288,7 @@ export class OpenPanel {
|
|||||||
) {
|
) {
|
||||||
return {
|
return {
|
||||||
...item.payload,
|
...item.payload,
|
||||||
profileId: String(
|
profileId: item.payload.profileId ?? this.profileId,
|
||||||
'profileId' in item.payload
|
|
||||||
? (item.payload.profileId ?? this.profileId)
|
|
||||||
: (this.profileId ?? '')
|
|
||||||
),
|
|
||||||
} as TrackHandlerPayload['payload'];
|
} as TrackHandlerPayload['payload'];
|
||||||
}
|
}
|
||||||
if (item.type === 'group') {
|
if (item.type === 'group') {
|
||||||
|
|||||||
@@ -7,15 +7,15 @@ export const zGroupPayload = z.object({
|
|||||||
type: z.string().min(1),
|
type: z.string().min(1),
|
||||||
name: z.string().min(1),
|
name: z.string().min(1),
|
||||||
properties: z.record(z.unknown()).optional(),
|
properties: z.record(z.unknown()).optional(),
|
||||||
profileId: z.string().optional(),
|
profileId: z.union([z.string().min(1), z.number()]).optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const zTrackPayload = z
|
export const zTrackPayload = z
|
||||||
.object({
|
.object({
|
||||||
name: z.string().min(1),
|
name: z.string().min(1),
|
||||||
properties: z.record(z.string(), z.unknown()).optional(),
|
properties: z.record(z.string(), z.unknown()).optional(),
|
||||||
profileId: z.string().or(z.number()).optional(),
|
profileId: z.union([z.string().min(1), z.number()]).optional(),
|
||||||
groups: z.array(z.string()).optional(),
|
groups: z.array(z.string().min(1)).optional(),
|
||||||
})
|
})
|
||||||
.refine((data) => !RESERVED_EVENT_NAMES.includes(data.name as any), {
|
.refine((data) => !RESERVED_EVENT_NAMES.includes(data.name as any), {
|
||||||
message: `Event name cannot be one of the reserved names: ${RESERVED_EVENT_NAMES.join(', ')}`,
|
message: `Event name cannot be one of the reserved names: ${RESERVED_EVENT_NAMES.join(', ')}`,
|
||||||
|
|||||||
Reference in New Issue
Block a user