From 8bbf36473bde1b7f9aff733cae2be8d5c151d116 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl-Gerhard=20Lindesva=CC=88rd?= Date: Sun, 26 Jan 2025 07:15:51 +0000 Subject: [PATCH] improve(export): improve docs for export and add some default values --- apps/api/src/controllers/export.controller.ts | 45 ++++++++++++----- apps/public/content/docs/api/export.mdx | 49 ++++++++++++++++++- 2 files changed, 80 insertions(+), 14 deletions(-) diff --git a/apps/api/src/controllers/export.controller.ts b/apps/api/src/controllers/export.controller.ts index 9dc30348..259aa2d4 100644 --- a/apps/api/src/controllers/export.controller.ts +++ b/apps/api/src/controllers/export.controller.ts @@ -10,7 +10,11 @@ import { getEventsCountCached, } from '@openpanel/db'; import { getChart } from '@openpanel/trpc/src/routers/chart.helpers'; -import { zChartInput } from '@openpanel/validation'; +import { + zChartEvent, + zChartEventFilter, + zChartInput, +} from '@openpanel/validation'; import { omit } from 'ramda'; async function getProjectId( @@ -140,16 +144,26 @@ export async function events( }); } -const chartSchemeFull = zChartInput.pick({ - events: true, - breakdowns: true, - projectId: true, - interval: true, - range: true, - previous: true, - startDate: true, - endDate: true, -}); +const chartSchemeFull = zChartInput + .pick({ + breakdowns: true, + projectId: true, + interval: true, + range: true, + previous: true, + startDate: true, + endDate: true, + }) + .extend({ + events: z.array( + z.object({ + name: z.string(), + filters: zChartEvent.shape.filters.optional(), + segment: zChartEvent.shape.segment.optional(), + property: zChartEvent.shape.property.optional(), + }), + ), + }); export async function charts( request: FastifyRequest<{ @@ -167,8 +181,15 @@ export async function charts( }); } + const { events, ...rest } = query.data; + return getChart({ - ...query.data, + ...rest, + events: events.map((event) => ({ + ...event, + segment: event.segment ?? 'event', + filters: event.filters ?? [], + })), chartType: 'linear', metric: 'sum', }); diff --git a/apps/public/content/docs/api/export.mdx b/apps/public/content/docs/api/export.mdx index 682f71a4..4d69c150 100644 --- a/apps/public/content/docs/api/export.mdx +++ b/apps/public/content/docs/api/export.mdx @@ -91,7 +91,7 @@ GET /export/charts | Parameter | Type | Description | Example | |-----------|------|-------------|---------| | projectId | string | The ID of the project to fetch chart data from | `abc123` | -| events | string[] | Array of event names to include in the chart | `["sign_up","purchase"]` | +| events | string[] | Array of event configurations to include in the chart | `[{"name":"sign_up","filters":[]}]` | | breakdowns | object[] | Array of breakdown configurations | `[{"name":"country"}]` | | interval | string | Time interval for data points | `day` | | range | string | Predefined date range | `last_7_days` | @@ -103,10 +103,55 @@ GET /export/charts | limit | number | Limit the number of results | `10` | | offset | number | Offset for pagination | `0` | +#### Events configuration + +Each event configuration object has the following properties: + +| Property | Type | Description | Required | +|----------|------|-------------|----------| +| name | string | Name of the event to track | Yes | +| filters | Filter[] | Array of filters to apply to the event | No | +| segment | string | Type of segmentation. Options: `event`, `user`, `session`, `user_average`, `one_event_per_user`, `property_sum`, `property_average` | No (defaults to `event`) | +| property | string | Property name to analyze when using property-based segments | No | + +##### Filter Configuration + +Each filter in the `filters` array has the following structure: + +| Property | Type | Description | Required | +|----------|------|-------------|----------| +| name | string | Name of the property to filter on | Yes | +| operator | string | Comparison operator. Valid values: `is`, `isNot`, `contains`, `doesNotContain`, `startsWith`, `endsWith`, `regex` | Yes | +| value | (string \| number \| boolean \| null)[] | Array of values to compare against | Yes | + +Example event configuration: +```json +{ + "name": "purchase", + "segment": "user", + "filters": [ + { + "name": "total", + "operator": "is", + "value": ["100"] + } + ] +} +``` + +The operators are used in the SQL builder (`chart.service.ts` lines 262-346) with the following mappings: +- `is`: Equals comparison +- `isNot`: Not equals comparison +- `contains`: LIKE %value% +- `doesNotContain`: NOT LIKE %value% +- `startsWith`: LIKE value% +- `endsWith`: LIKE %value +- `regex`: Match function + ### Example Request ```bash -curl 'https://api.openpanel.dev/export/charts?projectId=abc123&events=["sign_up","purchase"]&interval=day&range=last_30_days&chartType=linear&metric=sum' \ +curl 'https://api.openpanel.dev/export/charts?projectId=abc123&events=[{"name":"screen_view"}]&interval=day&range=last_30_days&chartType=linear&metric=sum' \ -H 'openpanel-client-id: YOUR_CLIENT_ID' \ -H 'openpanel-client-secret: YOUR_CLIENT_SECRET' ```