Merge branch 'dev' into jajaja

# Conflicts:
#	db/postgresql/schema.prisma
#	src/queries/sql/reports/getRevenue.ts
This commit is contained in:
Mike Cao 2025-06-10 21:11:44 -07:00
commit b2aa37a3df
9 changed files with 279 additions and 200 deletions

View file

@ -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");

View file

@ -46,6 +46,7 @@ model Session {
websiteEvent WebsiteEvent[] websiteEvent WebsiteEvent[]
sessionData SessionData[] sessionData SessionData[]
revenue Revenue[]
@@index([createdAt]) @@index([createdAt])
@@index([websiteId]) @@index([websiteId])
@ -79,6 +80,7 @@ model Website {
team Team? @relation(fields: [teamId], references: [id]) team Team? @relation(fields: [teamId], references: [id])
eventData EventData[] eventData EventData[]
report Report[] report Report[]
revenue Revenue[]
sessionData SessionData[] sessionData SessionData[]
segment Segment[] segment Segment[]
@ -222,7 +224,7 @@ model Report {
type String @db.VarChar(200) type String @db.VarChar(200)
name String @db.VarChar(200) name String @db.VarChar(200)
description String @db.VarChar(500) description String @db.VarChar(500)
parameters Json parameters Json
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6) createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6)
updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamptz(6) updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamptz(6)
@ -237,15 +239,36 @@ model Report {
} }
model Segment { model Segment {
id String @id() @unique() @map("segment_id") @db.Uuid id String @id() @unique() @map("segment_id") @db.Uuid
websiteId String @map("website_id") @db.Uuid websiteId String @map("website_id") @db.Uuid
name String @db.VarChar(200) type String @db.VarChar(200)
filters Json name String @db.VarChar(200)
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6) filters Json
updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamptz(6) 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]) website Website @relation(fields: [websiteId], references: [id])
@@index([websiteId]) @@index([websiteId])
@@map("segment") @@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")
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Before After
Before After

View file

