import { alphabetIds, deprecated_timeRanges, lineTypes, } from '@openpanel/constants'; import type { IChartBreakdown, IChartEventFilter, IChartEventItem, IChartLineType, IChartRange, IReport, IReportOptions, } from '@openpanel/validation'; import type { Report as DbReport, ReportLayout } from '../prisma-client'; import { db } from '../prisma-client'; export type IServiceReport = Awaited>; export const onlyReportEvents = ( series: NonNullable['series'], ) => { return series.filter((item) => item.type === 'event'); }; export function transformFilter( filter: Partial, index: number, ): IChartEventFilter { return { id: filter.id ?? alphabetIds[index] ?? 'A', name: filter.name ?? 'Unknown Filter', operator: filter.operator ?? 'is', value: typeof filter.value === 'string' ? [filter.value] : (filter.value ?? []), }; } export function transformReportEventItem( item: IChartEventItem, index: number, ): IChartEventItem { if (item.type === 'formula') { // Transform formula return { type: 'formula', id: item.id ?? alphabetIds[index]!, formula: item.formula || '', displayName: item.displayName, }; } // Transform event with type field return { type: 'event', segment: item.segment ?? 'event', filters: (item.filters ?? []).map(transformFilter), id: item.id ?? alphabetIds[index]!, name: item.name || 'unknown_event', displayName: item.displayName, property: item.property, }; } export function transformReport( report: DbReport & { layout?: ReportLayout | null }, ): IReport & { id: string; layout?: ReportLayout | null; } { const options = report.options as IReportOptions | null | undefined; return { id: report.id, projectId: report.projectId, name: report.name || 'Untitled', chartType: report.chartType, lineType: (report.lineType as IChartLineType) ?? lineTypes.monotone, interval: report.interval, series: (report.events as IChartEventItem[]).map(transformReportEventItem) ?? [], breakdowns: report.breakdowns as IChartBreakdown[], range: report.range in deprecated_timeRanges ? '30d' : (report.range as IChartRange), previous: report.previous ?? false, formula: report.formula ?? undefined, metric: report.metric ?? 'sum', unit: report.unit ?? undefined, layout: report.layout ?? undefined, options: options ?? undefined, }; } export function getReportsByDashboardId(dashboardId: string) { return db.report .findMany({ where: { dashboardId, }, include: { layout: true, }, }) .then((reports) => reports.map(transformReport)); } export async function getReportById(id: string) { const report = await db.report.findUnique({ where: { id, }, include: { layout: true, }, }); if (!report) { return null; } return transformReport(report); }