moderator endpoints for referrals (#1515)
This commit is contained in:
1 parent
6b0d210b57
commit
10733d9d23
12 files changed
+1142
No files matched your search
+146
@@ -0,0 +1,146 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n ur.id as `id: u64`,\n ur.invited_user_token as `invited_user_token: UserToken`,\n invited.username as `invited_username: String`,\n invited.display_name as `invited_display_name: String`,\n invited.email_address as `invited_email_address: String`,\n ur.referrer_user_token as `referrer_user_token: UserToken`,\n referrer.username as `referrer_username: String`,\n referrer.display_name as `referrer_display_name: String`,\n ur.maybe_referral_code_token as `maybe_referral_code_token: UserReferralCodeToken`,\n ur.maybe_referral_url,\n ur.maybe_landing_url,\n ur.created_at\nFROM user_referrals ur\nJOIN users invited ON invited.token = ur.invited_user_token\nJOIN users referrer ON referrer.token = ur.referrer_user_token\nORDER BY ur.id DESC\nLIMIT ?\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "id: u64",
|
||||
"type_info": {
|
||||
"type": "LongLong",
|
||||
"flags": "NOT_NULL | PRIMARY_KEY | UNSIGNED | AUTO_INCREMENT",
|
||||
"char_set": 63,
|
||||
"max_size": 20
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "invited_user_token: UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "invited_username: String",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "invited_display_name: String",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "invited_email_address: String",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "referrer_user_token: UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "referrer_username: String",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "referrer_display_name: String",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"name": "maybe_referral_code_token: UserReferralCodeToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"name": "maybe_referral_url",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"name": "maybe_landing_url",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"name": "created_at",
|
||||
"type_info": {
|
||||
"type": "Datetime",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "507a60f98f6da63620abc28a5a83772f29ffcfdfcc8d30bfa7c611d73073ca16"
|
||||
}
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n ur.id as `id: u64`,\n ur.invited_user_token as `invited_user_token: UserToken`,\n invited.username as `invited_username: String`,\n invited.display_name as `invited_display_name: String`,\n invited.email_address as `invited_email_address: String`,\n ur.referrer_user_token as `referrer_user_token: UserToken`,\n referrer.username as `referrer_username: String`,\n referrer.display_name as `referrer_display_name: String`,\n ur.maybe_referral_code_token as `maybe_referral_code_token: UserReferralCodeToken`,\n ur.maybe_referral_url,\n ur.maybe_landing_url,\n ur.created_at\nFROM user_referrals ur\nJOIN users invited ON invited.token = ur.invited_user_token\nJOIN users referrer ON referrer.token = ur.referrer_user_token\nWHERE ur.id < ?\nORDER BY ur.id DESC\nLIMIT ?\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "id: u64",
|
||||
"type_info": {
|
||||
"type": "LongLong",
|
||||
"flags": "NOT_NULL | PRIMARY_KEY | UNSIGNED | AUTO_INCREMENT",
|
||||
"char_set": 63,
|
||||
"max_size": 20
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "invited_user_token: UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "invited_username: String",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "invited_display_name: String",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "invited_email_address: String",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "referrer_user_token: UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "referrer_username: String",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "referrer_display_name: String",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"name": "maybe_referral_code_token: UserReferralCodeToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"name": "maybe_referral_url",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"name": "maybe_landing_url",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"name": "created_at",
|
||||
"type_info": {
|
||||
"type": "Datetime",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "b2049fa1c9f76c73a9a22144de716b47dccdd35caeefb3721e75ec9aaf4614f0"
|
||||
}
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n ur.id as `id: u64`,\n ur.invited_user_token as `invited_user_token: UserToken`,\n invited.username as `invited_username: String`,\n invited.display_name as `invited_display_name: String`,\n invited.email_address as `invited_email_address: String`,\n ur.referrer_user_token as `referrer_user_token: UserToken`,\n referrer.username as `referrer_username: String`,\n referrer.display_name as `referrer_display_name: String`,\n ur.maybe_referral_code_token as `maybe_referral_code_token: UserReferralCodeToken`,\n ur.maybe_referral_url,\n ur.maybe_landing_url,\n ur.created_at\nFROM user_referrals ur\nJOIN users invited ON invited.token = ur.invited_user_token\nJOIN users referrer ON referrer.token = ur.referrer_user_token\nWHERE referrer.username = ?\nORDER BY ur.id DESC\nLIMIT ?\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "id: u64",
|
||||
"type_info": {
|
||||
"type": "LongLong",
|
||||
"flags": "NOT_NULL | PRIMARY_KEY | UNSIGNED | AUTO_INCREMENT",
|
||||
"char_set": 63,
|
||||
"max_size": 20
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "invited_user_token: UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "invited_username: String",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "invited_display_name: String",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "invited_email_address: String",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "referrer_user_token: UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "referrer_username: String",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "referrer_display_name: String",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"name": "maybe_referral_code_token: UserReferralCodeToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"name": "maybe_referral_url",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"name": "maybe_landing_url",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"name": "created_at",
|
||||
"type_info": {
|
||||
"type": "Datetime",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "e73dfa3af6a1a8f510f084435da86571e096f3d7e597fb01d6397d380b135341"
|
||||
}
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
{
|
||||
"db_name": "MySQL",
|
||||
"query": "\nSELECT\n ur.id as `id: u64`,\n ur.invited_user_token as `invited_user_token: UserToken`,\n invited.username as `invited_username: String`,\n invited.display_name as `invited_display_name: String`,\n invited.email_address as `invited_email_address: String`,\n ur.referrer_user_token as `referrer_user_token: UserToken`,\n referrer.username as `referrer_username: String`,\n referrer.display_name as `referrer_display_name: String`,\n ur.maybe_referral_code_token as `maybe_referral_code_token: UserReferralCodeToken`,\n ur.maybe_referral_url,\n ur.maybe_landing_url,\n ur.created_at\nFROM user_referrals ur\nJOIN users invited ON invited.token = ur.invited_user_token\nJOIN users referrer ON referrer.token = ur.referrer_user_token\nWHERE referrer.username = ?\n AND ur.id < ?\nORDER BY ur.id DESC\nLIMIT ?\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "id: u64",
|
||||
"type_info": {
|
||||
"type": "LongLong",
|
||||
"flags": "NOT_NULL | PRIMARY_KEY | UNSIGNED | AUTO_INCREMENT",
|
||||
"char_set": 63,
|
||||
"max_size": 20
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "invited_user_token: UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "invited_username: String",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "invited_display_name: String",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "invited_email_address: String",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "referrer_user_token: UserToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "referrer_username: String",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | UNIQUE_KEY | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "referrer_display_name: String",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "NOT_NULL | BINARY | NO_DEFAULT_VALUE",
|
||||
"char_set": 224,
|
||||
"max_size": 80
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 8,
|
||||
"name": "maybe_referral_code_token: UserReferralCodeToken",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 9,
|
||||
"name": "maybe_referral_url",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 10,
|
||||
"name": "maybe_landing_url",
|
||||
"type_info": {
|
||||
"type": "VarString",
|
||||
"flags": "BINARY",
|
||||
"char_set": 224,
|
||||
"max_size": 1020
|
||||
}
|
||||
},
|
||||
{
|
||||
"ordinal": 11,
|
||||
"name": "created_at",
|
||||
"type_info": {
|
||||
"type": "Datetime",
|
||||
"flags": "NOT_NULL | MULTIPLE_KEY | BINARY",
|
||||
"char_set": 63,
|
||||
"max_size": 19
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 3
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "fb021a5fe7a6c0e284968d917f9d612953629d20a06efccc3fce3d930a7fe266"
|
||||
}
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
use chrono::{DateTime, NaiveDateTime, Utc};
|
||||
use sqlx::MySqlPool;
|
||||
use tokens::tokens::user_referral_codes::UserReferralCodeToken;
|
||||
use tokens::tokens::users::UserToken;
|
||||
|
||||
pub struct UserReferralListItem {
|
||||
pub id: u64,
|
||||
pub invited_user_token: UserToken,
|
||||
pub invited_username: String,
|
||||
pub invited_display_name: String,
|
||||
pub invited_email_address: String,
|
||||
pub referrer_user_token: UserToken,
|
||||
pub referrer_username: String,
|
||||
pub referrer_display_name: String,
|
||||
pub maybe_referral_code_token: Option<UserReferralCodeToken>,
|
||||
pub maybe_referral_url: Option<String>,
|
||||
pub maybe_landing_url: Option<String>,
|
||||
pub created_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
struct RawRow {
|
||||
id: u64,
|
||||
invited_user_token: UserToken,
|
||||
invited_username: String,
|
||||
invited_display_name: String,
|
||||
invited_email_address: String,
|
||||
referrer_user_token: UserToken,
|
||||
referrer_username: String,
|
||||
referrer_display_name: String,
|
||||
maybe_referral_code_token: Option<UserReferralCodeToken>,
|
||||
maybe_referral_url: Option<String>,
|
||||
maybe_landing_url: Option<String>,
|
||||
created_at: NaiveDateTime,
|
||||
}
|
||||
|
||||
pub struct ListGlobalUserReferralsArgs<'a> {
|
||||
pub maybe_cursor_id: Option<u64>,
|
||||
pub limit: u32,
|
||||
pub mysql_pool: &'a MySqlPool,
|
||||
}
|
||||
|
||||
pub async fn list_global_user_referrals(
|
||||
args: ListGlobalUserReferralsArgs<'_>,
|
||||
) -> Result<Vec<UserReferralListItem>, sqlx::Error> {
|
||||
let limit = args.limit as i64;
|
||||
|
||||
let rows = match args.maybe_cursor_id {
|
||||
Some(cursor_id) => {
|
||||
sqlx::query_as!(
|
||||
RawRow,
|
||||
r#"
|
||||
SELECT
|
||||
ur.id as `id: u64`,
|
||||
ur.invited_user_token as `invited_user_token: UserToken`,
|
||||
invited.username as `invited_username: String`,
|
||||
invited.display_name as `invited_display_name: String`,
|
||||
invited.email_address as `invited_email_address: String`,
|
||||
ur.referrer_user_token as `referrer_user_token: UserToken`,
|
||||
referrer.username as `referrer_username: String`,
|
||||
referrer.display_name as `referrer_display_name: String`,
|
||||
ur.maybe_referral_code_token as `maybe_referral_code_token: UserReferralCodeToken`,
|
||||
ur.maybe_referral_url,
|
||||
ur.maybe_landing_url,
|
||||
ur.created_at
|
||||
FROM user_referrals ur
|
||||
JOIN users invited ON invited.token = ur.invited_user_token
|
||||
JOIN users referrer ON referrer.token = ur.referrer_user_token
|
||||
WHERE ur.id < ?
|
||||
ORDER BY ur.id DESC
|
||||
LIMIT ?
|
||||
"#,
|
||||
cursor_id as u64,
|
||||
limit,
|
||||
)
|
||||
.fetch_all(args.mysql_pool)
|
||||
.await?
|
||||
}
|
||||
None => {
|
||||
sqlx::query_as!(
|
||||
RawRow,
|
||||
r#"
|
||||
SELECT
|
||||
ur.id as `id: u64`,
|
||||
ur.invited_user_token as `invited_user_token: UserToken`,
|
||||
invited.username as `invited_username: String`,
|
||||
invited.display_name as `invited_display_name: String`,
|
||||
invited.email_address as `invited_email_address: String`,
|
||||
ur.referrer_user_token as `referrer_user_token: UserToken`,
|
||||
referrer.username as `referrer_username: String`,
|
||||
referrer.display_name as `referrer_display_name: String`,
|
||||
ur.maybe_referral_code_token as `maybe_referral_code_token: UserReferralCodeToken`,
|
||||
ur.maybe_referral_url,
|
||||
ur.maybe_landing_url,
|
||||
ur.created_at
|
||||
FROM user_referrals ur
|
||||
JOIN users invited ON invited.token = ur.invited_user_token
|
||||
JOIN users referrer ON referrer.token = ur.referrer_user_token
|
||||
ORDER BY ur.id DESC
|
||||
LIMIT ?
|
||||
"#,
|
||||
limit,
|
||||
)
|
||||
.fetch_all(args.mysql_pool)
|
||||
.await?
|
||||
}
|
||||
};
|
||||
|
||||
Ok(rows.into_iter().map(|r| UserReferralListItem {
|
||||
id: r.id,
|
||||
invited_user_token: r.invited_user_token,
|
||||
invited_username: r.invited_username,
|
||||
invited_display_name: r.invited_display_name,
|
||||
invited_email_address: r.invited_email_address,
|
||||
referrer_user_token: r.referrer_user_token,
|
||||
referrer_username: r.referrer_username,
|
||||
referrer_display_name: r.referrer_display_name,
|
||||
maybe_referral_code_token: r.maybe_referral_code_token,
|
||||
maybe_referral_url: r.maybe_referral_url,
|
||||
maybe_landing_url: r.maybe_landing_url,
|
||||
created_at: r.created_at.and_utc(),
|
||||
}).collect())
|
||||
}
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
use chrono::{DateTime, NaiveDateTime, Utc};
|
||||
use sqlx::MySqlPool;
|
||||
use tokens::tokens::user_referral_codes::UserReferralCodeToken;
|
||||
use tokens::tokens::users::UserToken;
|
||||
|
||||
use crate::queries::user_referrals::list_global_user_referrals::UserReferralListItem;
|
||||
|
||||
struct RawRow {
|
||||
id: u64,
|
||||
invited_user_token: UserToken,
|
||||
invited_username: String,
|
||||
invited_display_name: String,
|
||||
invited_email_address: String,
|
||||
referrer_user_token: UserToken,
|
||||
referrer_username: String,
|
||||
referrer_display_name: String,
|
||||
maybe_referral_code_token: Option<UserReferralCodeToken>,
|
||||
maybe_referral_url: Option<String>,
|
||||
maybe_landing_url: Option<String>,
|
||||
created_at: NaiveDateTime,
|
||||
}
|
||||
|
||||
pub struct ListUserReferralsForUserArgs<'a> {
|
||||
pub referrer_username: &'a str,
|
||||
pub maybe_cursor_id: Option<u64>,
|
||||
pub limit: u32,
|
||||
pub mysql_pool: &'a MySqlPool,
|
||||
}
|
||||
|
||||
pub async fn list_user_referrals_for_user(
|
||||
args: ListUserReferralsForUserArgs<'_>,
|
||||
) -> Result<Vec<UserReferralListItem>, sqlx::Error> {
|
||||
let limit = args.limit as i64;
|
||||
|
||||
let rows = match args.maybe_cursor_id {
|
||||
Some(cursor_id) => {
|
||||
sqlx::query_as!(
|
||||
RawRow,
|
||||
r#"
|
||||
SELECT
|
||||
ur.id as `id: u64`,
|
||||
ur.invited_user_token as `invited_user_token: UserToken`,
|
||||
invited.username as `invited_username: String`,
|
||||
invited.display_name as `invited_display_name: String`,
|
||||
invited.email_address as `invited_email_address: String`,
|
||||
ur.referrer_user_token as `referrer_user_token: UserToken`,
|
||||
referrer.username as `referrer_username: String`,
|
||||
referrer.display_name as `referrer_display_name: String`,
|
||||
ur.maybe_referral_code_token as `maybe_referral_code_token: UserReferralCodeToken`,
|
||||
ur.maybe_referral_url,
|
||||
ur.maybe_landing_url,
|
||||
ur.created_at
|
||||
FROM user_referrals ur
|
||||
JOIN users invited ON invited.token = ur.invited_user_token
|
||||
JOIN users referrer ON referrer.token = ur.referrer_user_token
|
||||
WHERE referrer.username = ?
|
||||
AND ur.id < ?
|
||||
ORDER BY ur.id DESC
|
||||
LIMIT ?
|
||||
"#,
|
||||
args.referrer_username,
|
||||
cursor_id as u64,
|
||||
limit,
|
||||
)
|
||||
.fetch_all(args.mysql_pool)
|
||||
.await?
|
||||
}
|
||||
None => {
|
||||
sqlx::query_as!(
|
||||
RawRow,
|
||||
r#"
|
||||
SELECT
|
||||
ur.id as `id: u64`,
|
||||
ur.invited_user_token as `invited_user_token: UserToken`,
|
||||
invited.username as `invited_username: String`,
|
||||
invited.display_name as `invited_display_name: String`,
|
||||
invited.email_address as `invited_email_address: String`,
|
||||
ur.referrer_user_token as `referrer_user_token: UserToken`,
|
||||
referrer.username as `referrer_username: String`,
|
||||
referrer.display_name as `referrer_display_name: String`,
|
||||
ur.maybe_referral_code_token as `maybe_referral_code_token: UserReferralCodeToken`,
|
||||
ur.maybe_referral_url,
|
||||
ur.maybe_landing_url,
|
||||
ur.created_at
|
||||
FROM user_referrals ur
|
||||
JOIN users invited ON invited.token = ur.invited_user_token
|
||||
JOIN users referrer ON referrer.token = ur.referrer_user_token
|
||||
WHERE referrer.username = ?
|
||||
ORDER BY ur.id DESC
|
||||
LIMIT ?
|
||||
"#,
|
||||
args.referrer_username,
|
||||
limit,
|
||||
)
|
||||
.fetch_all(args.mysql_pool)
|
||||
.await?
|
||||
}
|
||||
};
|
||||
|
||||
Ok(rows.into_iter().map(|r| UserReferralListItem {
|
||||
id: r.id,
|
||||
invited_user_token: r.invited_user_token,
|
||||
invited_username: r.invited_username,
|
||||
invited_display_name: r.invited_display_name,
|
||||
invited_email_address: r.invited_email_address,
|
||||
referrer_user_token: r.referrer_user_token,
|
||||
referrer_username: r.referrer_username,
|
||||
referrer_display_name: r.referrer_display_name,
|
||||
maybe_referral_code_token: r.maybe_referral_code_token,
|
||||
maybe_referral_url: r.maybe_referral_url,
|
||||
maybe_landing_url: r.maybe_landing_url,
|
||||
created_at: r.created_at.and_utc(),
|
||||
}).collect())
|
||||
}
|
||||
@@ -1 +1,3 @@
|
||||
pub mod insert_user_referral;
|
||||
pub mod list_global_user_referrals;
|
||||
pub mod list_user_referrals_for_user;
|
||||
@@ -7,6 +7,7 @@ pub mod staff_audit_logs;
|
||||
pub mod user;
|
||||
pub mod user_bans;
|
||||
pub mod user_feature_flags;
|
||||
pub mod user_referrals;
|
||||
pub mod user_sessions;
|
||||
pub mod wallet_ledger_entries;
|
||||
pub mod wallets;
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
pub mod moderator_list_global_user_referrals_handler;
|
||||
pub mod moderator_list_user_referrals_for_user_handler;
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use actix_web::web::{Json, Query};
|
||||
use actix_web::{web, HttpRequest};
|
||||
use chrono::{DateTime, Utc};
|
||||
use log::warn;
|
||||
use utoipa::{IntoParams, ToSchema};
|
||||
|
||||
use mysql_queries::queries::user_referrals::list_global_user_referrals::{
|
||||
list_global_user_referrals, ListGlobalUserReferralsArgs,
|
||||
};
|
||||
use tokens::tokens::user_referral_codes::UserReferralCodeToken;
|
||||
use tokens::tokens::users::UserToken;
|
||||
|
||||
use crate::http_server::common_responses::advanced_common_web_error::AdvancedCommonWebError;
|
||||
use crate::http_server::web_utils::user_session::require_moderator::{
|
||||
require_moderator, UseDatabase,
|
||||
};
|
||||
use crate::state::server_state::ServerState;
|
||||
|
||||
const CURSOR_NAME: &str = "modusrref";
|
||||
const DEFAULT_LIMIT: u32 = 100;
|
||||
const MAX_LIMIT: u32 = 1000;
|
||||
|
||||
// --- Request ---
|
||||
|
||||
#[derive(Deserialize, ToSchema, IntoParams)]
|
||||
pub struct ListGlobalUserReferralsQueryParams {
|
||||
pub cursor: Option<String>,
|
||||
pub limit: Option<u32>,
|
||||
}
|
||||
|
||||
// --- Response ---
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
pub struct ListGlobalUserReferralsSuccessResponse {
|
||||
pub success: bool,
|
||||
pub referrals: Vec<UserReferralResponse>,
|
||||
pub maybe_cursor: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
pub struct UserReferralResponse {
|
||||
pub invited_user: InvitedUserDetails,
|
||||
pub referrer_user: ReferrerUserDetails,
|
||||
pub maybe_referral_code_token: Option<UserReferralCodeToken>,
|
||||
pub maybe_referral_url: Option<String>,
|
||||
pub maybe_landing_url: Option<String>,
|
||||
pub created_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
pub struct InvitedUserDetails {
|
||||
pub token: UserToken,
|
||||
pub username: String,
|
||||
pub display_name: String,
|
||||
pub email_address: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
pub struct ReferrerUserDetails {
|
||||
pub token: UserToken,
|
||||
pub username: String,
|
||||
pub display_name: String,
|
||||
}
|
||||
|
||||
// --- Handler ---
|
||||
|
||||
/// List all user referrals globally. Moderators only.
|
||||
#[utoipa::path(
|
||||
get,
|
||||
tag = "Moderation",
|
||||
path = "/v1/moderation/user_referrals/list",
|
||||
params(
|
||||
ListGlobalUserReferralsQueryParams,
|
||||
),
|
||||
responses(
|
||||
(status = 200, description = "Success", body = ListGlobalUserReferralsSuccessResponse),
|
||||
(status = 401, description = "Unauthorized"),
|
||||
(status = 500, description = "Server error"),
|
||||
),
|
||||
)]
|
||||
pub async fn moderator_list_global_user_referrals_handler(
|
||||
http_request: HttpRequest,
|
||||
query: Query<ListGlobalUserReferralsQueryParams>,
|
||||
server_state: web::Data<Arc<ServerState>>,
|
||||
) -> Result<Json<ListGlobalUserReferralsSuccessResponse>, AdvancedCommonWebError> {
|
||||
|
||||
let _user_session = require_moderator(
|
||||
&http_request,
|
||||
&server_state,
|
||||
UseDatabase::GrabNewConnection,
|
||||
).await.map_err(|err| {
|
||||
warn!("Moderator check failed: {:?}", err);
|
||||
AdvancedCommonWebError::NotAuthorized
|
||||
})?;
|
||||
|
||||
let limit = query.limit
|
||||
.unwrap_or(DEFAULT_LIMIT)
|
||||
.min(MAX_LIMIT);
|
||||
|
||||
let maybe_cursor_id = match &query.cursor {
|
||||
None => None,
|
||||
Some(cursor_str) => {
|
||||
let decoded = server_state.opaque_cursors
|
||||
.decode_cursor_expecting_name(CURSOR_NAME, cursor_str)
|
||||
.map_err(|err| {
|
||||
warn!("Failed to decode cursor: {:?}", err);
|
||||
AdvancedCommonWebError::BadInputWithSimpleMessage(
|
||||
"Invalid cursor".to_string())
|
||||
})?;
|
||||
decoded.last_id
|
||||
}
|
||||
};
|
||||
|
||||
let records = list_global_user_referrals(
|
||||
ListGlobalUserReferralsArgs {
|
||||
maybe_cursor_id,
|
||||
limit,
|
||||
mysql_pool: &server_state.mysql_pool,
|
||||
},
|
||||
).await.map_err(|err| {
|
||||
warn!("Failed to list user referrals: {:?}", err);
|
||||
AdvancedCommonWebError::from_error(err)
|
||||
})?;
|
||||
|
||||
let maybe_cursor = records.last().map(|last| {
|
||||
server_state.opaque_cursors
|
||||
.encode_last_id_cursor(CURSOR_NAME, last.id)
|
||||
}).transpose().map_err(|err| {
|
||||
warn!("Failed to encode cursor: {:?}", err);
|
||||
AdvancedCommonWebError::server_error_with_message("Failed to encode cursor")
|
||||
})?;
|
||||
|
||||
let referrals = records.into_iter().map(|r| {
|
||||
UserReferralResponse {
|
||||
invited_user: InvitedUserDetails {
|
||||
token: r.invited_user_token,
|
||||
username: r.invited_username,
|
||||
display_name: r.invited_display_name,
|
||||
email_address: r.invited_email_address,
|
||||
},
|
||||
referrer_user: ReferrerUserDetails {
|
||||
token: r.referrer_user_token,
|
||||
username: r.referrer_username,
|
||||
display_name: r.referrer_display_name,
|
||||
},
|
||||
maybe_referral_code_token: r.maybe_referral_code_token,
|
||||
maybe_referral_url: r.maybe_referral_url,
|
||||
maybe_landing_url: r.maybe_landing_url,
|
||||
created_at: r.created_at,
|
||||
}
|
||||
}).collect();
|
||||
|
||||
Ok(Json(ListGlobalUserReferralsSuccessResponse {
|
||||
success: true,
|
||||
referrals,
|
||||
maybe_cursor,
|
||||
}))
|
||||
}
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use actix_web::web::{Json, Path, Query};
|
||||
use actix_web::{web, HttpRequest};
|
||||
use log::warn;
|
||||
use utoipa::{IntoParams, ToSchema};
|
||||
|
||||
use mysql_queries::queries::user_referrals::list_user_referrals_for_user::{
|
||||
list_user_referrals_for_user, ListUserReferralsForUserArgs,
|
||||
};
|
||||
|
||||
use crate::http_server::common_responses::advanced_common_web_error::AdvancedCommonWebError;
|
||||
use crate::http_server::endpoints::moderation::user_referrals::moderator_list_global_user_referrals_handler::{
|
||||
InvitedUserDetails, ReferrerUserDetails, UserReferralResponse,
|
||||
};
|
||||
use crate::http_server::web_utils::user_session::require_moderator::{
|
||||
require_moderator, UseDatabase,
|
||||
};
|
||||
use crate::state::server_state::ServerState;
|
||||
|
||||
const CURSOR_NAME: &str = "modusrrefu";
|
||||
const DEFAULT_LIMIT: u32 = 100;
|
||||
const MAX_LIMIT: u32 = 1000;
|
||||
|
||||
// --- Request ---
|
||||
|
||||
#[derive(Deserialize, ToSchema, IntoParams)]
|
||||
pub struct ListUserReferralsForUserQueryParams {
|
||||
pub cursor: Option<String>,
|
||||
pub limit: Option<u32>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, ToSchema)]
|
||||
pub struct ListUserReferralsForUserPathInfo {
|
||||
pub username: String,
|
||||
}
|
||||
|
||||
// --- Response ---
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
pub struct ListUserReferralsForUserSuccessResponse {
|
||||
pub success: bool,
|
||||
pub referrals: Vec<UserReferralResponse>,
|
||||
pub maybe_cursor: Option<String>,
|
||||
}
|
||||
|
||||
// --- Handler ---
|
||||
|
||||
/// List user referrals for a specific referrer user. Moderators only.
|
||||
#[utoipa::path(
|
||||
get,
|
||||
tag = "Moderation",
|
||||
path = "/v1/moderation/user_referrals/user/{username}/list",
|
||||
params(
|
||||
("username" = String, description = "The referrer's username"),
|
||||
ListUserReferralsForUserQueryParams,
|
||||
),
|
||||
responses(
|
||||
(status = 200, description = "Success", body = ListUserReferralsForUserSuccessResponse),
|
||||
(status = 401, description = "Unauthorized"),
|
||||
(status = 500, description = "Server error"),
|
||||
),
|
||||
)]
|
||||
pub async fn moderator_list_user_referrals_for_user_handler(
|
||||
http_request: HttpRequest,
|
||||
path: Path<ListUserReferralsForUserPathInfo>,
|
||||
query: Query<ListUserReferralsForUserQueryParams>,
|
||||
server_state: web::Data<Arc<ServerState>>,
|
||||
) -> Result<Json<ListUserReferralsForUserSuccessResponse>, AdvancedCommonWebError> {
|
||||
|
||||
let _user_session = require_moderator(
|
||||
&http_request,
|
||||
&server_state,
|
||||
UseDatabase::GrabNewConnection,
|
||||
).await.map_err(|err| {
|
||||
warn!("Moderator check failed: {:?}", err);
|
||||
AdvancedCommonWebError::NotAuthorized
|
||||
})?;
|
||||
|
||||
let limit = query.limit
|
||||
.unwrap_or(DEFAULT_LIMIT)
|
||||
.min(MAX_LIMIT);
|
||||
|
||||
let maybe_cursor_id = match &query.cursor {
|
||||
None => None,
|
||||
Some(cursor_str) => {
|
||||
let decoded = server_state.opaque_cursors
|
||||
.decode_cursor_expecting_name(CURSOR_NAME, cursor_str)
|
||||
.map_err(|err| {
|
||||
warn!("Failed to decode cursor: {:?}", err);
|
||||
AdvancedCommonWebError::BadInputWithSimpleMessage(
|
||||
"Invalid cursor".to_string())
|
||||
})?;
|
||||
decoded.last_id
|
||||
}
|
||||
};
|
||||
|
||||
let referrer_username = path.username.trim().to_lowercase();
|
||||
|
||||
let records = list_user_referrals_for_user(
|
||||
ListUserReferralsForUserArgs {
|
||||
referrer_username: &referrer_username,
|
||||
maybe_cursor_id,
|
||||
limit,
|
||||
mysql_pool: &server_state.mysql_pool,
|
||||
},
|
||||
).await.map_err(|err| {
|
||||
warn!("Failed to list user referrals for user: {:?}", err);
|
||||
AdvancedCommonWebError::from_error(err)
|
||||
})?;
|
||||
|
||||
let maybe_cursor = records.last().map(|last| {
|
||||
server_state.opaque_cursors
|
||||
.encode_last_id_cursor(CURSOR_NAME, last.id)
|
||||
}).transpose().map_err(|err| {
|
||||
warn!("Failed to encode cursor: {:?}", err);
|
||||
AdvancedCommonWebError::server_error_with_message("Failed to encode cursor")
|
||||
})?;
|
||||
|
||||
let referrals = records.into_iter().map(|r| {
|
||||
UserReferralResponse {
|
||||
invited_user: InvitedUserDetails {
|
||||
token: r.invited_user_token,
|
||||
username: r.invited_username,
|
||||
display_name: r.invited_display_name,
|
||||
email_address: r.invited_email_address,
|
||||
},
|
||||
referrer_user: ReferrerUserDetails {
|
||||
token: r.referrer_user_token,
|
||||
username: r.referrer_username,
|
||||
display_name: r.referrer_display_name,
|
||||
},
|
||||
maybe_referral_code_token: r.maybe_referral_code_token,
|
||||
maybe_referral_url: r.maybe_referral_url,
|
||||
maybe_landing_url: r.maybe_landing_url,
|
||||
created_at: r.created_at,
|
||||
}
|
||||
}).collect();
|
||||
|
||||
Ok(Json(ListUserReferralsForUserSuccessResponse {
|
||||
success: true,
|
||||
referrals,
|
||||
maybe_cursor,
|
||||
}))
|
||||
}
|
||||
+12
@@ -42,6 +42,8 @@ use crate::http_server::endpoints::moderation::user_feature_flags::moderator_edi
|
||||
use crate::http_server::endpoints::moderation::user_feature_flags::moderator_list_all_available_user_feature_flags_handler::moderator_list_all_available_user_feature_flags_handler;
|
||||
use crate::http_server::endpoints::moderation::user_feature_flags::moderator_list_user_feature_flags_handler::moderator_list_user_feature_flags_handler;
|
||||
use crate::http_server::endpoints::moderation::user_sessions::moderator_list_user_session_impersonation_requests_for_user_handler::moderator_list_user_session_impersonation_requests_for_user_handler;
|
||||
use crate::http_server::endpoints::moderation::user_referrals::moderator_list_global_user_referrals_handler::moderator_list_global_user_referrals_handler;
|
||||
use crate::http_server::endpoints::moderation::user_referrals::moderator_list_user_referrals_for_user_handler::moderator_list_user_referrals_for_user_handler;
|
||||
use crate::http_server::endpoints::moderation::user_sessions::moderator_list_user_session_impersonation_requests_handler::moderator_list_user_session_impersonation_requests_handler;
|
||||
use crate::http_server::endpoints::moderation::user_sessions::moderator_user_session_impersonation_request_handler::moderator_user_session_impersonation_request_handler;
|
||||
|
||||
@@ -132,6 +134,16 @@ pub fn add_moderator_routes<T, B> (app: App<T>) -> App<T>
|
||||
.route(web::head().to(|| HttpResponse::Ok()))
|
||||
)
|
||||
)
|
||||
.service(web::scope("/user_referrals")
|
||||
.service(web::resource("/list")
|
||||
.route(web::get().to(moderator_list_global_user_referrals_handler))
|
||||
.route(web::head().to(|| HttpResponse::Ok()))
|
||||
)
|
||||
.service(web::resource("/user/{username}/list")
|
||||
.route(web::get().to(moderator_list_user_referrals_for_user_handler))
|
||||
.route(web::head().to(|| HttpResponse::Ok()))
|
||||
)
|
||||
)
|
||||
.service(web::scope("/user_sessions")
|
||||
.service(web::resource("/impersonate")
|
||||
.route(web::post().to(moderator_user_session_impersonation_request_handler))
|
||||
|
||||
Reference in new issue
Block a user