@ -38,7 +38,7 @@
"label.add-step": [ "label.add-step": [
{ {
"type": 0, "type": 0,
"value": "Add step" "value": "إضافة خطوة"
} }
], ],
"label.add-website": [ "label.add-website": [
@ -77,6 +77,18 @@
"value": "تحليلات" "value": "تحليلات"
} }
], ],
"label.attribution": [
{
"type": 0,
"value": "الإسناد"
}
],
"label.attribution-description": [
{
"type": 0,
"value": "شاهد كيف يتفاعل المستخدمون مع حملاتك التسويقية وما الذي يحفز التحويلات."
}
],
"label.average": [ "label.average": [
{ {
"type": 0, "type": 0,
@ -122,7 +134,7 @@
"label.cancel": [ "label.cancel": [
{ {
"type": 0, "type": 0,
"value": "ألغِ" "value": "إلغاء"
} }
], ],
"label.change-password": [ "label.change-password": [
@ -152,7 +164,7 @@
"label.compare": [ "label.compare": [
{ {
"type": 0, "type": 0,
"value": "Compare" "value": "المقارنة"
} }
], ],
"label.confirm": [ "label.confirm": [
@ -170,7 +182,7 @@
"label.contains": [ "label.contains": [
{ {
"type": 0, "type": 0,
"value": "يحتوي" "value": "يحتوي على"
} }
], ],
"label.continue": [ "label.continue": [
@ -182,7 +194,7 @@
"label.count": [ "label.count": [
{ {
"type": 0, "type": 0,
"value": "Count" "value": "العدد"
} }
], ],
"label.countries": [ "label.countries": [
@ -236,7 +248,7 @@
"label.current": [ "label.current": [
{ {
"type": 0, "type": 0,
"value": "Current" "value": "الحالي"
} }
], ],
"label.current-password": [ "label.current-password": [
@ -254,7 +266,7 @@
"label.dashboard": [ "label.dashboard": [
{ {
"type": 0, "type": 0,
"value": "الشاشة الرئيسية" "value": "لوحة التحكم"
} }
], ],
"label.data": [ "label.data": [
@ -356,7 +368,7 @@
"label.does-not-contain": [ "label.does-not-contain": [
{ {
"type": 0, "type": 0,
"value": "لا يحتوي" "value": "لا يحتوي على"
} }
], ],
"label.domain": [ "label.domain": [
@ -374,7 +386,7 @@
"label.edit": [ "label.edit": [
{ {
"type": 0, "type": 0,
"value": "عدّل" "value": "تعديل"
} }
], ],
"label.edit-dashboard": [ "label.edit-dashboard": [
@ -398,13 +410,13 @@
"label.end-step": [ "label.end-step": [
{ {
"type": 0, "type": 0,
"value": "End Step" "value": "الخطوة الأخيرة"
} }
], ],
"label.entry": [ "label.entry": [
{ {
"type": 0, "type": 0,
"value": "Entry URL" "value": "رابط الدخول"
} }
], ],
"label.event": [ "label.event": [
@ -428,7 +440,7 @@
"label.exit": [ "label.exit": [
{ {
"type": 0, "type": 0,
"value": "Exit URL" "value": "رابط المغادرة"
} }
], ],
"label.false": [ "label.false": [
@ -476,7 +488,7 @@
"label.first-seen": [ "label.first-seen": [
{ {
"type": 0, "type": 0,
"value": "First seen" "value": "أول ظهور"
} }
], ],
"label.funnel": [ "label.funnel": [
@ -494,19 +506,19 @@
"label.goal": [ "label.goal": [
{ {
"type": 0, "type": 0,
"value": "Goal" "value": "الهدف"
} }
], ],
"label.goals": [ "label.goals": [
{ {
"type": 0, "type": 0,
"value": "Goals" "value": "الأهداف"
} }
], ],
"label.goals-description": [ "label.goals-description": [
{ {
"type": 0, "type": 0,
"value": "Track your goals for pageviews and events." "value": "تابع تحقق أهدافك المرتبطة بمشاهدات الصفحات والأحداث."
} }
], ],
"label.greater-than": [ "label.greater-than": [
@ -548,13 +560,13 @@
"label.is": [ "label.is": [
{ {
"type": 0, "type": 0,
"value": "هو" "value": "يساوي"
} }
], ],
"label.is-not": [ "label.is-not": [
{ {
"type": 0, "type": 0,
"value": م" "value": ا يساوي"
} }
], ],
"label.is-not-set": [ "label.is-not-set": [
@ -584,13 +596,13 @@
"label.journey": [ "label.journey": [
{ {
"type": 0, "type": 0,
"value": "Journey" "value": "رحلة المستخدم"
} }
], ],
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users navigate through your website." "value": "تعرّف على كيفية تنقّل المستخدمين داخل موقعك."
} }
], ],
"label.language": [ "label.language": [
@ -642,7 +654,7 @@
"label.last-months": [ "label.last-months": [
{ {
"type": 0, "type": 0,
"value": "Last " "value": "آخر "
}, },
{ {
"type": 1, "type": 1,
@ -650,13 +662,13 @@
}, },
{ {
"type": 0, "type": 0,
"value": " months" "value": " شهر/أشهر"
} }
], ],
"label.last-seen": [ "label.last-seen": [
{ {
"type": 0, "type": 0,
"value": "Last seen" "value": "آخر ظهور"
} }
], ],
"label.leave": [ "label.leave": [
@ -704,7 +716,7 @@
"label.manager": [ "label.manager": [
{ {
"type": 0, "type": 0,
"value": "Manager" "value": "مدير"
} }
], ],
"label.max": [ "label.max": [
@ -876,13 +888,13 @@
"label.path": [ "label.path": [
{ {
"type": 0, "type": 0,
"value": "Path" "value": "المسار"
} }
], ],
"label.paths": [ "label.paths": [
{ {
"type": 0, "type": 0,
"value": "Paths" "value": "المسارات"
} }
], ],
"label.powered-by": [ "label.powered-by": [
@ -898,19 +910,19 @@
"label.previous": [ "label.previous": [
{ {
"type": 0, "type": 0,
"value": "Previous" "value": "السابق"
} }
], ],
"label.previous-period": [ "label.previous-period": [
{ {
"type": 0, "type": 0,
"value": "Previous period" "value": "الفترة السابقة"
} }
], ],
"label.previous-year": [ "label.previous-year": [
{ {
"type": 0, "type": 0,
"value": "Previous year" "value": "العام السابق"
} }
], ],
"label.profile": [ "label.profile": [
@ -922,13 +934,13 @@
"label.properties": [ "label.properties": [
{ {
"type": 0, "type": 0,
"value": "Properties" "value": "الخصائص"
} }
], ],
"label.property": [ "label.property": [
{ {
"type": 0, "type": 0,
"value": "Property" "value": "الخاصية"
} }
], ],
"label.queries": [ "label.queries": [
@ -1042,19 +1054,19 @@
"label.revenue": [ "label.revenue": [
{ {
"type": 0, "type": 0,
"value": "Revenue" "value": "الإيرادات"
} }
], ],
"label.revenue-description": [ "label.revenue-description": [
{ {
"type": 0, "type": 0,
"value": "Look into your revenue across time." "value": "قم بإلقاء نظرة على بيانات إيراداتك وكيفية إنفاق المستخدمين."
} }
], ],
"label.revenue-property": [ "label.revenue-property": [
{ {
"type": 0, "type": 0,
"value": "Revenue Property" "value": "خاصية الإيرادات"
} }
], ],
"label.role": [ "label.role": [
@ -1114,7 +1126,7 @@
"label.session": [ "label.session": [
{ {
"type": 0, "type": 0,
"value": "Session" "value": "الزيارة"
} }
], ],
"label.sessions": [ "label.sessions": [
@ -1144,13 +1156,13 @@
"label.start-step": [ "label.start-step": [
{ {
"type": 0, "type": 0,
"value": "Start Step" "value": "الخطوة الأولى"
} }
], ],
"label.steps": [ "label.steps": [
{ {
"type": 0, "type": 0,
"value": "Steps" "value": "الخطوات"
} }
], ],
"label.sum": [ "label.sum": [
@ -1165,6 +1177,18 @@
"value": "تابلت" "value": "تابلت"
} }
], ],
"label.tag": [
{
"type": 0,
"value": "الوسم"
}
],
"label.tags": [
{
"type": 0,
"value": "الوسوم"
}
],
"label.team": [ "label.team": [
{ {
"type": 0, "type": 0,
@ -1180,7 +1204,7 @@
"label.team-manager": [ "label.team-manager": [
{ {
"type": 0, "type": 0,
"value": "Team manager" "value": "مدير الفريق"
} }
], ],
"label.team-member": [ "label.team-member": [
@ -1204,7 +1228,7 @@
"label.team-view-only": [ "label.team-view-only": [
{ {
"type": 0, "type": 0,
"value": "Team view only" "value": "عرض الفريق فقط"
} }
], ],
"label.team-websites": [ "label.team-websites": [
@ -1288,13 +1312,13 @@
"label.transactions": [ "label.transactions": [
{ {
"type": 0, "type": 0,
"value": "Transactions" "value": "المعاملات"
} }
], ],
"label.transfer": [ "label.transfer": [
{ {
"type": 0, "type": 0,
"value": "Transfer" "value": "نقل"
} }
], ],
"label.transfer-website": [ "label.transfer-website": [
@ -1330,7 +1354,7 @@
"label.uniqueCustomers": [ "label.uniqueCustomers": [
{ {
"type": 0, "type": 0,
"value": "Unique Customers" "value": "العملاء الفريدون"
} }
], ],
"label.unknown": [ "label.unknown": [
@ -1348,19 +1372,19 @@
"label.update": [ "label.update": [
{ {
"type": 0, "type": 0,
"value": "Update" "value": "تحديث"
} }
], ],
"label.url": [ "label.url": [
{ {
"type": 0, "type": 0,
"value": "URL" "value": "الرابط"
} }
], ],
"label.urls": [ "label.urls": [
{ {
"type": 0, "type": 0,
"value": "URLs" "value": "الروابط"
} }
], ],
"label.user": [ "label.user": [
@ -1372,7 +1396,7 @@
"label.user-property": [ "label.user-property": [
{ {
"type": 0, "type": 0,
"value": "User Property" "value": "سمات المستخدم"
} }
], ],
"label.username": [ "label.username": [
@ -1396,7 +1420,7 @@
"label.utm-description": [ "label.utm-description": [
{ {
"type": 0, "type": 0,
"value": "Track your campaigns through UTM parameters." "value": "تابع حملاتك التسويقية باستخدام معلمات UTM."
} }
], ],
"label.value": [ "label.value": [
@ -1432,7 +1456,7 @@
"label.views-per-visit": [ "label.views-per-visit": [
{ {
"type": 0, "type": 0,
"value": "Views per visit" "value": "مشاهدات لكل زيارة"
} }
], ],
"label.visit-duration": [ "label.visit-duration": [
@ -1450,7 +1474,7 @@
"label.visits": [ "label.visits": [
{ {
"type": 0, "type": 0,
"value": "Visits" "value": "الزيارات"
} }
], ],
"label.website": [ "label.website": [
@ -1534,7 +1558,7 @@
"message.collected-data": [ "message.collected-data": [
{ {
"type": 0, "type": 0,
"value": "Collected data" "value": "البيانات المجمعة"
} }
], ],
"message.confirm-delete": [ "message.confirm-delete": [
@ -1754,15 +1778,7 @@
"message.share-url": [ "message.share-url": [
{ {
"type": 0, "type": 0,
"value": "هذا الرابط الذي تم مشاركته بشكل عام لـ " "value": "إحصائيات موقعك متاحة للجميع على الرابط التالي:"
},
{
"type": 1,
"value": "target"
},
{
"type": 0,
"value": "."
} }
], ],
"message.team-already-member": [ "message.team-already-member": [

View file

@ -5,13 +5,15 @@
"label.add": "أضِف", "label.add": "أضِف",
"label.add-description": "أضِف وصف", "label.add-description": "أضِف وصف",
"label.add-member": "أضِف عضو", "label.add-member": "أضِف عضو",
"label.add-step": "Add step", "label.add-step": "إضافة خطوة",
"label.add-website": "إضافة موقع", "label.add-website": "إضافة موقع",
"label.admin": "مدير", "label.admin": "مدير",
"label.after": "يعد", "label.after": "يعد",
"label.all": "الكل", "label.all": "الكل",
"label.all-time": "كل الوقت", "label.all-time": "كل الوقت",
"label.analytics": "تحليلات", "label.analytics": "تحليلات",
"label.attribution": "الإسناد",
"label.attribution-description": "شاهد كيف يتفاعل المستخدمون مع حملاتك التسويقية وما الذي يحفز التحويلات.",
"label.average": "المتوسط", "label.average": "المتوسط",
"label.back": "للخلف", "label.back": "للخلف",
"label.before": "قبل", "label.before": "قبل",
@ -19,17 +21,17 @@
"label.breakdown": "التصنيف", "label.breakdown": "التصنيف",
"label.browser": "المتصفح", "label.browser": "المتصفح",
"label.browsers": "المتصفحات", "label.browsers": "المتصفحات",
"label.cancel": "ألغِ", "label.cancel": "إلغاء",
"label.change-password": "تغيير كلمة المرور", "label.change-password": "تغيير كلمة المرور",
"label.cities": "المدن", "label.cities": "المدن",
"label.city": "المدينة", "label.city": "المدينة",
"label.clear-all": "مسح الكل", "label.clear-all": "مسح الكل",
"label.compare": "Compare", "label.compare": "المقارنة",
"label.confirm": "تأكيد", "label.confirm": "تأكيد",
"label.confirm-password": "تأكيد كلمة المرور", "label.confirm-password": "تأكيد كلمة المرور",
"label.contains": "يحتوي", "label.contains": "يحتوي على",
"label.continue": "تابع", "label.continue": "تابع",
"label.count": "Count", "label.count": "العدد",
"label.countries": "الدول", "label.countries": "الدول",
"label.country": "الدولة", "label.country": "الدولة",
"label.create": "أنشِئ", "label.create": "أنشِئ",
@ -38,10 +40,10 @@
"label.create-user": "أنشِئ مستخدم", "label.create-user": "أنشِئ مستخدم",
"label.created": "أُنشئت", "label.created": "أُنشئت",
"label.created-by": "أُنشئ من قبل", "label.created-by": "أُنشئ من قبل",
"label.current": "Current", "label.current": "الحالي",
"label.current-password": "كلمة المرور الحالية", "label.current-password": "كلمة المرور الحالية",
"label.custom-range": "فترة مخصّصة", "label.custom-range": "فترة مخصّصة",
"label.dashboard": "الشاشة الرئيسية", "label.dashboard": "لوحة التحكم",
"label.data": "البيانات", "label.data": "البيانات",
"label.date": "التاريخ", "label.date": "التاريخ",
"label.date-range": "فترة مخصّصة", "label.date-range": "فترة مخصّصة",
@ -58,19 +60,19 @@
"label.device": "الجهاز", "label.device": "الجهاز",
"label.devices": "الأجهزة", "label.devices": "الأجهزة",
"label.dismiss": "تجاهل", "label.dismiss": "تجاهل",
"label.does-not-contain": "لا يحتوي", "label.does-not-contain": "لا يحتوي على",
"label.domain": "النطاق", "label.domain": "النطاق",
"label.dropoff": "إنزال", "label.dropoff": "إنزال",
"label.edit": "عدّل", "label.edit": "تعديل",
"label.edit-dashboard": "عدّل لوحة التحكم", "label.edit-dashboard": "عدّل لوحة التحكم",
"label.edit-member": "عدّل العضو", "label.edit-member": "عدّل العضو",
"label.enable-share-url": "فعّل مشاركة الرابط", "label.enable-share-url": "فعّل مشاركة الرابط",
"label.end-step": "End Step", "label.end-step": "الخطوة الأخيرة",
"label.entry": "Entry URL", "label.entry": "رابط الدخول",
"label.event": "الحدث", "label.event": "الحدث",
"label.event-data": "تاريخ الحدث", "label.event-data": "تاريخ الحدث",
"label.events": "الأحداث", "label.events": "الأحداث",
"label.exit": "Exit URL", "label.exit": "رابط المغادرة",
"label.false": "خطأ", "label.false": "خطأ",
"label.field": "الحقل", "label.field": "الحقل",
"label.fields": "الحقول", "label.fields": "الحقول",
@ -78,33 +80,33 @@
"label.filter-combined": "مُجمّعة", "label.filter-combined": "مُجمّعة",
"label.filter-raw": "خام", "label.filter-raw": "خام",
"label.filters": "التصفيات", "label.filters": "التصفيات",
"label.first-seen": "First seen", "label.first-seen": "أول ظهور",
"label.funnel": "قمع", "label.funnel": "قمع",
"label.funnel-description": "فهم معدل التحويل والانقطاع عن المستخدمين.", "label.funnel-description": "فهم معدل التحويل والانقطاع عن المستخدمين.",
"label.goal": "Goal", "label.goal": "الهدف",
"label.goals": "Goals", "label.goals": "الأهداف",
"label.goals-description": "Track your goals for pageviews and events.", "label.goals-description": "تابع تحقق أهدافك المرتبطة بمشاهدات الصفحات والأحداث.",
"label.greater-than": "أكبَر مِن", "label.greater-than": "أكبَر مِن",
"label.greater-than-equals": "أكبَر مِن أو يساوي", "label.greater-than-equals": "أكبَر مِن أو يساوي",
"label.host": "Host", "label.host": "Host",
"label.hosts": "Hosts", "label.hosts": "Hosts",
"label.insights": "نتائج التحليلات", "label.insights": "نتائج التحليلات",
"label.insights-description": "تعمق في بياناتك باستخدام الشرائح والتصفيات.", "label.insights-description": "تعمق في بياناتك باستخدام الشرائح والتصفيات.",
"label.is": "هو", "label.is": "يساوي",
"label.is-not": م", "label.is-not": ا يساوي",
"label.is-not-set": "لم ضُبط", "label.is-not-set": "لم ضُبط",
"label.is-set": "ضُبط", "label.is-set": "ضُبط",
"label.join": "انضم", "label.join": "انضم",
"label.join-team": "انضم للفريق", "label.join-team": "انضم للفريق",
"label.journey": "Journey", "label.journey": "رحلة المستخدم",
"label.journey-description": "Understand how users navigate through your website.", "label.journey-description": "تعرّف على كيفية تنقّل المستخدمين داخل موقعك.",
"label.language": "اللغة", "label.language": "اللغة",
"label.languages": "اللغات", "label.languages": "اللغات",
"label.laptop": "لابتوب", "label.laptop": "لابتوب",
"label.last-days": "آخر {x} يوم/ايام", "label.last-days": "آخر {x} يوم/ايام",
"label.last-hours": "آخر {x} ساعة", "label.last-hours": "آخر {x} ساعة",
"label.last-months": "Last {x} months", "label.last-months": "آخر {x} شهر/أشهر",
"label.last-seen": "Last seen", "label.last-seen": "آخر ظهور",
"label.leave": "غادر", "label.leave": "غادر",
"label.leave-team": "مغادرة المجموعة", "label.leave-team": "مغادرة المجموعة",
"label.less-than": "أقل مِن", "label.less-than": "أقل مِن",
@ -112,7 +114,7 @@
"label.login": "تسجيل الدخول", "label.login": "تسجيل الدخول",
"label.logout": "تسجيل الخروج", "label.logout": "تسجيل الخروج",
"label.manage": "التحكم", "label.manage": "التحكم",
"label.manager": "Manager", "label.manager": "مدير",
"label.max": "الحد الأقصى", "label.max": "الحد الأقصى",
"label.member": "عضو", "label.member": "عضو",
"label.members": "الأعضاء", "label.members": "الأعضاء",
@ -134,15 +136,15 @@
"label.pageTitle": "عنوان الصفحة", "label.pageTitle": "عنوان الصفحة",
"label.pages": "الصفحات", "label.pages": "الصفحات",
"label.password": "كلمة المرور", "label.password": "كلمة المرور",
"label.path": "Path", "label.path": "المسار",
"label.paths": "Paths", "label.paths": "المسارات",
"label.powered-by": "مشغل بواسطة {name}", "label.powered-by": "مشغل بواسطة {name}",
"label.previous": "Previous", "label.previous": "السابق",
"label.previous-period": "Previous period", "label.previous-period": "الفترة السابقة",
"label.previous-year": "Previous year", "label.previous-year": "العام السابق",
"label.profile": "الملف الشخصي", "label.profile": "الملف الشخصي",
"label.properties": "Properties", "label.properties": "الخصائص",
"label.property": "Property", "label.property": "الخاصية",
"label.queries": "استعلامات", "label.queries": "استعلامات",
"label.query": "استعلام", "label.query": "استعلام",
"label.query-parameters": "متغيرات الرابط", "label.query-parameters": "متغيرات الرابط",
@ -161,9 +163,9 @@
"label.reset-website": "اعادة تعيين الإحصائيات", "label.reset-website": "اعادة تعيين الإحصائيات",
"label.retention": "الاحتفاظ", "label.retention": "الاحتفاظ",
"label.retention-description": "قس مدى ثبات موقعك على الويب من خلال تتبع عدد مرات عودة المستخدمين.", "label.retention-description": "قس مدى ثبات موقعك على الويب من خلال تتبع عدد مرات عودة المستخدمين.",
"label.revenue": "Revenue", "label.revenue": "الإيرادات",
"label.revenue-description": "Look into your revenue across time.", "label.revenue-description": "قم بإلقاء نظرة على بيانات إيراداتك وكيفية إنفاق المستخدمين.",
"label.revenue-property": "Revenue Property", "label.revenue-property": "خاصية الإيرادات",
"label.role": "الصلاحية", "label.role": "الصلاحية",
"label.run-query": "شغّل الاستعلام", "label.run-query": "شغّل الاستعلام",
"label.save": "حفظ", "label.save": "حفظ",
@ -173,22 +175,24 @@
"label.select-date": "حدد التاريخ", "label.select-date": "حدد التاريخ",
"label.select-role": "حدد الدور", "label.select-role": "حدد الدور",
"label.select-website": "حدد موقع", "label.select-website": "حدد موقع",
"label.session": "Session", "label.session": "الزيارة",
"label.sessions": "الزيارات", "label.sessions": "الزيارات",
"label.settings": "الإعدادات", "label.settings": "الإعدادات",
"label.share-url": "مشاركة الرابط", "label.share-url": "مشاركة الرابط",
"label.single-day": "يوم واحد", "label.single-day": "يوم واحد",
"label.start-step": "Start Step", "label.start-step": "الخطوة الأولى",
"label.steps": "Steps", "label.steps": "الخطوات",
"label.sum": "المجموع", "label.sum": "المجموع",
"label.tablet": "تابلت", "label.tablet": "تابلت",
"label.tag": "الوسم",
"label.tags": "الوسوم",
"label.team": "الفريق", "label.team": "الفريق",
"label.team-id": "معرّف الفريق", "label.team-id": "معرّف الفريق",
"label.team-manager": "Team manager", "label.team-manager": "مدير الفريق",
"label.team-member": "عضو الفريق", "label.team-member": "عضو الفريق",
"label.team-name": "اسم الفريق", "label.team-name": "اسم الفريق",
"label.team-owner": "مدير الفريق", "label.team-owner": "مدير الفريق",
"label.team-view-only": "Team view only", "label.team-view-only": "عرض الفريق فقط",
"label.team-websites": "مواقع الفريق", "label.team-websites": "مواقع الفريق",
"label.teams": "الفرق", "label.teams": "الفرق",
"label.theme": "السمة", "label.theme": "السمة",
@ -202,34 +206,34 @@
"label.total": "الإجمالي", "label.total": "الإجمالي",
"label.total-records": "إجمالي السجلات", "label.total-records": "إجمالي السجلات",
"label.tracking-code": "كود التتبع", "label.tracking-code": "كود التتبع",
"label.transactions": "Transactions", "label.transactions": "المعاملات",
"label.transfer": "Transfer", "label.transfer": "نقل",
"label.transfer-website": "انقل الموقع", "label.transfer-website": "انقل الموقع",
"label.true": "حقيقي", "label.true": "حقيقي",
"label.type": "النوع", "label.type": "النوع",
"label.unique": "فريد", "label.unique": "فريد",
"label.unique-visitors": "زائرون فريدون", "label.unique-visitors": "زائرون فريدون",
"label.uniqueCustomers": "Unique Customers", "label.uniqueCustomers": "العملاء الفريدون",
"label.unknown": "غير معروف", "label.unknown": "غير معروف",
"label.untitled": "بدون عنوان", "label.untitled": "بدون عنوان",
"label.update": "Update", "label.update": "تحديث",
"label.url": "URL", "label.url": "الرابط",
"label.urls": "URLs", "label.urls": "الروابط",
"label.user": "المستخدم", "label.user": "المستخدم",
"label.user-property": "User Property", "label.user-property": "سمات المستخدم",
"label.username": "اسم المستخدم", "label.username": "اسم المستخدم",
"label.users": "المستخدمين", "label.users": "المستخدمين",
"label.utm": "UTM", "label.utm": "UTM",
"label.utm-description": "Track your campaigns through UTM parameters.", "label.utm-description": "تابع حملاتك التسويقية باستخدام معلمات UTM.",
"label.value": "القيمة", "label.value": "القيمة",
"label.view": "عرض", "label.view": "عرض",
"label.view-details": "عرض التفاصيل", "label.view-details": "عرض التفاصيل",
"label.view-only": "عرض فقط", "label.view-only": "عرض فقط",
"label.views": "المشاهدات", "label.views": "المشاهدات",
"label.views-per-visit": "Views per visit", "label.views-per-visit": "مشاهدات لكل زيارة",
"label.visit-duration": "متوسط وقت الزيارة", "label.visit-duration": "متوسط وقت الزيارة",
"label.visitors": "الزوار", "label.visitors": "الزوار",
"label.visits": "Visits", "label.visits": "الزيارات",
"label.website": "الموقع", "label.website": "الموقع",
"label.website-id": "معرّف الموقع", "label.website-id": "معرّف الموقع",
"label.websites": "المواقع", "label.websites": "المواقع",
@ -237,7 +241,7 @@
"label.yesterday": "الأمس", "label.yesterday": "الأمس",
"message.action-confirmation": "اكتب {confirmation} في المربع أدناه للتأكيد.", "message.action-confirmation": "اكتب {confirmation} في المربع أدناه للتأكيد.",
"message.active-users": "{x} حاليا {x, plural, one {زائر واحد} other {زوار}}", "message.active-users": "{x} حاليا {x, plural, one {زائر واحد} other {زوار}}",
"message.collected-data": "Collected data", "message.collected-data": "البيانات المجمعة",
"message.confirm-delete": "هل أنت متأكد من حذف {target}?", "message.confirm-delete": "هل أنت متأكد من حذف {target}?",
"message.confirm-leave": "هل أنت متأكد من مغادرة {target}?", "message.confirm-leave": "هل أنت متأكد من مغادرة {target}?",
"message.confirm-remove": "هل انت متأكد من حذف {target}?", "message.confirm-remove": "هل انت متأكد من حذف {target}?",
@ -261,9 +265,9 @@
"message.no-websites-configured": "لم تقم بإعداد اي موقع.", "message.no-websites-configured": "لم تقم بإعداد اي موقع.",
"message.page-not-found": "الصفحة غير موجودة.", "message.page-not-found": "الصفحة غير موجودة.",
"message.reset-website": "لإعادة ضبط موقع الويب هذا، اكتب {confirmation} في المربع أدناه للتأكيد.", "message.reset-website": "لإعادة ضبط موقع الويب هذا، اكتب {confirmation} في المربع أدناه للتأكيد.",
"message.reset-website-warning": "سيتم اعادة تعيين كافة الإحصائيات لهذا الموقع، لكن لن يتم تعيير كود التتبع", "message.reset-website-warning": "سيتم اعادة تعيين كافة الإحصائيات لهذا الموقع، لكن لن يتم تغيير كود التتبع",
"message.saved": "تم الحفظ بنجاح.", "message.saved": "تم الحفظ بنجاح.",
"message.share-url": "هذا الرابط الذي تم مشاركته بشكل عام لـ {target}.", "message.share-url": "إحصائيات موقعك متاحة للجميع على الرابط التالي:",
"message.team-already-member": "أنت عضو في الفريق", "message.team-already-member": "أنت عضو في الفريق",
"message.team-not-found": "لم يتم العثور على الفريق", "message.team-not-found": "لم يتم العثور على الفريق",
"message.team-websites-info": "يمكن مشاهدة الموقع من اي عضو في الفريق.", "message.team-websites-info": "يمكن مشاهدة الموقع من اي عضو في الفريق.",

View file

@ -5,6 +5,7 @@ import kafka from '@/lib/kafka';
import prisma from '@/lib/prisma'; import prisma from '@/lib/prisma';
import { uuid } from '@/lib/crypto'; import { uuid } from '@/lib/crypto';
import { saveEventData } from './saveEventData'; import { saveEventData } from './saveEventData';
import { saveRevenue } from './saveRevenue';
export interface SaveEventArgs { export interface SaveEventArgs {
websiteId: string; websiteId: string;
@ -130,6 +131,20 @@ async function relationalQuery({
eventData, eventData,
createdAt, 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,
});
}
} }
} }

View file

@ -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,
},
});
}

View file

@ -69,26 +69,16 @@ async function relationalQuery(
group by 1),`; group by 1),`;
const revenueEventQuery = `WITH events AS ( const revenueEventQuery = `WITH events AS (
select select
we.session_id, session_id,
max(ed.created_at) max_dt, max(created_at) max_dt,
sum(coalesce(cast(number_value as decimal(10,2)), cast(string_value as decimal(10,2)))) value sum(revenue) value
from event_data ed from revenue
join website_event we where website_id = {{websiteId::uuid}}
on we.event_id = ed.website_event_id and created_at between {{startDate}} and {{endDate}}
and we.website_id = ed.website_id and ${column} = {{conversionStep}}
join (select website_event_id and currency ${like} {{currency}}
from event_data group by 1),`;
where website_id = {{websiteId::uuid}}
and created_at between {{startDate}} and {{endDate}}
and data_key ${like} '%currency%'
and string_value = {{currency}}) currency
on currency.website_event_id = ed.website_event_id
where ed.website_id = {{websiteId::uuid}}
and ed.created_at between {{startDate}} and {{endDate}}
and ${column} = {{conversionStep}}
and ed.data_key ${like} '%revenue%'
group by 1),`;
function getModelQuery(model: string) { function getModelQuery(model: string) {
return model === 'firstClick' return model === 'firstClick'

View file

@ -38,22 +38,13 @@ async function relationalQuery(
const chartRes = await rawQuery( const chartRes = await rawQuery(
` `
select select
we.event_name x, event_name x,
${getDateSQL('ed.created_at', unit)} t, ${getDateSQL('created_at', unit)} t,
sum(coalesce(cast(number_value as decimal(10,2)), cast(string_value as decimal(10,2)))) y sum(revenue) y
from event_data ed from revenue
join website_event we where website_id = {{websiteId::uuid}}
on we.event_id = ed.website_event_id and created_at between {{startDate}} and {{endDate}}
join (select website_event_id and currency ${like} {{currency}}
from event_data
where website_id = {{websiteId::uuid}}
and created_at between {{startDate}} and {{endDate}}
and data_key ${like} '%currency%'
and string_value = {{currency}}) currency
on currency.website_event_id = ed.website_event_id
where ed.website_id = {{websiteId::uuid}}
and ed.created_at between {{startDate}} and {{endDate}}
and ed.data_key ${like} '%revenue%'
group by x, t group by x, t
order by t order by t
`, `,
@ -64,22 +55,13 @@ async function relationalQuery(
` `
select select
s.country as name, s.country as name,
sum(coalesce(cast(number_value as decimal(10,2)), cast(string_value as decimal(10,2)))) value sum(r.revenue) value
from event_data ed from revenue r
join website_event we
on we.event_id = ed.website_event_id
join session s join session s
on s.session_id = we.session_id on s.session_id = r.session_id
join (select website_event_id where r.website_id = {{websiteId::uuid}}
from event_data and r.created_at between {{startDate}} and {{endDate}}
where website_id = {{websiteId::uuid}} and r.currency ${like} {{currency}}
and created_at between {{startDate}} and {{endDate}}
and data_key ${like} '%currency%'
and string_value = {{currency}}) currency
on currency.website_event_id = ed.website_event_id
where ed.website_id = {{websiteId::uuid}}
and ed.created_at between {{startDate}} and {{endDate}}
and ed.data_key ${like} '%revenue%'
group by s.country group by s.country
`, `,
{ websiteId, startDate, endDate, currency }, { websiteId, startDate, endDate, currency },
@ -88,22 +70,13 @@ async function relationalQuery(
const totalRes = await rawQuery( const totalRes = await rawQuery(
` `
select select
sum(coalesce(cast(number_value as decimal(10,2)), cast(string_value as decimal(10,2)))) as sum, sum(revenue) as sum,
count(distinct event_id) as count, count(distinct event_id) as count,
count(distinct session_id) as unique_count count(distinct session_id) as unique_count
from event_data ed from revenue r
join website_event we where website_id = {{websiteId::uuid}}
on we.event_id = ed.website_event_id and created_at between {{startDate}} and {{endDate}}
join (select website_event_id and currency ${like} {{currency}}
from event_data
where website_id = {{websiteId::uuid}}
and created_at between {{startDate}} and {{endDate}}
and data_key ${like} '%currency%'
and string_value = {{currency}}) currency
on currency.website_event_id = ed.website_event_id
where ed.website_id = {{websiteId::uuid}}
and ed.created_at between {{startDate}} and {{endDate}}
and ed.data_key ${like} '%revenue%'
`, `,
{ websiteId, startDate, endDate, currency }, { websiteId, startDate, endDate, currency },
).then(result => result?.[0]); ).then(result => result?.[0]);
@ -111,24 +84,15 @@ async function relationalQuery(
const tableRes = await rawQuery( const tableRes = await rawQuery(
` `
select select
c.currency, currency,
sum(coalesce(cast(number_value as decimal(10,2)), cast(string_value as decimal(10,2)))) as sum, sum(revenue) as sum,
count(distinct ed.website_event_id) as count, count(distinct event_id) as count,
count(distinct we.session_id) as unique_count count(distinct session_id) as unique_count
from event_data ed from revenue r
join website_event we where website_id = {{websiteId::uuid}}
on we.event_id = ed.website_event_id and created_at between {{startDate}} and {{endDate}}
join (select website_event_id, string_value as currency group by currency
from event_data order by sum desc
where website_id = {{websiteId::uuid}}
and created_at between {{startDate}} and {{endDate}}
and data_key ${like} '%currency%') c
on c.website_event_id = ed.website_event_id
where ed.website_id = {{websiteId::uuid}}
and ed.created_at between {{startDate}} and {{endDate}}
and ed.data_key ${like} '%revenue%'
group by c.currency
order by sum desc;
`, `,
{ websiteId, startDate, endDate, unit, currency }, { websiteId, startDate, endDate, unit, currency },
); );