Refactor filter handling for queries.

This commit is contained in:
Mike Cao 2025-07-02 01:44:12 -07:00
parent 5b300f1ff5
commit ee6c68d27c
107 changed files with 731 additions and 835 deletions

View file

@ -3,7 +3,7 @@ import { getRealtimeData } from '@/queries';
import { canViewWebsite } from '@/lib/auth';
import { startOfMinute, subMinutes } from 'date-fns';
import { REALTIME_RANGE } from '@/lib/constants';
import { parseRequest } from '@/lib/request';
import { parseRequest, getQueryFilters } from '@/lib/request';
export async function GET(
request: Request,
@ -16,15 +16,19 @@ export async function GET(
}
const { websiteId } = await params;
const { timezone } = query;
if (!(await canViewWebsite(auth, websiteId))) {
return unauthorized();
}
const startDate = subMinutes(startOfMinute(new Date()), REALTIME_RANGE);
const filters = await getQueryFilters({
...query,
websiteId,
startAt: subMinutes(startOfMinute(new Date()), REALTIME_RANGE).getTime(),
endAt: Date.now(),
});
const data = await getRealtimeData(websiteId, { startDate, timezone });
const data = await getRealtimeData(websiteId, filters);
return json(data);
}

View file

@ -1,6 +1,6 @@
import { canViewWebsite } from '@/lib/auth';
import { unauthorized, json } from '@/lib/response';
import { parseRequest } from '@/lib/request';
import { getQueryFilters, parseRequest } from '@/lib/request';
import { getGoal } from '@/queries/sql/reports/getGoal';
import { reportResultSchema } from '@/lib/schema';
@ -15,21 +15,22 @@ export async function POST(request: Request) {
websiteId,
dateRange: { startDate, endDate },
parameters: { type, value, property, operator },
...filters
} = body;
if (!(await canViewWebsite(auth, websiteId))) {
return unauthorized();
}
const filters = await getQueryFilters(body.filters);
const data = await getGoal(websiteId, {
...filters,
startDate: new Date(startDate),
endDate: new Date(endDate),
type,
value,
property,
operator,
filters,
});
return json(data);

View file

