mirror of
https://github.com/kremalicious/umami.git
synced 2024-11-15 09:45:04 +01:00
Add user usage.
This commit is contained in:
parent
c41fb5ee1b
commit
9e2a478001
74
pages/api/users/[id]/usage.ts
Normal file
74
pages/api/users/[id]/usage.ts
Normal file
@ -0,0 +1,74 @@
|
||||
import { useAuth, useCors } from 'lib/middleware';
|
||||
import { NextApiRequestQueryBody } from 'lib/types';
|
||||
import { NextApiResponse } from 'next';
|
||||
import { methodNotAllowed, ok, unauthorized } from 'next-basics';
|
||||
import { getEventDataUsage, getEventUsage, getUserWebsites } from 'queries';
|
||||
|
||||
export interface UserUsageRequestQuery {
|
||||
id: string;
|
||||
startAt: string;
|
||||
endAt: string;
|
||||
}
|
||||
|
||||
export interface UserUsageRequestResponse {
|
||||
websiteEventUsage: number;
|
||||
eventDataUsage: number;
|
||||
websites: {
|
||||
websiteEventUsage: number;
|
||||
eventDataUsage: number;
|
||||
websiteId: string;
|
||||
websiteName: string;
|
||||
}[];
|
||||
}
|
||||
|
||||
export default async (
|
||||
req: NextApiRequestQueryBody<UserUsageRequestQuery>,
|
||||
res: NextApiResponse<UserUsageRequestResponse>,
|
||||
) => {
|
||||
await useCors(req, res);
|
||||
await useAuth(req, res);
|
||||
|
||||
const { user } = req.auth;
|
||||
|
||||
if (req.method === 'GET') {
|
||||
if (!user.isAdmin) {
|
||||
return unauthorized(res);
|
||||
}
|
||||
|
||||
const { id: userId, startAt, endAt } = req.query;
|
||||
|
||||
const startDate = new Date(+startAt);
|
||||
const endDate = new Date(+endAt);
|
||||
|
||||
const websites = await getUserWebsites(userId);
|
||||
|
||||
const websiteIds = websites.map(a => a.id);
|
||||
|
||||
const websiteEventUsage = await getEventUsage(websiteIds, startDate, endDate);
|
||||
const eventDataUsage = await getEventDataUsage(websiteIds, startDate, endDate);
|
||||
|
||||
const websiteUsage = websites.map(a => ({
|
||||
websiteId: a.id,
|
||||
websiteName: a.name,
|
||||
websiteEventUsage: websiteEventUsage.find(b => a.id === b.websiteId)?.count || 0,
|
||||
eventDataUsage: eventDataUsage.find(b => a.id === b.websiteId)?.count || 0,
|
||||
}));
|
||||
|
||||
const usage = websiteUsage.reduce(
|
||||
(acc, cv) => {
|
||||
acc.websiteEventUsage += cv.websiteEventUsage;
|
||||
acc.eventDataUsage += cv.eventDataUsage;
|
||||
|
||||
return acc;
|
||||
},
|
||||
{ websiteEventUsage: 0, eventDataUsage: 0 },
|
||||
);
|
||||
|
||||
return ok(res, {
|
||||
...usage,
|
||||
websites: websiteUsage,
|
||||
});
|
||||
}
|
||||
|
||||
return methodNotAllowed(res);
|
||||
};
|
@ -4,14 +4,14 @@ import { NextApiResponse } from 'next';
|
||||
import { methodNotAllowed, ok, unauthorized } from 'next-basics';
|
||||
import { getUserWebsites } from 'queries';
|
||||
|
||||
export interface WebsitesRequestBody {
|
||||
export interface UserWebsitesRequestBody {
|
||||
name: string;
|
||||
domain: string;
|
||||
shareId: string;
|
||||
}
|
||||
|
||||
export default async (
|
||||
req: NextApiRequestQueryBody<any, WebsitesRequestBody>,
|
||||
req: NextApiRequestQueryBody<any, UserWebsitesRequestBody>,
|
||||
res: NextApiResponse,
|
||||
) => {
|
||||
await useCors(req, res);
|
||||
|
32
queries/analytics/event/getEventUsage.ts
Normal file
32
queries/analytics/event/getEventUsage.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import clickhouse from 'lib/clickhouse';
|
||||
import { CLICKHOUSE, PRISMA, runQuery } from 'lib/db';
|
||||
|
||||
export function getEventUsage(...args: [websiteIds: string[], startDate: Date, endDate: Date]) {
|
||||
return runQuery({
|
||||
[PRISMA]: () => relationalQuery(...args),
|
||||
[CLICKHOUSE]: () => clickhouseQuery(...args),
|
||||
});
|
||||
}
|
||||
|
||||
function relationalQuery(websiteIds: string[], startDate: Date, endDate: Date) {
|
||||
throw new Error('Not Implemented');
|
||||
}
|
||||
|
||||
function clickhouseQuery(websiteIds: string[], startDate: Date, endDate: Date) {
|
||||
const { rawQuery } = clickhouse;
|
||||
|
||||
return rawQuery(
|
||||
`select
|
||||
website_id as websiteId,
|
||||
count(*) as count
|
||||
from website_event
|
||||
where created_at between {startDate:DateTime64} and {endDate:DateTime64}
|
||||
and website_id in {websiteIds:Array(UUID)}
|
||||
group by website_id`,
|
||||
{
|
||||
websiteIds,
|
||||
startDate,
|
||||
endDate,
|
||||
},
|
||||
);
|
||||
}
|
32
queries/analytics/eventData/getEventDataUsage.ts
Normal file
32
queries/analytics/eventData/getEventDataUsage.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import clickhouse from 'lib/clickhouse';
|
||||
import { CLICKHOUSE, PRISMA, runQuery } from 'lib/db';
|
||||
|
||||
export function getEventDataUsage(...args: [websiteIds: string[], startDate: Date, endDate: Date]) {
|
||||
return runQuery({
|
||||
[PRISMA]: () => relationalQuery(...args),
|
||||
[CLICKHOUSE]: () => clickhouseQuery(...args),
|
||||
});
|
||||
}
|
||||
|
||||
function relationalQuery(websiteIds: string[], startDate: Date, endDate: Date) {
|
||||
throw new Error('Not Implemented');
|
||||
}
|
||||
|
||||
function clickhouseQuery(websiteIds: string[], startDate: Date, endDate: Date) {
|
||||
const { rawQuery } = clickhouse;
|
||||
|
||||
return rawQuery(
|
||||
`select
|
||||
website_id as websiteId,
|
||||
count(*) as count
|
||||
from event_data
|
||||
where created_at between {startDate:DateTime64} and {endDate:DateTime64}
|
||||
and website_id in {websiteIds:Array(UUID)}
|
||||
group by website_id`,
|
||||
{
|
||||
websiteIds,
|
||||
startDate,
|
||||
endDate,
|
||||
},
|
||||
);
|
||||
}
|
@ -3,8 +3,10 @@ export * from './admin/teamUser';
|
||||
export * from './admin/user';
|
||||
export * from './admin/website';
|
||||
export * from './analytics/event/getEventMetrics';
|
||||
export * from './analytics/event/getEventUsage';
|
||||
export * from './analytics/event/getEvents';
|
||||
export * from './analytics/eventData/getEventData';
|
||||
export * from './analytics/eventData/getEventDataUsage';
|
||||
export * from './analytics/event/saveEvent';
|
||||
export * from './analytics/pageview/getPageviewMetrics';
|
||||
export * from './analytics/pageview/getPageviewStats';
|
||||
|
Loading…
Reference in New Issue
Block a user