diff --git a/.sqlx/query-2aca8f34773d1028fb5d4cf5d3f2ab65cc3b8cea5f94bb0e1a0f632a787d708f.json b/.sqlx/query-4198ea701f956dd65cab1a8e60b5b67df45f8c07bb70e3c4f090d943feafdaf3.json similarity index 58% rename from .sqlx/query-2aca8f34773d1028fb5d4cf5d3f2ab65cc3b8cea5f94bb0e1a0f632a787d708f.json rename to .sqlx/query-4198ea701f956dd65cab1a8e60b5b67df45f8c07bb70e3c4f090d943feafdaf3.json index 840c77f2..be792ea9 100644 --- a/.sqlx/query-2aca8f34773d1028fb5d4cf5d3f2ab65cc3b8cea5f94bb0e1a0f632a787d708f.json +++ b/.sqlx/query-4198ea701f956dd65cab1a8e60b5b67df45f8c07bb70e3c4f090d943feafdaf3.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n SELECT mod_id, SUM(amount) amount_sum, DATE_BIN($4::interval, created, TIMESTAMP '2001-01-01') AS interval_start\n FROM payouts_values\n WHERE mod_id = ANY($1) AND created BETWEEN $2 AND $3\n GROUP by mod_id, interval_start ORDER BY interval_start\n ", + "query": "\n SELECT mod_id, SUM(amount) amount_sum, DATE_BIN($4::interval, created, TIMESTAMP '2001-01-01') AS interval_start\n FROM payouts_values\n WHERE mod_id = ANY($1) AND created BETWEEN $2 AND $3\n GROUP by mod_id, interval_start ORDER BY interval_start\n ", "describe": { "columns": [ { @@ -33,5 +33,5 @@ null ] }, - "hash": "2aca8f34773d1028fb5d4cf5d3f2ab65cc3b8cea5f94bb0e1a0f632a787d708f" + "hash": "4198ea701f956dd65cab1a8e60b5b67df45f8c07bb70e3c4f090d943feafdaf3" } diff --git a/.sqlx/query-dfb4bd3db0d1cc2b2f811c267547a224ee4710e202cf1c8f3f35e49b54d6f2f9.json b/.sqlx/query-dfb4bd3db0d1cc2b2f811c267547a224ee4710e202cf1c8f3f35e49b54d6f2f9.json new file mode 100644 index 00000000..2515dfe4 --- /dev/null +++ b/.sqlx/query-dfb4bd3db0d1cc2b2f811c267547a224ee4710e202cf1c8f3f35e49b54d6f2f9.json @@ -0,0 +1,37 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT mod_id, SUM(amount) amount_sum, DATE_BIN($4::interval, created, TIMESTAMP '2001-01-01') AS interval_start\n FROM payouts_values\n WHERE user_id = $1 AND created BETWEEN $2 AND $3\n GROUP by mod_id, interval_start ORDER BY interval_start\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "mod_id", + "type_info": "Int8" + }, + { + "ordinal": 1, + "name": "amount_sum", + "type_info": "Numeric" + }, + { + "ordinal": 2, + "name": "interval_start", + "type_info": "Timestamptz" + } + ], + "parameters": { + "Left": [ + "Int8", + "Timestamptz", + "Timestamptz", + "Interval" + ] + }, + "nullable": [ + true, + null, + null + ] + }, + "hash": "dfb4bd3db0d1cc2b2f811c267547a224ee4710e202cf1c8f3f35e49b54d6f2f9" +} diff --git a/src/routes/v3/analytics_get.rs b/src/routes/v3/analytics_get.rs index 7447c1db..9fa3d7f4 100644 --- a/src/routes/v3/analytics_get.rs +++ b/src/routes/v3/analytics_get.rs @@ -98,7 +98,7 @@ pub async fn playtimes_get( // Convert String list to list of ProjectIds or VersionIds // - Filter out unauthorized projects/versions // - If no project_ids or version_ids are provided, we default to all projects the user has access to - let project_ids = filter_allowed_ids(project_ids, user, &pool, &redis).await?; + let project_ids = filter_allowed_ids(project_ids, user, &pool, &redis, None).await?; // Get the views let playtimes = crate::clickhouse::fetch_playtimes( @@ -164,7 +164,7 @@ pub async fn views_get( // Convert String list to list of ProjectIds or VersionIds // - Filter out unauthorized projects/versions // - If no project_ids or version_ids are provided, we default to all projects the user has access to - let project_ids = filter_allowed_ids(project_ids, user, &pool, &redis).await?; + let project_ids = filter_allowed_ids(project_ids, user, &pool, &redis, None).await?; // Get the views let views = crate::clickhouse::fetch_views( @@ -230,7 +230,7 @@ pub async fn downloads_get( // Convert String list to list of ProjectIds or VersionIds // - Filter out unauthorized projects/versions // - If no project_ids or version_ids are provided, we default to all projects the user has access to - let project_ids = filter_allowed_ids(project_ids, user_option, &pool, &redis).await?; + let project_ids = filter_allowed_ids(project_ids, user_option, &pool, &redis, None).await?; // Get the downloads let downloads = crate::clickhouse::fetch_downloads( @@ -304,27 +304,60 @@ pub async fn revenue_get( // Convert String list to list of ProjectIds or VersionIds // - Filter out unauthorized projects/versions // - If no project_ids or version_ids are provided, we default to all projects the user has access to - let project_ids = filter_allowed_ids(project_ids, user, &pool, &redis).await?; + let project_ids = + filter_allowed_ids(project_ids, user.clone(), &pool, &redis, Some(true)).await?; let duration: PgInterval = Duration::minutes(resolution_minutes as i64) .try_into() .map_err(|_| ApiError::InvalidInput("Invalid resolution_minutes".to_string()))?; // Get the revenue data let project_ids = project_ids.unwrap_or_default(); - let payouts_values = sqlx::query!( - " - SELECT mod_id, SUM(amount) amount_sum, DATE_BIN($4::interval, created, TIMESTAMP '2001-01-01') AS interval_start - FROM payouts_values - WHERE mod_id = ANY($1) AND created BETWEEN $2 AND $3 - GROUP by mod_id, interval_start ORDER BY interval_start - ", - &project_ids.iter().map(|x| x.0 as i64).collect::>(), - start_date, - end_date, - duration, - ) - .fetch_all(&**pool) - .await?; + + struct PayoutValue { + mod_id: Option, + amount_sum: Option, + interval_start: Option>, + } + + let payouts_values = if project_ids.is_empty() { + sqlx::query!( + " + SELECT mod_id, SUM(amount) amount_sum, DATE_BIN($4::interval, created, TIMESTAMP '2001-01-01') AS interval_start + FROM payouts_values + WHERE user_id = $1 AND created BETWEEN $2 AND $3 + GROUP by mod_id, interval_start ORDER BY interval_start + ", + user.id.0 as i64, + start_date, + end_date, + duration, + ) + .fetch_all(&**pool) + .await?.into_iter().map(|x| PayoutValue { + mod_id: x.mod_id, + amount_sum: x.amount_sum, + interval_start: x.interval_start, + }).collect::>() + } else { + sqlx::query!( + " + SELECT mod_id, SUM(amount) amount_sum, DATE_BIN($4::interval, created, TIMESTAMP '2001-01-01') AS interval_start + FROM payouts_values + WHERE mod_id = ANY($1) AND created BETWEEN $2 AND $3 + GROUP by mod_id, interval_start ORDER BY interval_start + ", + &project_ids.iter().map(|x| x.0 as i64).collect::>(), + start_date, + end_date, + duration, + ) + .fetch_all(&**pool) + .await?.into_iter().map(|x| PayoutValue { + mod_id: x.mod_id, + amount_sum: x.amount_sum, + interval_start: x.interval_start, + }).collect::>() + }; let mut hm: HashMap<_, _> = project_ids .into_iter() @@ -391,7 +424,7 @@ pub async fn countries_downloads_get( // Convert String list to list of ProjectIds or VersionIds // - Filter out unauthorized projects/versions // - If no project_ids or version_ids are provided, we default to all projects the user has access to - let project_ids = filter_allowed_ids(project_ids, user, &pool, &redis).await?; + let project_ids = filter_allowed_ids(project_ids, user, &pool, &redis, None).await?; // Get the countries let countries = crate::clickhouse::fetch_countries_downloads( @@ -463,7 +496,7 @@ pub async fn countries_views_get( // Convert String list to list of ProjectIds or VersionIds // - Filter out unauthorized projects/versions // - If no project_ids or version_ids are provided, we default to all projects the user has access to - let project_ids = filter_allowed_ids(project_ids, user, &pool, &redis).await?; + let project_ids = filter_allowed_ids(project_ids, user, &pool, &redis, None).await?; // Get the countries let countries = crate::clickhouse::fetch_countries_views( @@ -515,9 +548,10 @@ async fn filter_allowed_ids( user: crate::models::users::User, pool: &web::Data, redis: &RedisPool, + remove_defaults: Option, ) -> Result>, ApiError> { // If no project_ids or version_ids are provided, we default to all projects the user has *public* access to - if project_ids.is_none() { + if project_ids.is_none() && !remove_defaults.unwrap_or(false) { project_ids = Some( user_item::User::get_projects(user.id.into(), &***pool, redis) .await? diff --git a/src/util/webhook.rs b/src/util/webhook.rs index 747739c5..df008eb1 100644 --- a/src/util/webhook.rs +++ b/src/util/webhook.rs @@ -291,6 +291,7 @@ fn get_gv_range( ) -> String { // both -> least to greatest game_versions.sort_by(|a, b| a.created.cmp(&b.created)); + game_versions.dedup_by(|a, b| a.version == b.version); all_game_versions.sort_by(|a, b| a.created.cmp(&b.created)); diff --git a/tests/analytics.rs b/tests/analytics.rs index a524a767..13c44806 100644 --- a/tests/analytics.rs +++ b/tests/analytics.rs @@ -209,7 +209,7 @@ pub async fn permissions_analytics_revenue() { // On success, should have 1 versions returned |value: &serde_json::Value| { let value = value.as_object().unwrap(); - assert_eq!(value.len(), 1); + assert_eq!(value.len(), 0); }, ) .simple_project_permissions_test(view_analytics, req_gen)