segment migration and support

This commit is contained in:
Francis Cao 2025-06-04 08:47:42 -07:00
parent 42be91b736
commit 1840b8b419
8 changed files with 1484 additions and 1412 deletions

View file

@ -0,0 +1,17 @@
-- CreateTable
CREATE TABLE "segment" (
"segment_id" UUID NOT NULL,
"website_id" UUID NOT NULL,
"name" VARCHAR(200) NOT NULL,
"filters" JSONB NOT NULL,
"created_at" TIMESTAMPTZ(6) DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMPTZ(6),
CONSTRAINT "segment_pkey" PRIMARY KEY ("segment_id")
);
-- CreateIndex
CREATE UNIQUE INDEX "segment_segment_id_key" ON "segment"("segment_id");
-- CreateIndex
CREATE INDEX "segment_website_id_idx" ON "segment"("website_id");

View file

@ -77,6 +77,7 @@ model Website {
eventData EventData[]
report Report[]
sessionData SessionData[]
segment Segment[]
@@index([userId])
@@index([teamId])
@ -231,3 +232,17 @@ model Report {
@@index([name])
@@map("report")
}
model Segment {
id String @id() @unique() @map("segment_id") @db.Uuid
websiteId String @map("website_id") @db.Uuid
name String @map("name") @db.VarChar(200)
filters Json @map("filters")
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6)
updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamptz(6)
website Website @relation(fields: [websiteId], references: [id])
@@index([websiteId])
@@map("segment")
}

2821
pnpm-lock.yaml generated

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
import { z } from 'zod';
import { canViewWebsite } from '@/lib/auth';
import { EVENT_COLUMNS, FILTER_COLUMNS, SESSION_COLUMNS } from '@/lib/constants';
import { EVENT_COLUMNS, FILTER_COLUMNS, GROUP_FILTERS, SESSION_COLUMNS } from '@/lib/constants';
import { getValues } from '@/queries';
import { parseRequest, getRequestDateRange } from '@/lib/request';
import { badRequest, json, unauthorized } from '@/lib/response';
@ -30,7 +30,11 @@ export async function GET(
return unauthorized();
}
if (!SESSION_COLUMNS.includes(type) && !EVENT_COLUMNS.includes(type)) {
if (
!SESSION_COLUMNS.includes(type) &&
!EVENT_COLUMNS.includes(type) &&
!GROUP_FILTERS.includes(type)
) {
return badRequest('Invalid type.');
}

View file

@ -4,6 +4,7 @@ export function useFields() {
const { formatMessage, labels } = useMessages();
const fields = [
{ name: 'segment', type: 'string', label: formatMessage(labels.segment) },
{ name: 'url', type: 'string', label: formatMessage(labels.url) },
{ name: 'title', type: 'string', label: formatMessage(labels.pageTitle) },
{ name: 'referrer', type: 'string', label: formatMessage(labels.referrer) },

View file

@ -99,6 +99,7 @@ export const labels = defineMessages({
countries: { id: 'label.countries', defaultMessage: 'Countries' },
languages: { id: 'label.languages', defaultMessage: 'Languages' },
tags: { id: 'label.tags', defaultMessage: 'Tags' },
segments: { id: 'label.segments', defaultMessage: 'Segments' },
count: { id: 'label.count', defaultMessage: 'Count' },
average: { id: 'label.average', defaultMessage: 'Average' },
sum: { id: 'label.sum', defaultMessage: 'Sum' },
@ -229,6 +230,7 @@ export const labels = defineMessages({
device: { id: 'label.device', defaultMessage: 'Device' },
pageTitle: { id: 'label.pageTitle', defaultMessage: 'Page title' },
tag: { id: 'label.tag', defaultMessage: 'Tag' },
segment: { id: 'label.segment', defaultMessage: 'Segment' },
day: { id: 'label.day', defaultMessage: 'Day' },
date: { id: 'label.date', defaultMessage: 'Date' },
pageOf: { id: 'label.page-of', defaultMessage: 'Page {current} of {total}' },

View file

@ -47,6 +47,8 @@ export const SESSION_COLUMNS = [
'host',
];
export const GROUP_FILTERS = ['segment', 'cohort'];
export const FILTER_COLUMNS = {
url: 'url_path',
entry: 'url_path',
@ -64,6 +66,7 @@ export const FILTER_COLUMNS = {
language: 'language',
event: 'event_name',
tag: 'tag',
segment: 'segment',
};
export const COLLECTION_TYPE = {

View file

@ -0,0 +1,29 @@
import prisma from '@/lib/prisma';
import { Prisma, Segment } from '@prisma/client';
async function findSegment(criteria: Prisma.SegmentFindUniqueArgs): Promise<Segment> {
return prisma.client.Segment.findUnique(criteria);
}
export async function getSegment(segmentId: string): Promise<Segment> {
return findSegment({
where: {
id: segmentId,
},
});
}
export async function createSegment(data: Prisma.SegmentUncheckedCreateInput): Promise<Segment> {
return prisma.client.Segment.create({ data });
}
export async function updateSegment(
SegmentId: string,
data: Prisma.SegmentUpdateInput,
): Promise<Segment> {
return prisma.client.Segment.update({ where: { id: SegmentId }, data });
}
export async function deleteSegment(SegmentId: string): Promise<Segment> {
return prisma.client.Segment.delete({ where: { id: SegmentId } });
}