@ -1,7 +1,7 @@
import { z } from 'zod';
import { unauthorized, json } from '@/lib/response';
import { canViewTeam } from '@/lib/auth';
import { parseRequest } from '@/lib/request';
import { getQueryFilters, parseRequest } from '@/lib/request';
import { pagingParams } from '@/lib/schema';
import { getTeamWebsites } from '@/queries';
@ -20,7 +20,9 @@ export async function GET(request: Request, { params }: { params: Promise<{ team
return unauthorized();
}
const websites = await getTeamWebsites(teamId, query);
const filters = await getQueryFilters(query);
const websites = await getTeamWebsites(teamId, filters);
return json(websites);
}

View file

@ -3,7 +3,7 @@ import { json, unauthorized } from '@/lib/response';
import { getAllUserWebsitesIncludingTeamOwner } from '@/queries/prisma/website';
import { getEventUsage } from '@/queries/sql/events/getEventUsage';
import { getEventDataUsage } from '@/queries/sql/events/getEventDataUsage';
import { parseRequest, getRequestDateRange } from '@/lib/request';
import { parseRequest, getQueryFilters } from '@/lib/request';
export async function GET(request: Request, { params }: { params: Promise<{ userId: string }> }) {
const schema = z.object({
@ -22,14 +22,14 @@ export async function GET(request: Request, { params }: { params: Promise<{ user
}
const { userId } = await params;
const { startDate, endDate } = await getRequestDateRange(query);
const filters = await getQueryFilters(query);
const websites = await getAllUserWebsitesIncludingTeamOwner(userId);
const websiteIds = websites.map(a => a.id);
const websiteEventUsage = await getEventUsage(websiteIds, startDate, endDate);
const eventDataUsage = await getEventDataUsage(websiteIds, startDate, endDate);
const websiteEventUsage = await getEventUsage(websiteIds, filters);
const eventDataUsage = await getEventDataUsage(websiteIds, filters);
const websiteUsage = websites.map(a => ({
websiteId: a.id,

View file

@ -2,7 +2,7 @@ import { z } from 'zod';
import { unauthorized, json } from '@/lib/response';
import { getUserWebsites } from '@/queries/prisma/website';
import { pagingParams } from '@/lib/schema';
import { parseRequest } from '@/lib/request';
import { getQueryFilters, parseRequest } from '@/lib/request';
export async function GET(request: Request, { params }: { params: Promise<{ userId: string }> }) {
const schema = z.object({
@ -21,7 +21,9 @@ export async function GET(request: Request, { params }: { params: Promise<{ user
return unauthorized();
}
const websites = await getUserWebsites(userId, query);
const filters = await getQueryFilters(query);
const websites = await getUserWebsites(userId, filters);
return json(websites);
}

View file

@ -1,5 +1,5 @@
import { z } from 'zod';
import { getRequestDateRange, parseRequest } from '@/lib/request';
import { getQueryFilters, parseRequest } from '@/lib/request';
import { unauthorized, json } from '@/lib/response';
import { canViewWebsite } from '@/lib/auth';
import { getEventDataEvents } from '@/queries/sql/events/getEventDataEvents';
@ -20,16 +20,16 @@ export async function GET(
}
const { websiteId } = await params;
const { event } = query;
const { startDate, endDate } = await getRequestDateRange(query);
if (!(await canViewWebsite(auth, websiteId))) {
return unauthorized();
}
const { event } = query;
const filters = await getQueryFilters(query);
const data = await getEventDataEvents(websiteId, {
startDate,
endDate,
...filters,
event,
});

View file

@ -1,5 +1,5 @@
import { z } from 'zod';
import { getRequestDateRange, parseRequest } from '@/lib/request';
import { getQueryFilters, parseRequest } from '@/lib/request';
import { unauthorized, json } from '@/lib/response';
import { canViewWebsite } from '@/lib/auth';
import { getEventDataFields } from '@/queries';
@ -20,16 +20,14 @@ export async function GET(
}
const { websiteId } = await params;
const { startDate, endDate } = await getRequestDateRange(query);
if (!(await canViewWebsite(auth, websiteId))) {
return unauthorized();
}
const data = await getEventDataFields(websiteId, {
startDate,
endDate,
});
const filters = await getQueryFilters(query);
const data = await getEventDataFields(websiteId, filters);
return json(data);
}

View file

@ -1,5 +1,5 @@
import { z } from 'zod';
import { getRequestDateRange, parseRequest } from '@/lib/request';
import { getQueryFilters, parseRequest } from '@/lib/request';
import { unauthorized, json } from '@/lib/response';
import { canViewWebsite } from '@/lib/auth';
import { getEventDataProperties } from '@/queries';
@ -21,14 +21,15 @@ export async function GET(
}
const { websiteId } = await params;
const { propertyName } = query;
const { startDate, endDate } = await getRequestDateRange(query);
if (!(await canViewWebsite(auth, websiteId))) {
return unauthorized();
}
const data = await getEventDataProperties(websiteId, { startDate, endDate, propertyName });
const { propertyName } = query;
const filters = await getQueryFilters(query);
const data = await getEventDataProperties(websiteId, { ...filters, propertyName });
return json(data);
}

View file

@ -1,5 +1,5 @@
import { z } from 'zod';
import { getRequestDateRange, parseRequest } from '@/lib/request';
import { getQueryFilters, parseRequest } from '@/lib/request';
import { unauthorized, json } from '@/lib/response';
import { canViewWebsite } from '@/lib/auth';
import { getEventDataStats } from '@/queries';
@ -21,13 +21,14 @@ export async function GET(
}
const { websiteId } = await params;
const { startDate, endDate } = await getRequestDateRange(query);
if (!(await canViewWebsite(auth, websiteId))) {
return unauthorized();
}
const data = await getEventDataStats(websiteId, { startDate, endDate });
const filters = await getQueryFilters(query);
const data = await getEventDataStats(websiteId, filters);
return json(data);
}

View file

@ -1,5 +1,5 @@
import { z } from 'zod';
import { getRequestDateRange, parseRequest } from '@/lib/request';
import { getQueryFilters, parseRequest } from '@/lib/request';
import { unauthorized, json } from '@/lib/response';
import { canViewWebsite } from '@/lib/auth';
import { getEventDataValues } from '@/queries';
@ -22,16 +22,16 @@ export async function GET(
}
const { websiteId } = await params;
const { eventName, propertyName } = query;
const { startDate, endDate } = await getRequestDateRange(query);
if (!(await canViewWebsite(auth, websiteId))) {
return unauthorized();
}
const { eventName, propertyName } = query;
const filters = await getQueryFilters(query);
const data = await getEventDataValues(websiteId, {
startDate,
endDate,
...filters,
eventName,
propertyName,
});

View file

@ -1,5 +1,5 @@
import { z } from 'zod';
import { getRequestDateRange, parseRequest } from '@/lib/request';
import { getQueryFilters, parseRequest } from '@/lib/request';
import { unauthorized, json } from '@/lib/response';
import { canViewWebsite } from '@/lib/auth';
import { pagingParams } from '@/lib/schema';
@ -22,13 +22,14 @@ export async function GET(
}
const { websiteId } = await params;
const { startDate, endDate } = await getRequestDateRange(query);
if (!(await canViewWebsite(auth, websiteId))) {
return unauthorized();
}
const data = await getWebsiteEvents(websiteId, { ...query, startDate, endDate }, query);
const filters = await getQueryFilters(query);
const data = await getWebsiteEvents(websiteId, filters);
return json(data);
}

View file

@ -1,5 +1,5 @@
import { z } from 'zod';
import { parseRequest, getRequestDateRange, getRequestFilters } from '@/lib/request';
import { parseRequest, getQueryFilters } from '@/lib/request';
import { unauthorized, json } from '@/lib/response';
import { canViewWebsite } from '@/lib/auth';
import { filterParams, timezoneParam, unitParam } from '@/lib/schema';
@ -24,20 +24,12 @@ export async function GET(
}
const { websiteId } = await params;
const { timezone } = query;
const { startDate, endDate, unit } = await getRequestDateRange(query);
if (!(await canViewWebsite(auth, websiteId))) {
return unauthorized();
}
const filters = {
...getRequestFilters(query),
startDate,
endDate,
timezone,
unit,
};
const filters = await getQueryFilters({ ...query, websiteId });
const data = await getEventMetrics(websiteId, filters);

View file

@ -13,7 +13,7 @@ import {
VIDEO_DOMAINS,
PAID_AD_PARAMS,
} from '@/lib/constants';
import { getRequestFilters, getRequestDateRange, parseRequest } from '@/lib/request';
import { parseRequest, getQueryFilters } from '@/lib/request';
import { json, unauthorized, badRequest } from '@/lib/response';
import { getPageviewMetrics, getSessionMetrics, getChannelMetrics } from '@/queries';
import { filterParams } from '@/lib/schema';
@ -45,13 +45,8 @@ export async function GET(
return unauthorized();
}
const { startDate, endDate } = await getRequestDateRange(query);
const column = FILTER_COLUMNS[type] || type;
const filters = {
...getRequestFilters(query),
startDate,
endDate,
};
const filters = await getQueryFilters({ ...query, websiteId });
if (search) {
filters[type] = {

View file

@ -1,7 +1,7 @@
import { z } from 'zod';
import { canViewWebsite } from '@/lib/auth';
import { getRequestFilters, getRequestDateRange, parseRequest } from '@/lib/request';
import { unitParam, timezoneParam, filterParams } from '@/lib/schema';
import { getQueryFilters, parseRequest } from '@/lib/request';
import { dateRangeParams, filterParams } from '@/lib/schema';
import { getCompareDate } from '@/lib/date';
import { unauthorized, json } from '@/lib/response';
import { getPageviewStats, getSessionStats } from '@/queries';
@ -11,11 +11,7 @@ export async function GET(
{ params }: { params: Promise<{ websiteId: string }> },
) {
const schema = z.object({
startAt: z.coerce.number().int(),
endAt: z.coerce.number().int(),
unit: unitParam,
timezone: timezoneParam,
compare: z.string().optional(),
...dateRangeParams,
...filterParams,
});
@ -26,32 +22,23 @@ export async function GET(
}
const { websiteId } = await params;
const { timezone, compare } = query;
if (!(await canViewWebsite(auth, websiteId))) {
return unauthorized();
}
const { startDate, endDate, unit } = await getRequestDateRange(query);
const filters = {
...getRequestFilters(query),
startDate,
endDate,
timezone,
unit,
};
const filters = await getQueryFilters({ ...query, websiteId });
const [pageviews, sessions] = await Promise.all([
getPageviewStats(websiteId, filters),
getSessionStats(websiteId, filters),
]);
if (compare) {
if (filters.compare) {
const { startDate: compareStartDate, endDate: compareEndDate } = getCompareDate(
compare,
startDate,
endDate,
filters.compare,
filters.startDate,
filters.endDate,
);
const [comparePageviews, compareSessions] = await Promise.all([
@ -70,8 +57,8 @@ export async function GET(
return json({
pageviews,
sessions,
startDate,
endDate,
startDate: filters.startDate,
endDate: filters.endDate,
compare: {
pageviews: comparePageviews,
sessions: compareSessions,

View file

@ -1,5 +1,5 @@
import { z } from 'zod';
import { getRequestDateRange, parseRequest } from '@/lib/request';
import { getQueryFilters, parseRequest } from '@/lib/request';
import { unauthorized, json } from '@/lib/response';
import { canViewWebsite } from '@/lib/auth';
import { getSessionDataProperties } from '@/queries';
@ -22,13 +22,13 @@ export async function GET(
const { websiteId } = await params;
const { propertyName } = query;
const { startDate, endDate } = await getRequestDateRange(query);
const filters = await getQueryFilters(query);
if (!(await canViewWebsite(auth, websiteId))) {
return unauthorized();
}
const data = await getSessionDataProperties(websiteId, { startDate, endDate, propertyName });
const data = await getSessionDataProperties(websiteId, { ...filters, propertyName });
return json(data);
}

View file

@ -1,5 +1,5 @@
import { canViewWebsite } from '@/lib/auth';
import { getRequestDateRange, parseRequest } from '@/lib/request';
import { getQueryFilters, parseRequest } from '@/lib/request';
import { json, unauthorized } from '@/lib/response';
import { getSessionDataValues } from '@/queries';
import { z } from 'zod';
@ -22,15 +22,14 @@ export async function GET(
const { propertyName } = query;
const { websiteId } = await params;
const { startDate, endDate } = await getRequestDateRange(query);
const filters = await getQueryFilters({ ...query, websiteId });
if (!(await canViewWebsite(auth, websiteId))) {
return unauthorized();
}
const data = await getSessionDataValues(websiteId, {
startDate,
endDate,
...filters,
propertyName,
});

View file

@ -1,5 +1,5 @@
import { z } from 'zod';
import { parseRequest, getRequestDateRange } from '@/lib/request';
import { parseRequest, getQueryFilters } from '@/lib/request';
import { unauthorized, json } from '@/lib/response';
import { canViewWebsite } from '@/lib/auth';
import { getSessionActivity } from '@/queries';
@ -20,13 +20,14 @@ export async function GET(
}
const { websiteId, sessionId } = await params;
const { startDate, endDate } = await getRequestDateRange(query);
if (!(await canViewWebsite(auth, websiteId))) {
return unauthorized();
}
const data = await getSessionActivity(websiteId, sessionId, startDate, endDate);
const filters = await getQueryFilters(query);
const data = await getSessionActivity(websiteId, sessionId, filters);
return json(data);
}

View file

@ -1,8 +1,8 @@
import { z } from 'zod';
import { getRequestDateRange, parseRequest } from '@/lib/request';
import { getQueryFilters, parseRequest } from '@/lib/request';
import { unauthorized, json } from '@/lib/response';
import { canViewWebsite } from '@/lib/auth';
import { pagingParams } from '@/lib/schema';
import { dateRangeParams, filterParams, pagingParams } from '@/lib/schema';
import { getWebsiteSessions } from '@/queries';
export async function GET(
@ -10,8 +10,8 @@ export async function GET(
{ params }: { params: Promise<{ websiteId: string }> },
) {
const schema = z.object({
startAt: z.coerce.number().int(),
endAt: z.coerce.number().int(),
...dateRangeParams,
...filterParams,
...pagingParams,
});
@ -21,14 +21,15 @@ export async function GET(
return error();
}
const { startDate, endDate } = await getRequestDateRange(query);
const { websiteId } = await params;
if (!(await canViewWebsite(auth, websiteId))) {
return unauthorized();
}
const data = await getWebsiteSessions(websiteId, { startDate, endDate }, query);
const filters = await getQueryFilters({ ...query, websiteId });
const data = await getWebsiteSessions(websiteId, filters);
return json(data);
}

View file

@ -1,5 +1,5 @@
import { z } from 'zod';
import { parseRequest, getRequestDateRange, getRequestFilters } from '@/lib/request';
import { parseRequest, getQueryFilters } from '@/lib/request';
import { unauthorized, json } from '@/lib/response';
import { canViewWebsite } from '@/lib/auth';
import { filterParams } from '@/lib/schema';
@ -27,15 +27,9 @@ export async function GET(
return unauthorized();
}
const { startDate, endDate } = await getRequestDateRange(query);
const filters = await getQueryFilters(query);
const filters = getRequestFilters(query);
const metrics = await getWebsiteSessionStats(websiteId, {
...filters,
startDate,
endDate,
});
const metrics = await getWebsiteSessionStats(websiteId, filters);
const data = Object.keys(metrics[0]).reduce((obj, key) => {
obj[key] = {

View file

@ -1,5 +1,5 @@
import { z } from 'zod';
import { getRequestDateRange, parseRequest } from '@/lib/request';
import { getQueryFilters, parseRequest } from '@/lib/request';
import { unauthorized, json } from '@/lib/response';
import { canViewWebsite } from '@/lib/auth';
import { pagingParams, timezoneParam } from '@/lib/schema';
@ -23,14 +23,14 @@ export async function GET(
}
const { websiteId } = await params;
const { timezone } = query;
const { startDate, endDate } = await getRequestDateRange(query);
if (!(await canViewWebsite(auth, websiteId))) {
return unauthorized();
}
const data = await getWebsiteSessionsWeekly(websiteId, { startDate, endDate, timezone });
const filters = await getQueryFilters(query);
const data = await getWebsiteSessionsWeekly(websiteId, filters);
return json(data);
}

View file

@ -1,8 +1,7 @@
import { z } from 'zod';
import { parseRequest, getRequestDateRange, getRequestFilters } from '@/lib/request';
import { parseRequest, getQueryFilters } from '@/lib/request';
import { unauthorized, json } from '@/lib/response';
import { canViewWebsite } from '@/lib/auth';
import { getCompareDate } from '@/lib/date';
import { filterParams } from '@/lib/schema';
import { getWebsiteStats } from '@/queries';
@ -24,32 +23,20 @@ export async function GET(
}
const { websiteId } = await params;
const { compare } = query;
if (!(await canViewWebsite(auth, websiteId))) {
return unauthorized();
}
const { startDate, endDate } = await getRequestDateRange(query);
const { startDate: compareStartDate, endDate: compareEndDate } = getCompareDate(
compare,
startDate,
endDate,
);
const filters = await getQueryFilters({ ...query, websiteId });
const filters = getRequestFilters(query);
const metrics = await getWebsiteStats(websiteId, {
...filters,
startDate,
endDate,
});
const data = await getWebsiteStats(websiteId, filters);
const previous = await getWebsiteStats(websiteId, {
...filters,
startDate: compareStartDate,
endDate: compareEndDate,
startDate: filters.compareStartDate,
endDate: filters.compareEndDate,
});
return json({ ...metrics, previous });
return json({ ...data, previous });
}

View file

@ -2,7 +2,7 @@ import { z } from 'zod';
import { canViewWebsite } from '@/lib/auth';
import { EVENT_COLUMNS, FILTER_COLUMNS, SESSION_COLUMNS } from '@/lib/constants';
import { getValues } from '@/queries';
import { parseRequest, getRequestDateRange } from '@/lib/request';
import { parseRequest, getQueryFilters } from '@/lib/request';
import { badRequest, json, unauthorized } from '@/lib/response';
export async function GET(
@ -23,7 +23,7 @@ export async function GET(
}
const { websiteId } = await params;
const { type, search } = query;
const { type } = query;
if (!(await canViewWebsite(auth, websiteId))) {
return unauthorized();
@ -33,9 +33,9 @@ export async function GET(
return badRequest('Invalid type.');
}
const { startDate, endDate } = await getRequestDateRange(query);
const filters = await getQueryFilters(query);
const values = await getValues(websiteId, FILTER_COLUMNS[type], startDate, endDate, search);
const values = await getValues(websiteId, FILTER_COLUMNS[type], { ...filters });
return json(values.filter(n => n).sort());
}