* fix: how we fetch profiles in the buffer * perf: optimize event buffer * remove unused file * fix * wip * wip: try groupmq 2 * try simplified event buffer with duration calculation on the fly instead
112 lines
2.2 KiB
TypeScript
112 lines
2.2 KiB
TypeScript
import { cacheable } from '@openpanel/redis';
|
|
import sqlstring from 'sqlstring';
|
|
import { chQuery, TABLE_NAMES } from '../clickhouse/client';
|
|
import type { Prisma, Project } from '../prisma-client';
|
|
import { db } from '../prisma-client';
|
|
|
|
export type IServiceProject = Project;
|
|
export type IServiceProjectWithClients = Prisma.ProjectGetPayload<{
|
|
include: {
|
|
clients: true;
|
|
};
|
|
}>;
|
|
|
|
export async function getProjectById(id: string) {
|
|
const res = await db.project.findUnique({
|
|
where: {
|
|
id,
|
|
},
|
|
});
|
|
|
|
if (!res) {
|
|
return null;
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
/** L1 LRU (60s) + L2 Redis. clear() invalidates Redis + local LRU; other nodes may serve stale from LRU for up to 60s. */
|
|
export const getProjectByIdCached = cacheable(getProjectById, 60 * 60 * 24);
|
|
|
|
export async function getProjectWithClients(id: string) {
|
|
const res = await db.$primary().project.findUnique({
|
|
where: {
|
|
id,
|
|
},
|
|
include: {
|
|
clients: true,
|
|
},
|
|
});
|
|
|
|
if (!res) {
|
|
return null;
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
export function getProjectsByOrganizationId(organizationId: string) {
|
|
return db.project.findMany({
|
|
where: {
|
|
organizationId,
|
|
},
|
|
orderBy: {
|
|
eventsCount: 'desc',
|
|
},
|
|
});
|
|
}
|
|
|
|
export async function getProjects({
|
|
organizationId,
|
|
userId,
|
|
}: {
|
|
organizationId: string;
|
|
userId: string | null;
|
|
}) {
|
|
if (!userId) {
|
|
return [];
|
|
}
|
|
|
|
const [projects, members, access] = await Promise.all([
|
|
db.project.findMany({
|
|
where: {
|
|
organizationId,
|
|
},
|
|
orderBy: {
|
|
eventsCount: 'desc',
|
|
},
|
|
}),
|
|
db.member.findMany({
|
|
where: {
|
|
userId,
|
|
organizationId,
|
|
},
|
|
}),
|
|
db.projectAccess.findMany({
|
|
where: {
|
|
userId,
|
|
organizationId,
|
|
},
|
|
}),
|
|
]);
|
|
|
|
if (members.length === 0) {
|
|
return [];
|
|
}
|
|
|
|
if (access.length > 0) {
|
|
return projects.filter((project) =>
|
|
access.some((a) => a.projectId === project.id)
|
|
);
|
|
}
|
|
|
|
return projects;
|
|
}
|
|
|
|
export const getProjectEventsCount = async (projectId: string) => {
|
|
const res = await chQuery<{ count: number }>(
|
|
`SELECT count(*) as count FROM ${TABLE_NAMES.events} WHERE project_id = ${sqlstring.escape(projectId)} AND name NOT IN ('session_start', 'session_end')`
|
|
);
|
|
return res[0]?.count;
|
|
};
|