diff --git a/db/postgresql/migrations/13_add_revenue/migration.sql b/db/postgresql/migrations/13_add_revenue/migration.sql new file mode 100644 index 00000000..96e11661 --- /dev/null +++ b/db/postgresql/migrations/13_add_revenue/migration.sql @@ -0,0 +1,31 @@ +-- AlterTable +ALTER TABLE "segment" ADD COLUMN "type" VARCHAR(200) NOT NULL; + +-- CreateTable +CREATE TABLE "revenue" ( + "revenue_id" UUID NOT NULL, + "website_id" UUID NOT NULL, + "session_id" UUID NOT NULL, + "event_id" UUID NOT NULL, + "event_name" VARCHAR(50) NOT NULL, + "currency" VARCHAR(100) NOT NULL, + "revenue" DECIMAL(19,4), + "created_at" TIMESTAMPTZ(6) DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "revenue_pkey" PRIMARY KEY ("revenue_id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "revenue_revenue_id_key" ON "revenue"("revenue_id"); + +-- CreateIndex +CREATE INDEX "revenue_website_id_idx" ON "revenue"("website_id"); + +-- CreateIndex +CREATE INDEX "revenue_session_id_idx" ON "revenue"("session_id"); + +-- CreateIndex +CREATE INDEX "revenue_website_id_created_at_idx" ON "revenue"("website_id", "created_at"); + +-- CreateIndex +CREATE INDEX "revenue_website_id_session_id_created_at_idx" ON "revenue"("website_id", "session_id", "created_at"); diff --git a/db/postgresql/schema.prisma b/db/postgresql/schema.prisma index a6c35908..cf824f79 100644 --- a/db/postgresql/schema.prisma +++ b/db/postgresql/schema.prisma @@ -43,6 +43,7 @@ model Session { websiteEvent WebsiteEvent[] sessionData SessionData[] + revenue Revenue[] @@index([createdAt]) @@index([websiteId]) @@ -76,6 +77,7 @@ model Website { team Team? @relation(fields: [teamId], references: [id]) eventData EventData[] report Report[] + revenue Revenue[] sessionData SessionData[] segment Segment[] @@ -236,6 +238,7 @@ model Report { model Segment { id String @id() @unique() @map("segment_id") @db.Uuid websiteId String @map("website_id") @db.Uuid + type String @db.VarChar(200) name String @db.VarChar(200) filters Json createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6) @@ -245,4 +248,24 @@ model Segment { @@index([websiteId]) @@map("segment") +} + +model Revenue { + id String @id() @unique() @map("revenue_id") @db.Uuid + websiteId String @map("website_id") @db.Uuid + sessionId String @map("session_id") @db.Uuid + eventId String @map("event_id") @db.Uuid + eventName String @map("event_name") @db.VarChar(50) + currency String @db.VarChar(100) + revenue Decimal? @db.Decimal(19, 4) + createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6) + + website Website @relation(fields: [websiteId], references: [id]) + session Session @relation(fields: [sessionId], references: [id]) + + @@index([websiteId]) + @@index([sessionId]) + @@index([websiteId, createdAt]) + @@index([websiteId, sessionId, createdAt]) + @@map("revenue") } \ No newline at end of file diff --git a/src/queries/sql/events/saveEvent.ts b/src/queries/sql/events/saveEvent.ts index 737b9b9f..92056206 100644 --- a/src/queries/sql/events/saveEvent.ts +++ b/src/queries/sql/events/saveEvent.ts @@ -5,6 +5,7 @@ import kafka from '@/lib/kafka'; import prisma from '@/lib/prisma'; import { uuid } from '@/lib/crypto'; import { saveEventData } from './saveEventData'; +import { saveRevenue } from './saveRevenue'; export interface SaveEventArgs { websiteId: string; @@ -130,6 +131,20 @@ async function relationalQuery({ eventData, createdAt, }); + + const { revenue, currency } = eventData; + + if (revenue > 0 && currency) { + await saveRevenue({ + websiteId, + sessionId, + eventId: websiteEventId, + eventName: eventName?.substring(0, EVENT_NAME_LENGTH), + currency, + revenue, + createdAt, + }); + } } } diff --git a/src/queries/sql/events/saveRevenue.ts b/src/queries/sql/events/saveRevenue.ts new file mode 100644 index 00000000..a38df83a --- /dev/null +++ b/src/queries/sql/events/saveRevenue.ts @@ -0,0 +1,36 @@ +import { uuid } from '@/lib/crypto'; +import { PRISMA, runQuery } from '@/lib/db'; +import prisma from '@/lib/prisma'; + +export interface SaveRevenueArgs { + websiteId: string; + sessionId: string; + eventId: string; + eventName: string; + currency: string; + revenue: number; + createdAt: Date; +} + +export async function saveRevenue(data: SaveRevenueArgs) { + return runQuery({ + [PRISMA]: () => relationalQuery(data), + }); +} + +async function relationalQuery(data: SaveRevenueArgs) { + const { websiteId, sessionId, eventId, eventName, currency, revenue, createdAt } = data; + + await prisma.client.revenue.create({ + data: { + id: uuid(), + websiteId, + sessionId, + eventId, + eventName, + currency, + revenue, + createdAt, + }, + }); +}