Initial affiliate codes implementation (#4382)

* Initial affiliate codes implementation

* some more docs to codes

* sqlx prepare

* Address PR comments

* Address more PR comments

* fix clippy

* Switch to using Json<T> for type-safe responses
This commit is contained in:
aecsocket
2025-09-18 16:43:34 +01:00
committed by GitHub
parent 6da190ed01
commit 4def0e8407
15 changed files with 607 additions and 2 deletions

View File

@@ -0,0 +1,67 @@
use ariadne::ids::UserId;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use crate::models::ids::AffiliateCodeId;
/// Affiliate code used to track referral purchases.
///
/// See [`AffiliateCode`].
///
/// This struct contains information which should only be visible to admins.
#[derive(Serialize, Deserialize)]
pub struct AdminAffiliateCode {
/// Affiliate code ID.
pub id: AffiliateCodeId,
/// When the code was created.
pub created_at: DateTime<Utc>,
/// User who created the code.
pub created_by: UserId,
/// User who refers the purchaser.
pub affiliate: UserId,
}
/// Affiliate code used to track referral purchases.
///
/// When a user follows a URL with [`AffiliateCode::id`] as an affiliate
/// parameter, the code will be saved as a cookie. When the same user purchases
/// a product with an affiliate code cookie, the purchase under that code is
/// tracked.
///
/// This struct contains information which is allowed to be seen by an
/// affiliate.
#[derive(Serialize, Deserialize)]
pub struct AffiliateCode {
/// Affiliate code ID.
pub id: AffiliateCodeId,
/// User who refers the purchaser.
pub affiliate: UserId,
}
impl From<crate::database::models::affiliate_code_item::DBAffiliateCode>
for AdminAffiliateCode
{
fn from(
data: crate::database::models::affiliate_code_item::DBAffiliateCode,
) -> Self {
Self {
id: data.id.into(),
created_at: data.created_at,
created_by: data.created_by.into(),
affiliate: data.affiliate.into(),
}
}
}
impl From<crate::database::models::affiliate_code_item::DBAffiliateCode>
for AffiliateCode
{
fn from(
data: crate::database::models::affiliate_code_item::DBAffiliateCode,
) -> Self {
Self {
id: data.id.into(),
affiliate: data.affiliate.into(),
}
}
}

View File

@@ -25,3 +25,4 @@ base62_id!(ThreadId);
base62_id!(ThreadMessageId);
base62_id!(UserSubscriptionId);
base62_id!(VersionId);
base62_id!(AffiliateCodeId);

View File

@@ -1,3 +1,4 @@
pub mod affiliate_code;
pub mod analytics;
pub mod billing;
pub mod collections;