mirror of
https://github.com/modrinth/code.git
synced 2026-08-30 11:36:05 +00:00
start on runs routes
This commit is contained in:
@@ -160,6 +160,7 @@ FLAME_ANVIL_URL=none
|
||||
STRIPE_API_KEY=none
|
||||
STRIPE_WEBHOOK_SECRET=none
|
||||
|
||||
ADITUDE_BASE_URL=https://cloud.aditude.io/api
|
||||
ADITUDE_API_KEY=none
|
||||
|
||||
PYRO_API_KEY=none
|
||||
|
||||
@@ -186,6 +186,7 @@ FLAME_ANVIL_URL=none
|
||||
STRIPE_API_KEY=none
|
||||
STRIPE_WEBHOOK_SECRET=none
|
||||
|
||||
ADITUDE_BASE_URL=https://cloud.aditude.io/api
|
||||
ADITUDE_API_KEY=none
|
||||
|
||||
PYRO_API_KEY=none
|
||||
|
||||
@@ -335,6 +335,7 @@ vars! {
|
||||
STRIPE_API_KEY: String = "none";
|
||||
STRIPE_WEBHOOK_SECRET: String = "none";
|
||||
|
||||
ADITUDE_BASE_URL: String = "https://cloud.aditude.io/api";
|
||||
ADITUDE_API_KEY: String = "none";
|
||||
|
||||
PYRO_API_KEY: String = "none";
|
||||
|
||||
@@ -70,6 +70,7 @@ pub struct LabrinthConfig {
|
||||
pub rate_limiter: web::Data<AsyncRateLimiter>,
|
||||
pub stripe_client: stripe::Client,
|
||||
pub anrok_client: anrok::Client,
|
||||
pub aditude_client: web::Data<aditude::Client>,
|
||||
pub email_queue: web::Data<EmailQueue>,
|
||||
pub archon_client: web::Data<ArchonClient>,
|
||||
pub gotenberg_client: GotenbergClient,
|
||||
@@ -99,6 +100,10 @@ pub fn app_setup(
|
||||
let scheduler = scheduler::Scheduler::new();
|
||||
|
||||
let http_client = web::Data::new(HttpClient::new());
|
||||
let aditude_client = web::Data::new(aditude::Client::new(
|
||||
ENV.ADITUDE_BASE_URL.clone(),
|
||||
ENV.ADITUDE_API_KEY.clone(),
|
||||
));
|
||||
let tiltify_client =
|
||||
web::Data::new(TiltifyClient::new(http_client.get_ref().clone()));
|
||||
let search_state = web::Data::new(search::SearchState {
|
||||
@@ -302,6 +307,7 @@ pub fn app_setup(
|
||||
rate_limiter: limiter,
|
||||
stripe_client,
|
||||
anrok_client,
|
||||
aditude_client,
|
||||
gotenberg_client,
|
||||
http_client,
|
||||
tiltify_client,
|
||||
@@ -359,6 +365,7 @@ pub fn app_data_config(
|
||||
.app_data(labrinth_config.archon_client.clone())
|
||||
.app_data(web::Data::new(labrinth_config.stripe_client.clone()))
|
||||
.app_data(web::Data::new(labrinth_config.anrok_client.clone()))
|
||||
.app_data(labrinth_config.aditude_client.clone())
|
||||
.app_data(labrinth_config.rate_limiter.clone())
|
||||
.app_data(labrinth_config.kafka_client.clone())
|
||||
.app_data(labrinth_config.search_state.clone())
|
||||
|
||||
@@ -36,7 +36,7 @@ pub async fn estimate(
|
||||
periods: &[YearMonth],
|
||||
) -> Result<Vec<PeriodEstimate>> {
|
||||
redis
|
||||
.get_cached_keys(REDIS_KEY, periods, |periods| async {
|
||||
.get_cached_keys(REDIS_KEY, periods, |periods| async move {
|
||||
fetch_estimates(aditude, redis, &periods)
|
||||
.await
|
||||
.map_err(ApiError::Internal)
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
//!
|
||||
//! How revenue is distributed:
|
||||
//! - While a month is still open/in review:
|
||||
//! - `raw_estimated_revenue_usd`: how much our ad provider estimates we'll
|
||||
//! - `estimated.raw_revenue_usd`: how much our ad provider estimates we'll
|
||||
//! earn for a specific period
|
||||
//! - We also get a value for this per day
|
||||
//! - `fees_usd`: how much we pay in fees to Clean.io
|
||||
@@ -36,23 +36,23 @@
|
||||
//! - e.g. if variance is 10%, and we estimate that we'll earn $100k, then
|
||||
//! our ad provider will probably give us closer to $90k - the variance
|
||||
//! lets us express this difference
|
||||
//! - `net_estimated_revenue_usd`: raw estimated - fees - variance
|
||||
//! - `platform_net_estimated_revenue_usd`: net estimated revenue x Modrinth's cut
|
||||
//! - `creator_net_estimated_revenue_usd`: net estimated revenue x (1 - Modrinth's cut)
|
||||
//! - `net_revenue_usd`: raw estimated - fees - variance
|
||||
//! - `platform_net_revenue_usd`: net estimated revenue x Modrinth's cut
|
||||
//! - `creator_net_revenue_usd`: net estimated revenue x (1 - Modrinth's cut)
|
||||
//! - After a payout run has been executed:
|
||||
//! - We save the per-day raw estimated revenue and impressions in the
|
||||
//! database
|
||||
//! - `raw_actual_revenue_usd`: how much we got from Aditude, input by an admin
|
||||
//! - `actual.raw_revenue_usd`: how much we got from Aditude, input by an admin
|
||||
//! - We compute this per-day by:
|
||||
//! ```text
|
||||
//! let factor = raw_actual_revenue_usd / raw_estimated_revenue_usd
|
||||
//! raw_actual_revenue_usd_for_today = raw_estimated_revenue_usd_for_today * factor
|
||||
//! let factor = actual.raw_revenue_usd / raw_estimated_revenue_usd
|
||||
//! raw_revenue_usd_for_today = raw_estimated_revenue_usd_for_today * factor
|
||||
//! ```
|
||||
//! - (fees stay the same, since they're based on impressions, not revenue)
|
||||
//! - (variance is ignored, since that's purely an estimation value)
|
||||
//! - `adjustments_usd`: sum of all manual adjustments input by the admin
|
||||
//! - `net_actual_revenue_usd`: raw actual revenue - fees + adjustments
|
||||
//! - `(platform|creator)_net_estimated_revenue_usd`: same logic as estimated,
|
||||
//! - `actual.net_revenue_usd`: raw actual revenue - fees + adjustments
|
||||
//! - `actual.(platform|creator)_net_revenue_usd`: same logic as estimated,
|
||||
//! but using the net actual revenue
|
||||
//!
|
||||
//! ## Variance
|
||||
@@ -76,12 +76,22 @@ const PLATFORM_REVENUE_SPLIT: Decimal = dec!(0.25);
|
||||
/// This may refer to either estimated or actual revenue.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct DayDistribution {
|
||||
/// Amount of revenue input into the algorithm.
|
||||
pub raw_revenue_usd: Decimal,
|
||||
/// Operational fees to subtract.
|
||||
pub fees_usd: Decimal,
|
||||
/// Estimation variance to subtract.
|
||||
///
|
||||
/// For non-estimates (actual revenue values), this is zero.
|
||||
pub variance_usd: Decimal,
|
||||
/// Manually-input adjustments on top of raw revenue.
|
||||
pub sum_adjustments_usd: Decimal,
|
||||
/// Total net revenue that we earned;
|
||||
/// `raw_revenue - fees - variance + sum_adjustments`.
|
||||
pub net_revenue_usd: Decimal,
|
||||
/// How much of the net revenue goes to the platform.
|
||||
pub platform_net_revenue_usd: Decimal,
|
||||
/// How much of the net revenue goes to creators.
|
||||
pub creator_net_revenue_usd: Decimal,
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ pub mod medal;
|
||||
pub mod moderation;
|
||||
pub mod mural;
|
||||
pub mod pats;
|
||||
pub mod payout_runs;
|
||||
pub mod search;
|
||||
pub mod server_ping;
|
||||
pub mod session;
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
use actix_web::{get, web};
|
||||
|
||||
use crate::{queue::payout_run::DayDistribution, routes::ApiError};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct PayoutRuns {
|
||||
pub periods: Vec<PayoutRunPeriod>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct PayoutRunPeriod {
|
||||
pub period: YearMonth,
|
||||
pub status: PayoutRunStatus,
|
||||
pub days: Vec<PayoutRunDay>,
|
||||
pub adjustments: Vec<PayoutRunAdjustment>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct PayoutRunDay {
|
||||
pub date: NaiveDate,
|
||||
pub estimated: DayDistribution,
|
||||
pub actual: Option<DayDistribution>,
|
||||
}
|
||||
|
||||
/// Manual admin-input adjustment to a [`PayoutRunPeriod`].
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct PayoutRunAdjustment {
|
||||
/// Total value of the adjustment.
|
||||
pub amount_usd: Decimal,
|
||||
/// Why this adjustment was applied.
|
||||
///
|
||||
/// Only visible to admins.
|
||||
pub description: Option<String>,
|
||||
}
|
||||
|
||||
#[get("/")]
|
||||
pub async fn get_runs() -> Result<web::Json<PayoutRuns>, ApiError> {}
|
||||
Reference in New Issue
Block a user