use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
use crate::models::AuthMethod;
use crate::repositories::{OrgEntity, UserEntity};
#[derive(Debug, Clone, Deserialize)]
pub struct ListUsersQueryParams {
#[serde(default = "default_limit")]
pub limit: u32,
#[serde(default)]
pub offset: u32,
}
#[derive(Debug, Clone, Deserialize)]
pub struct ListOrgsQueryParams {
#[serde(default = "default_limit")]
pub limit: u32,
#[serde(default)]
pub offset: u32,
}
fn default_limit() -> u32 {
50
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct AdminUserResponse {
pub id: Uuid,
#[serde(skip_serializing_if = "Option::is_none")]
pub email: Option<String>,
pub email_verified: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub username: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub picture: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub wallet_address: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub google_id: Option<String>,
pub auth_methods: Vec<AuthMethod>,
pub is_system_admin: bool,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
#[serde(skip_serializing_if = "Option::is_none")]
pub last_login_at: Option<DateTime<Utc>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub balance_lamports: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub referral_code: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub referred_by: Option<Uuid>,
#[serde(skip_serializing_if = "Option::is_none")]
pub referral_count: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub payout_wallet_address: Option<String>,
}
impl From<&UserEntity> for AdminUserResponse {
fn from(entity: &UserEntity) -> Self {
Self {
id: entity.id,
email: entity.email.clone(),
email_verified: entity.email_verified,
name: entity.name.clone(),
username: entity.username.clone(),
picture: entity.picture.clone(),
wallet_address: entity.wallet_address.clone(),
google_id: entity.google_id.clone(),
auth_methods: entity.auth_methods.clone(),
is_system_admin: entity.is_system_admin,
created_at: entity.created_at,
updated_at: entity.updated_at,
last_login_at: entity.last_login_at,
balance_lamports: None, referral_code: Some(entity.referral_code.clone()),
referred_by: entity.referred_by,
referral_count: None, payout_wallet_address: entity.payout_wallet_address.clone(),
}
}
}
impl AdminUserResponse {
pub fn with_balance(mut self, balance: i64) -> Self {
self.balance_lamports = Some(balance);
self
}
pub fn with_referral_count(mut self, count: u64) -> Self {
self.referral_count = Some(count);
self
}
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ListUsersResponse {
pub users: Vec<AdminUserResponse>,
pub total: u64,
pub limit: u32,
pub offset: u32,
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct AdminOrgResponse {
pub id: Uuid,
pub name: String,
pub slug: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub logo_url: Option<String>,
pub is_personal: bool,
pub owner_id: Uuid,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
impl From<&OrgEntity> for AdminOrgResponse {
fn from(entity: &OrgEntity) -> Self {
Self {
id: entity.id,
name: entity.name.clone(),
slug: entity.slug.clone(),
logo_url: entity.logo_url.clone(),
is_personal: entity.is_personal,
owner_id: entity.owner_id,
created_at: entity.created_at,
updated_at: entity.updated_at,
}
}
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ListAdminOrgsResponse {
pub orgs: Vec<AdminOrgResponse>,
pub total: u64,
pub limit: u32,
pub offset: u32,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SetSystemAdminRequest {
pub is_admin: bool,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AdjustCreditsRequest {
pub amount_lamports: i64,
#[serde(default = "default_currency")]
pub currency: String,
pub reason: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub reference_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub reference_id: Option<Uuid>,
}
fn default_currency() -> String {
"SOL".to_string()
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct AdjustCreditsResponse {
pub transaction_id: Uuid,
pub new_balance_lamports: i64,
pub amount_lamports: i64,
pub currency: String,
pub display: String,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ListCreditRefundRequestsQueryParams {
#[serde(default = "default_limit")]
pub limit: u32,
#[serde(default)]
pub offset: u32,
pub status: Option<String>,
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct AdminCreditRefundRequestResponse {
pub id: Uuid,
pub user_id: Uuid,
pub original_transaction_id: Uuid,
pub amount_lamports: i64,
pub currency: String,
pub reason: String,
pub status: String,
pub created_at: DateTime<Utc>,
#[serde(skip_serializing_if = "Option::is_none")]
pub processed_at: Option<DateTime<Utc>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub processed_by: Option<Uuid>,
#[serde(skip_serializing_if = "Option::is_none")]
pub processed_amount_lamports: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub processed_transaction_id: Option<Uuid>,
#[serde(skip_serializing_if = "Option::is_none")]
pub processed_reason: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub rejected_at: Option<DateTime<Utc>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub rejected_by: Option<Uuid>,
#[serde(skip_serializing_if = "Option::is_none")]
pub rejected_reason: Option<String>,
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ListCreditRefundRequestsResponse {
pub refund_requests: Vec<AdminCreditRefundRequestResponse>,
pub total: u64,
pub limit: u32,
pub offset: u32,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ProcessCreditRefundRequestInput {
pub amount_lamports: i64,
pub reason: String,
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ProcessCreditRefundRequestResponse {
pub processed: bool,
pub refund_request_id: Uuid,
pub processed_transaction_id: Uuid,
pub processed_amount_lamports: i64,
pub currency: String,
pub new_balance_lamports: i64,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RejectCreditRefundRequestInput {
pub reason: String,
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct RejectCreditRefundRequestResponse {
pub rejected: bool,
pub refund_request_id: Uuid,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AdminUpdateUserRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub email: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub email_verified: Option<bool>,
}