mirror of
https://github.com/Litlyx/litlyx
synced 2025-12-10 07:48:37 +01:00
[NOT READY] fix dates + charts + ui
This commit is contained in:
@@ -7,7 +7,7 @@ export default defineEventHandler(async event => {
|
||||
const data = await getRequestData(event, { requireSchema: false, requireSlice: true });
|
||||
if (!data) return;
|
||||
|
||||
const { pid, from, to, slice, project_id } = data;
|
||||
const { pid, from, to, slice, project_id, timeOffset } = data;
|
||||
|
||||
const cacheKey = `timeline:events:${pid}:${slice}:${from}:${to}`;
|
||||
const cacheExp = 60;
|
||||
@@ -16,7 +16,7 @@ export default defineEventHandler(async event => {
|
||||
const timelineData = await executeTimelineAggregation({
|
||||
projectId: project_id,
|
||||
model: EventModel,
|
||||
from, to, slice
|
||||
from, to, slice, timeOffset
|
||||
});
|
||||
return timelineData;
|
||||
});
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { EventModel } from "@schema/metrics/EventSchema";
|
||||
import { Redis, TIMELINE_EXPIRE_TIME } from "~/server/services/CacheService";
|
||||
import { executeAdvancedTimelineAggregation} from "~/server/services/TimelineService";
|
||||
import { executeAdvancedTimelineAggregation } from "~/server/services/TimelineService";
|
||||
|
||||
export default defineEventHandler(async event => {
|
||||
|
||||
const data = await getRequestData(event, { requireSchema: false, requireSlice: true });
|
||||
if (!data) return;
|
||||
|
||||
const { from, to, slice, project_id } = data;
|
||||
const { from, to, slice, project_id, timeOffset } = data;
|
||||
|
||||
return await Redis.useCache({ key: `timeline:events_stacked:${project_id}:${slice}:${from || 'none'}:${to || 'none'}`, exp: TIMELINE_EXPIRE_TIME }, async () => {
|
||||
|
||||
@@ -17,6 +17,7 @@ export default defineEventHandler(async event => {
|
||||
from, to, slice,
|
||||
customProjection: { name: "$_id.name" },
|
||||
customIdGroup: { name: '$name' },
|
||||
timeOffset
|
||||
})
|
||||
|
||||
return timelineStackedEvents;
|
||||
|
||||
@@ -7,7 +7,7 @@ export default defineEventHandler(async event => {
|
||||
const data = await getRequestData(event, { requireSchema: false, requireSlice: true });
|
||||
if (!data) return;
|
||||
|
||||
const { pid, from, to, slice, project_id } = data;
|
||||
const { pid, from, to, slice, project_id, timeOffset } = data;
|
||||
|
||||
const cacheKey = `timeline:sessions:${pid}:${slice}:${from}:${to}`;
|
||||
const cacheExp = 60;
|
||||
@@ -16,7 +16,7 @@ export default defineEventHandler(async event => {
|
||||
const timelineData = await executeTimelineAggregation({
|
||||
projectId: project_id,
|
||||
model: SessionModel,
|
||||
from, to, slice,
|
||||
from, to, slice, timeOffset
|
||||
});
|
||||
return timelineData;
|
||||
});
|
||||
|
||||
@@ -7,7 +7,7 @@ export default defineEventHandler(async event => {
|
||||
const data = await getRequestData(event, { requireSchema: false, requireSlice: true });
|
||||
if (!data) return;
|
||||
|
||||
const { pid, from, to, slice, project_id } = data;
|
||||
const { pid, from, to, slice, project_id, timeOffset } = data;
|
||||
|
||||
const cacheKey = `timeline:sessions_duration:${pid}:${slice}:${from}:${to}`;
|
||||
const cacheExp = 60;
|
||||
|
||||
@@ -7,7 +7,7 @@ export default defineEventHandler(async event => {
|
||||
const data = await getRequestData(event, { requireSchema: false, requireSlice: true });
|
||||
if (!data) return;
|
||||
|
||||
const { pid, from, to, slice, project_id } = data;
|
||||
const { pid, from, to, slice, project_id, timeOffset } = data;
|
||||
|
||||
const cacheKey = `timeline:visits:${pid}:${slice}:${from}:${to}`;
|
||||
const cacheExp = 60;
|
||||
@@ -16,7 +16,7 @@ export default defineEventHandler(async event => {
|
||||
const timelineData = await executeTimelineAggregation({
|
||||
projectId: project_id,
|
||||
model: VisitModel,
|
||||
from, to, slice
|
||||
from, to, slice, timeOffset
|
||||
});
|
||||
return timelineData;
|
||||
});
|
||||
|
||||
@@ -10,7 +10,7 @@ export type TimelineAggregationOptions = {
|
||||
from: string | number,
|
||||
to: string | number,
|
||||
slice: Slice,
|
||||
dateOffset?: number,
|
||||
timeOffset?: number,
|
||||
debug?: boolean
|
||||
}
|
||||
|
||||
@@ -29,14 +29,13 @@ export async function executeAdvancedTimelineAggregation<T = {}>(options: Advanc
|
||||
options.customIdGroup = options.customIdGroup || {};
|
||||
|
||||
const { dateFromParts, granularity } = DateService.getGranularityData(options.slice, '$tmpDate');
|
||||
|
||||
if (!dateFromParts) throw Error('Slice is probably not correct');
|
||||
|
||||
|
||||
const [sliceValid, errorOrDays] = checkSliceValidity(options.from, options.to, options.slice);
|
||||
|
||||
if (!sliceValid) throw Error(errorOrDays);
|
||||
|
||||
const timeOffset = options.timeOffset || 0;
|
||||
|
||||
const aggregation = [
|
||||
{
|
||||
$match: {
|
||||
@@ -54,7 +53,7 @@ export async function executeAdvancedTimelineAggregation<T = {}>(options: Advanc
|
||||
$dateSubtract: {
|
||||
startDate: "$created_at",
|
||||
unit: "minute",
|
||||
amount: options.dateOffset || -60
|
||||
amount: timeOffset
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -76,8 +75,8 @@ export async function executeAdvancedTimelineAggregation<T = {}>(options: Advanc
|
||||
step: 1,
|
||||
unit: granularity,
|
||||
bounds: [
|
||||
new Date(options.from),
|
||||
new Date(options.to)
|
||||
new Date(new Date(options.from).getTime() - (timeOffset * 1000 * 60)),
|
||||
new Date(new Date(options.to).getTime() - (timeOffset * 1000 * 60) + 1),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ export type GetRequestDataOptions = {
|
||||
/** @default true */ allowLitlyx?: boolean,
|
||||
/** @default false */ requireSlice?: boolean,
|
||||
/** @default true */ requireRange?: boolean,
|
||||
/** @default false */ requireOffset?: boolean,
|
||||
}
|
||||
|
||||
async function hasAccessToProject(user_id: string, project: TProject) {
|
||||
@@ -49,6 +50,7 @@ export async function getRequestData(event: H3Event<EventHandlerRequest>, option
|
||||
const allowLitlyx = options?.allowLitlyx || true;
|
||||
const requireSlice = options?.requireSlice || false;
|
||||
const requireRange = options?.requireRange || false;
|
||||
const requireOffset = options?.requireOffset || false;
|
||||
|
||||
const pid = getHeader(event, 'x-pid');
|
||||
if (!pid) return setResponseStatus(event, 400, 'x-pid is required');
|
||||
@@ -62,6 +64,12 @@ export async function getRequestData(event: H3Event<EventHandlerRequest>, option
|
||||
if (!from || !to) return setResponseStatus(event, 400, 'x-from and x-to are required');
|
||||
}
|
||||
|
||||
const offsetRaw = getRequestHeader(event, 'x-time-offset');
|
||||
const offset = parseInt(offsetRaw?.toString() as string);
|
||||
if (requireOffset) {
|
||||
if (offset === null || offset === undefined || isNaN(offset)) return setResponseStatus(event, 400, 'x-time-offset is required');
|
||||
}
|
||||
|
||||
|
||||
let model: Model<any> = undefined as any;
|
||||
|
||||
@@ -99,7 +107,7 @@ export async function getRequestData(event: H3Event<EventHandlerRequest>, option
|
||||
return {
|
||||
from: from as string,
|
||||
to: to as string,
|
||||
pid, project_id, project, user, limit, slice, schemaName, model
|
||||
pid, project_id, project, user, limit, slice, schemaName, model, timeOffset: offset
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user