add charts to export api
This commit is contained in:
@@ -1,42 +1,39 @@
|
||||
import { parseQueryString } from '@/utils/parse-zod-query-string';
|
||||
import type { FastifyReply, FastifyRequest } from 'fastify';
|
||||
import { z } from 'zod';
|
||||
|
||||
import type { GetEventListOptions } from '@openpanel/db';
|
||||
import { ClientType, db, getEventList, getEventsCount } from '@openpanel/db';
|
||||
import { getChart } from '@openpanel/trpc/src/routers/chart';
|
||||
import { zChartInput } from '@openpanel/validation';
|
||||
|
||||
type EventsQuery = {
|
||||
project_id?: string;
|
||||
event?: string | string[];
|
||||
start?: string;
|
||||
end?: string;
|
||||
page?: string;
|
||||
limit?: string;
|
||||
};
|
||||
export async function events(
|
||||
async function getProjectId(
|
||||
request: FastifyRequest<{
|
||||
Querystring: EventsQuery;
|
||||
Querystring: {
|
||||
project_id?: string;
|
||||
projectId?: string;
|
||||
};
|
||||
}>,
|
||||
reply: FastifyReply
|
||||
) {
|
||||
const query = request.query;
|
||||
const limit = parseInt(query.limit || '50', 10);
|
||||
const page = parseInt(query.page || '1', 10);
|
||||
let projectId = request.query.projectId || request.query.project_id;
|
||||
|
||||
if (query.project_id) {
|
||||
if (projectId) {
|
||||
if (
|
||||
request.client?.type === ClientType.read &&
|
||||
request.client?.projectId !== query.project_id
|
||||
request.client?.projectId !== projectId
|
||||
) {
|
||||
reply.status(403).send({
|
||||
error: 'Forbidden',
|
||||
message: 'You do not have access to this project',
|
||||
});
|
||||
return;
|
||||
return '';
|
||||
}
|
||||
|
||||
const project = await db.project.findUnique({
|
||||
where: {
|
||||
organizationSlug: request.client?.organizationSlug,
|
||||
id: query.project_id,
|
||||
id: projectId,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -45,29 +42,64 @@ export async function events(
|
||||
error: 'Not Found',
|
||||
message: 'Project not found',
|
||||
});
|
||||
return;
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
const projectId = query.project_id ?? request.client?.projectId;
|
||||
if (!projectId && request.client?.projectId) {
|
||||
projectId = request.client?.projectId;
|
||||
}
|
||||
|
||||
if (!projectId) {
|
||||
reply.status(400).send({
|
||||
error: 'Bad Request',
|
||||
message: 'project_id is required',
|
||||
});
|
||||
return;
|
||||
return '';
|
||||
}
|
||||
|
||||
return projectId;
|
||||
}
|
||||
|
||||
const eventsScheme = z.object({
|
||||
project_id: z.string().optional(),
|
||||
projectId: z.string().optional(),
|
||||
event: z.union([z.string(), z.array(z.string())]).optional(),
|
||||
start: z.coerce.string().optional(),
|
||||
end: z.coerce.string().optional(),
|
||||
page: z.coerce.number().optional().default(1),
|
||||
limit: z.coerce.number().optional().default(50),
|
||||
});
|
||||
|
||||
export async function events(
|
||||
request: FastifyRequest<{
|
||||
Querystring: z.infer<typeof eventsScheme>;
|
||||
}>,
|
||||
reply: FastifyReply
|
||||
) {
|
||||
const query = eventsScheme.safeParse(request.query);
|
||||
|
||||
if (query.success === false) {
|
||||
return reply.status(400).send({
|
||||
error: 'Bad Request',
|
||||
message: 'Invalid query parameters',
|
||||
details: query.error.errors,
|
||||
});
|
||||
}
|
||||
|
||||
const projectId = await getProjectId(request, reply);
|
||||
const limit = query.data.limit;
|
||||
const page = Math.max(query.data.page, 1);
|
||||
const take = Math.max(Math.min(limit, 50), 1);
|
||||
const cursor = page - 1;
|
||||
const options: GetEventListOptions = {
|
||||
projectId,
|
||||
events: (Array.isArray(query.event) ? query.event : [query.event]).filter(
|
||||
(s): s is string => typeof s === 'string'
|
||||
),
|
||||
startDate: query.start ? new Date(query.start) : undefined,
|
||||
endDate: query.end ? new Date(query.end) : undefined,
|
||||
events: (Array.isArray(query.data.event)
|
||||
? query.data.event
|
||||
: [query.data.event]
|
||||
).filter((s): s is string => typeof s === 'string'),
|
||||
startDate: query.data.start ? new Date(query.data.start) : undefined,
|
||||
endDate: query.data.end ? new Date(query.data.end) : undefined,
|
||||
cursor,
|
||||
take,
|
||||
meta: false,
|
||||
@@ -89,3 +121,39 @@ export async function events(
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
const chartSchemeFull = zChartInput.pick({
|
||||
events: true,
|
||||
breakdowns: true,
|
||||
projectId: true,
|
||||
interval: true,
|
||||
range: true,
|
||||
previous: true,
|
||||
startDate: true,
|
||||
endDate: true,
|
||||
});
|
||||
|
||||
export async function charts(
|
||||
request: FastifyRequest<{
|
||||
Querystring: Record<string, string>;
|
||||
}>,
|
||||
reply: FastifyReply
|
||||
) {
|
||||
const query = chartSchemeFull.safeParse(parseQueryString(request.query));
|
||||
|
||||
if (query.success === false) {
|
||||
return reply.status(400).send({
|
||||
error: 'Bad Request',
|
||||
message: 'Invalid query parameters',
|
||||
details: query.error.errors,
|
||||
});
|
||||
}
|
||||
|
||||
return getChart({
|
||||
...query.data,
|
||||
name: 'export-api',
|
||||
metric: 'sum',
|
||||
lineType: 'monotone',
|
||||
chartType: 'linear',
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user