feat: group analytics

* wip

* wip

* wip

* wip

* wip

* add buffer

* wip

* wip

* fixes

* fix

* wip

* group validation

* fix group issues

* docs: add groups
This commit is contained in:
Carl-Gerhard Lindesvärd
2026-03-20 10:46:09 +01:00
committed by GitHub
parent 88a2d876ce
commit 11e9ecac1a
99 changed files with 5944 additions and 1432 deletions

View File

@@ -26,7 +26,7 @@ export function format(
}>,
includeAlphaIds: boolean,
previousSeries: ConcreteSeries[] | null = null,
limit: number | undefined = undefined,
limit: number | undefined = undefined
): FinalChart {
const series = concreteSeries.map((cs) => {
// Find definition for this series
@@ -70,7 +70,7 @@ export function format(
const previousSerie = previousSeries?.find(
(ps) =>
ps.definitionIndex === cs.definitionIndex &&
ps.name.slice(1).join(':::') === cs.name.slice(1).join(':::'),
ps.name.slice(1).join(':::') === cs.name.slice(1).join(':::')
);
return {
@@ -89,24 +89,24 @@ export function format(
previous: {
sum: getPreviousMetric(
metrics.sum,
sum(previousSerie.data.map((d) => d.count)),
sum(previousSerie.data.map((d) => d.count))
),
average: getPreviousMetric(
metrics.average,
round(average(previousSerie.data.map((d) => d.count)), 2),
round(average(previousSerie.data.map((d) => d.count)), 2)
),
min: getPreviousMetric(
metrics.min,
min(previousSerie.data.map((d) => d.count)),
min(previousSerie.data.map((d) => d.count))
),
max: getPreviousMetric(
metrics.max,
max(previousSerie.data.map((d) => d.count)),
max(previousSerie.data.map((d) => d.count))
),
count: getPreviousMetric(
metrics.count ?? 0,
previousSerie.data.find((item) => !!item.total_count)
?.total_count ?? null,
?.total_count ?? null
),
},
}
@@ -118,7 +118,7 @@ export function format(
previous: previousSerie?.data[index]
? getPreviousMetric(
item.count,
previousSerie.data[index]?.count ?? null,
previousSerie.data[index]?.count ?? null
)
: undefined,
})),

View File

@@ -1,5 +1,5 @@
import { getPreviousMetric, groupByLabels } from '@openpanel/common';
import type { ISerieDataItem } from '@openpanel/common';
import { groupByLabels } from '@openpanel/common';
import { alphabetIds } from '@openpanel/constants';
import type {
FinalChart,
@@ -33,7 +33,7 @@ export async function executeChart(input: IReportInput): Promise<FinalChart> {
// Handle subscription end date limit
const endDate = await getOrganizationSubscriptionChartEndDate(
input.projectId,
normalized.endDate,
normalized.endDate
);
if (endDate) {
normalized.endDate = endDate;
@@ -73,6 +73,7 @@ export async function executeChart(input: IReportInput): Promise<FinalChart> {
executionPlan.definitions,
includeAlphaIds,
previousSeries,
normalized.limit
);
return response;
@@ -83,7 +84,7 @@ export async function executeChart(input: IReportInput): Promise<FinalChart> {
* Executes a simplified pipeline: normalize -> fetch aggregate -> format
*/
export async function executeAggregateChart(
input: IReportInput,
input: IReportInput
): Promise<FinalChart> {
// Stage 1: Normalize input
const normalized = await normalize(input);
@@ -91,7 +92,7 @@ export async function executeAggregateChart(
// Handle subscription end date limit
const endDate = await getOrganizationSubscriptionChartEndDate(
input.projectId,
normalized.endDate,
normalized.endDate
);
if (endDate) {
normalized.endDate = endDate;
@@ -137,7 +138,7 @@ export async function executeAggregateChart(
getAggregateChartSql(queryInput),
{
session_timezone: timezone,
},
}
);
// Fallback: if no results with breakdowns, try without breakdowns
@@ -149,7 +150,7 @@ export async function executeAggregateChart(
}),
{
session_timezone: timezone,
},
}
);
}
@@ -262,7 +263,7 @@ export async function executeAggregateChart(
getAggregateChartSql(queryInput),
{
session_timezone: timezone,
},
}
);
if (queryResult.length === 0 && normalized.breakdowns.length > 0) {
@@ -273,7 +274,7 @@ export async function executeAggregateChart(
}),
{
session_timezone: timezone,
},
}
);
}
@@ -344,7 +345,7 @@ export async function executeAggregateChart(
normalized.series,
includeAlphaIds,
previousSeries,
normalized.limit,
normalized.limit
);
return response;