Merge branch 'dev' into jajaja

# Conflicts:
#	src/lib/detect.ts
#	src/queries/sql/reports/getRevenue.ts
This commit is contained in:
Mike Cao 2025-06-08 22:26:26 -07:00
commit 0027502707
8 changed files with 70 additions and 69 deletions

View file

@ -25,7 +25,7 @@ body:
- type: input - type: input
attributes: attributes:
label: Which Umami version are you using? (if relevant) label: Which Umami version are you using? (if relevant)
description: 'For example: Chrome, Edge, Firefox, etc' description: 'For example: 2.18.0, 2.15.1, 1.39.0, etc'
- type: input - type: input
attributes: attributes:
label: Which browser are you using? (if relevant) label: Which browser are you using? (if relevant)

View file

@ -11,6 +11,8 @@ env:
jobs: jobs:
build: build:
# Only run the CI if it belongs to the original repository
if: github.repository == 'umami-software/umami'
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:

View file

@ -246,3 +246,38 @@ SELECT * ORDER BY toStartOfDay(created_at), website_id, referrer_domain, created
); );
ALTER TABLE umami.website_event MATERIALIZE PROJECTION website_event_referrer_domain_projection; ALTER TABLE umami.website_event MATERIALIZE PROJECTION website_event_referrer_domain_projection;
-- revenue
CREATE TABLE umami.website_revenue
(
website_id UUID,
session_id UUID,
event_id UUID,
event_name String,
currency String,
revenue DECIMAL(18,4),
created_at DateTime('UTC')
)
ENGINE = MergeTree
PARTITION BY toYYYYMM(created_at)
ORDER BY (website_id, session_id, created_at)
SETTINGS index_granularity = 8192;
CREATE MATERIALIZED VIEW umami.website_revenue_mv
TO umami.website_revenue
AS
SELECT DISTINCT
ed.website_id,
ed.session_id,
ed.event_id,
ed.event_name,
c.currency,
coalesce(toDecimal64(ed.number_value, 2), toDecimal64(ed.string_value, 2)) revenue,
ed.created_at
FROM umami.event_data ed
JOIN (SELECT event_id, string_value as currency
FROM umami.event_data
WHERE positionCaseInsensitive(data_key, 'currency') > 0) c
ON c.event_id = ed.event_id
WHERE positionCaseInsensitive(data_key, 'revenue') > 0;

View file

@ -1,7 +1,3 @@
-- ConvertData
UPDATE "report"
SET "parameters" = CONCAT('"', REPLACE(parameters, '"', '\"'), '"');
-- AlterTable -- AlterTable
ALTER TABLE "report" ALTER TABLE "report"
ALTER COLUMN "parameters" SET DATA TYPE JSONB USING parameters::JSONB; ALTER COLUMN "parameters" SET DATA TYPE JSONB USING parameters::JSONB;

View file

