added stats page for referrals (shared, and received) (#95)
* added stats page for referrals (shared, and received) * removed referrals address, and return ok response if no referrals used * merged from devel * changed unwrap for context * changes from PR
This commit is contained in:
parent
172baabb4e
commit
fd69e6acdd
@ -189,6 +189,14 @@ pub async fn serve(
|
|||||||
"/user/referral",
|
"/user/referral",
|
||||||
get(users::referral::user_referral_link_get),
|
get(users::referral::user_referral_link_get),
|
||||||
)
|
)
|
||||||
|
.route(
|
||||||
|
"/user/referral/stats/used-codes",
|
||||||
|
get(users::referral::user_used_referral_stats),
|
||||||
|
)
|
||||||
|
.route(
|
||||||
|
"/user/referral/stats/shared-codes",
|
||||||
|
get(users::referral::user_shared_referral_stats),
|
||||||
|
)
|
||||||
.route("/user/revert_logs", get(users::stats::user_revert_logs_get))
|
.route("/user/revert_logs", get(users::stats::user_revert_logs_get))
|
||||||
.route(
|
.route(
|
||||||
"/user/stats/aggregate",
|
"/user/stats/aggregate",
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
//! Handle registration, logins, and managing account data.
|
//! Handle registration, logins, and managing account data.
|
||||||
use crate::app::Web3ProxyApp;
|
use crate::app::Web3ProxyApp;
|
||||||
use crate::errors::Web3ProxyResponse;
|
use crate::errors::Web3ProxyResponse;
|
||||||
|
use crate::frontend::users::referral;
|
||||||
use crate::referral_code::ReferralCode;
|
use crate::referral_code::ReferralCode;
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use axum::{
|
use axum::{
|
||||||
@ -10,14 +11,18 @@ use axum::{
|
|||||||
Extension, Json, TypedHeader,
|
Extension, Json, TypedHeader,
|
||||||
};
|
};
|
||||||
use axum_macros::debug_handler;
|
use axum_macros::debug_handler;
|
||||||
use entities::referrer;
|
use entities::{referee, referrer, user};
|
||||||
|
use ethers::types::Address;
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use http::StatusCode;
|
use http::StatusCode;
|
||||||
use migration::sea_orm;
|
use migration::sea_orm;
|
||||||
|
use migration::sea_orm::prelude::{DateTime, Decimal};
|
||||||
use migration::sea_orm::ActiveModelTrait;
|
use migration::sea_orm::ActiveModelTrait;
|
||||||
use migration::sea_orm::ColumnTrait;
|
use migration::sea_orm::ColumnTrait;
|
||||||
use migration::sea_orm::EntityTrait;
|
use migration::sea_orm::EntityTrait;
|
||||||
use migration::sea_orm::QueryFilter;
|
use migration::sea_orm::QueryFilter;
|
||||||
|
use num_traits::one;
|
||||||
|
use serde::Serialize;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
@ -70,3 +75,132 @@ pub async fn user_referral_link_get(
|
|||||||
let response = (status_code, Json(response_json)).into_response();
|
let response = (status_code, Json(response_json)).into_response();
|
||||||
Ok(response)
|
Ok(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[debug_handler]
|
||||||
|
pub async fn user_used_referral_stats(
|
||||||
|
Extension(app): Extension<Arc<Web3ProxyApp>>,
|
||||||
|
TypedHeader(Authorization(bearer)): TypedHeader<Authorization<Bearer>>,
|
||||||
|
Query(_params): Query<HashMap<String, String>>,
|
||||||
|
) -> Web3ProxyResponse {
|
||||||
|
// First get the bearer token and check if the user is logged in
|
||||||
|
let (user, _semaphore) = app.bearer_is_authorized(bearer).await?;
|
||||||
|
|
||||||
|
let db_replica = app
|
||||||
|
.db_replica()
|
||||||
|
.context("getting replica db for user's revert logs")?;
|
||||||
|
|
||||||
|
// Get all referral records associated with this user
|
||||||
|
let referrals = referee::Entity::find()
|
||||||
|
.filter(referee::Column::UserId.eq(user.id))
|
||||||
|
.find_also_related(referrer::Entity)
|
||||||
|
.all(db_replica.as_ref())
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
// For each related referral person, find the corresponding user-address
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
struct Info {
|
||||||
|
credits_applied_for_referee: bool,
|
||||||
|
credits_applied_for_referrer: Decimal,
|
||||||
|
referral_start_date: DateTime,
|
||||||
|
used_referral_code: String,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut out: Vec<Info> = Vec::new();
|
||||||
|
for x in referrals.into_iter() {
|
||||||
|
let (referral_record, referrer_record) = (x.0, x.1.context("each referral entity should have a referral code associated with it, but this is not the case!")?);
|
||||||
|
// The foreign key is never optional
|
||||||
|
let referring_user = user::Entity::find_by_id(referrer_record.user_id)
|
||||||
|
.one(db_replica.as_ref())
|
||||||
|
.await?
|
||||||
|
.context("Database error, no foreign key found for referring user")?;
|
||||||
|
let tmp = Info {
|
||||||
|
credits_applied_for_referee: referral_record.credits_applied_for_referee,
|
||||||
|
credits_applied_for_referrer: referral_record.credits_applied_for_referrer,
|
||||||
|
referral_start_date: referral_record.referral_start_date,
|
||||||
|
used_referral_code: referrer_record.referral_code,
|
||||||
|
};
|
||||||
|
// Start inserting json's into this
|
||||||
|
out.push(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Turn this into a response
|
||||||
|
let response_json = json!({
|
||||||
|
"referrals": out,
|
||||||
|
"user": user,
|
||||||
|
});
|
||||||
|
|
||||||
|
let response = (StatusCode::OK, Json(response_json)).into_response();
|
||||||
|
Ok(response)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[debug_handler]
|
||||||
|
pub async fn user_shared_referral_stats(
|
||||||
|
Extension(app): Extension<Arc<Web3ProxyApp>>,
|
||||||
|
TypedHeader(Authorization(bearer)): TypedHeader<Authorization<Bearer>>,
|
||||||
|
Query(_params): Query<HashMap<String, String>>,
|
||||||
|
) -> Web3ProxyResponse {
|
||||||
|
// First get the bearer token and check if the user is logged in
|
||||||
|
let (user, _semaphore) = app.bearer_is_authorized(bearer).await?;
|
||||||
|
|
||||||
|
let db_replica = app
|
||||||
|
.db_replica()
|
||||||
|
.context("getting replica db for user's revert logs")?;
|
||||||
|
|
||||||
|
// Get all referral records associated with this user
|
||||||
|
let referrals = referrer::Entity::find()
|
||||||
|
.filter(referrer::Column::UserId.eq(user.id))
|
||||||
|
.find_also_related(referee::Entity)
|
||||||
|
.all(db_replica.as_ref())
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
// Return early if the user does not have any referred entities
|
||||||
|
if referrals.len() == 0 {
|
||||||
|
let response_json = json!({
|
||||||
|
"referrals": [],
|
||||||
|
"used_referral_code": None::<()>,
|
||||||
|
"user": user,
|
||||||
|
});
|
||||||
|
|
||||||
|
let response = (StatusCode::OK, Json(response_json)).into_response();
|
||||||
|
return Ok(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
// For each related referral person, find the corresponding user-address
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
struct Info {
|
||||||
|
credits_applied_for_referee: bool,
|
||||||
|
credits_applied_for_referrer: Decimal,
|
||||||
|
referral_start_date: DateTime,
|
||||||
|
referred_address: Address,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut out: Vec<Info> = Vec::new();
|
||||||
|
let mut used_referral_code = "".to_owned(); // This is only for safety purposes, because of the condition above we always know that there is at least one record
|
||||||
|
for x in referrals.into_iter() {
|
||||||
|
let (referrer, referral_record) = (x.0, x.1.context("each referral code should have a referee associated with it (that's what we query), but this is not the case!")?);
|
||||||
|
used_referral_code = referrer.referral_code;
|
||||||
|
// The foreign key is never optional
|
||||||
|
let referred_user = user::Entity::find_by_id(referral_record.user_id)
|
||||||
|
.one(db_replica.as_ref())
|
||||||
|
.await?
|
||||||
|
.context("Database error, no foreign key found for referring user")?;
|
||||||
|
let tmp = Info {
|
||||||
|
credits_applied_for_referee: referral_record.credits_applied_for_referee,
|
||||||
|
credits_applied_for_referrer: referral_record.credits_applied_for_referrer,
|
||||||
|
referral_start_date: referral_record.referral_start_date,
|
||||||
|
referred_address: Address::from_slice(&referred_user.address),
|
||||||
|
};
|
||||||
|
// Start inserting json's into this
|
||||||
|
out.push(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Turn this into a response
|
||||||
|
let response_json = json!({
|
||||||
|
"referrals": out,
|
||||||
|
"used_referral_code": used_referral_code,
|
||||||
|
"user": user,
|
||||||
|
});
|
||||||
|
|
||||||
|
let response = (StatusCode::OK, Json(response_json)).into_response();
|
||||||
|
Ok(response)
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user