@ -145,7 +145,8 @@ export async function POST(request: Request) {
const base = hostname ? `https://${hostname}` : 'https://localhost'; const base = hostname ? `https://${hostname}` : 'https://localhost';
const currentUrl = new URL(url, base); const currentUrl = new URL(url, base);
let urlPath = currentUrl.pathname === '/undefined' ? '' : currentUrl.pathname; let urlPath =
currentUrl.pathname === '/undefined' ? '' : currentUrl.pathname + currentUrl.hash;
const urlQuery = currentUrl.search.substring(1); const urlQuery = currentUrl.search.substring(1);
const urlDomain = currentUrl.hostname.replace(/^www./, ''); const urlDomain = currentUrl.hostname.replace(/^www./, '');
@ -169,7 +170,7 @@ export async function POST(request: Request) {
const twclid = currentUrl.searchParams.get('twclid'); const twclid = currentUrl.searchParams.get('twclid');
if (process.env.REMOVE_TRAILING_SLASH) { if (process.env.REMOVE_TRAILING_SLASH) {
urlPath = urlPath.replace(/(.+)\/$/, '$1'); urlPath = urlPath.replace(/\/(?=(#.*)?$)/, '');
} }
if (referrer) { if (referrer) {

View file

@ -124,7 +124,9 @@ export async function getLocation(ip: string = '', headers: Headers, hasPayloadI
if (!globalThis[MAXMIND]) { if (!globalThis[MAXMIND]) {
const dir = path.join(process.cwd(), 'geo'); const dir = path.join(process.cwd(), 'geo');
globalThis[MAXMIND] = await maxmind.open(path.resolve(dir, 'GeoLite2-City.mmdb')); globalThis[MAXMIND] = await maxmind.open(
process.env.GEOLITE_DB_PATH || path.resolve(dir, 'GeoLite2-City.mmdb'),
);
} }
const result = globalThis[MAXMIND].get(ip); const result = globalThis[MAXMIND].get(ip);

View file

@ -311,21 +311,14 @@ async function clickhouseQuery(
const revenueEventQuery = `WITH events AS ( const revenueEventQuery = `WITH events AS (
select select
ed.session_id, session_id,
max(ed.created_at) max_dt, max(created_at) max_dt,
sum(coalesce(toDecimal64(number_value, 2), toDecimal64(string_value, 2))) as value sum(revenue) as value
from event_data ed from website_revenue
join (select event_id
from event_data
where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64}
and positionCaseInsensitive(data_key, 'currency') > 0
and string_value = {currency:String}) c
on c.event_id = ed.event_id
where website_id = {websiteId:UUID} where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64} and created_at between {startDate:DateTime64} and {endDate:DateTime64}
and ${column} = {conversionStep:String} and ${column} = {conversionStep:String}
and positionCaseInsensitive(ed.data_key, 'revenue') > 0 and currency = {currency:String}
group by 1),`; group by 1),`;
function getModelQuery(model: string) { function getModelQuery(model: string) {

View file

@ -164,18 +164,11 @@ async function clickhouseQuery(
select select
event_name x, event_name x,
${getDateSQL('created_at', unit)} t, ${getDateSQL('created_at', unit)} t,
sum(coalesce(toDecimal64(number_value, 2), toDecimal64(string_value, 2))) y sum(revenue) y
from event_data from website_revenue
join (select event_id
from event_data
where website_id = {websiteId:UUID} where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64} and created_at between {startDate:DateTime64} and {endDate:DateTime64}
and positionCaseInsensitive(data_key, 'currency') > 0 and currency = {currency:String}
and string_value = {currency:String}) currency
on currency.event_id = event_data.event_id
where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64}
and positionCaseInsensitive(data_key, 'revenue') > 0
group by x, t group by x, t
order by t order by t
`, `,
@ -191,23 +184,16 @@ async function clickhouseQuery(
` `
select select
s.country as name, s.country as name,
sum(coalesce(toDecimal64(number_value, 2), toDecimal64(string_value, 2))) as value sum(w.revenue) as value
from event_data ed from website_revenue w
join (select event_id
from event_data
where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64}
and positionCaseInsensitive(data_key, 'currency') > 0
and string_value = {currency:String}) c
on c.event_id = ed.event_id
join (select distinct website_id, session_id, country join (select distinct website_id, session_id, country
from website_event_stats_hourly from website_event_stats_hourly
where website_id = {websiteId:UUID}) s where website_id = {websiteId:UUID}) s
on ed.website_id = s.website_id on w.website_id = s.website_id
and ed.session_id = s.session_id and w.session_id = s.session_id
where ed.website_id = {websiteId:UUID} where w.website_id = {websiteId:UUID}
and ed.created_at between {startDate:DateTime64} and {endDate:DateTime64} and w.created_at between {startDate:DateTime64} and {endDate:DateTime64}
and positionCaseInsensitive(ed.data_key, 'revenue') > 0 and w.currency = {currency:String}
group by s.country group by s.country
`, `,
{ websiteId, startDate, endDate, currency }, { websiteId, startDate, endDate, currency },
@ -221,20 +207,13 @@ async function clickhouseQuery(
}>( }>(
` `
select select
sum(coalesce(toDecimal64(number_value, 2), toDecimal64(string_value, 2))) as sum, sum(revenue) as sum,
uniqExact(event_id) as count, uniqExact(event_id) as count,
uniqExact(session_id) as unique_count uniqExact(session_id) as unique_count
from event_data from website_revenue
join (select event_id
from event_data
where website_id = {websiteId:UUID} where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64} and created_at between {startDate:DateTime64} and {endDate:DateTime64}
and positionCaseInsensitive(data_key, 'currency') > 0 and currency = {currency:String}
and string_value = {currency:String}) currency
on currency.event_id = event_data.event_id
where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64}
and positionCaseInsensitive(data_key, 'revenue') > 0
`, `,
{ websiteId, startDate, endDate, currency }, { websiteId, startDate, endDate, currency },
).then(result => result?.[0]); ).then(result => result?.[0]);
@ -250,22 +229,15 @@ async function clickhouseQuery(
>( >(
` `
select select
c.currency, currency,
sum(coalesce(toDecimal64(ed.number_value, 2), toDecimal64(ed.string_value, 2))) as sum, sum(revenue) as sum,
uniqExact(ed.event_id) as count, uniqExact(event_id) as count,
uniqExact(ed.session_id) as unique_count uniqExact(session_id) as unique_count
from event_data ed from website_revenue
join (select event_id, string_value as currency
from event_data
where website_id = {websiteId:UUID} where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64} and created_at between {startDate:DateTime64} and {endDate:DateTime64}
and positionCaseInsensitive(data_key, 'currency') > 0) c group by currency
on c.event_id = ed.event_id order by sum desc
where website_id = {websiteId:UUID}
and created_at between {startDate:DateTime64} and {endDate:DateTime64}
and positionCaseInsensitive(data_key, 'revenue') > 0
group by c.currency
order by sum desc;
`, `,
{ websiteId, startDate, endDate, unit, currency }, { websiteId, startDate, endDate, unit, currency },
); );