This commit is contained in:
2026-05-10 22:20:54 +08:00
parent d6219f1a0c
commit 192accd796
92 changed files with 7045 additions and 1559 deletions

View File

@@ -13,6 +13,9 @@ use crate::domain::*;
use crate::errors::*;
use crate::{format_utc_micros, runtime_profile_recharge_product_by_id};
pub const PROFILE_USER_TAG_MAX_COUNT: usize = 8;
pub const PROFILE_USER_TAG_MAX_CHARS: usize = 16;
// 统一把共享必填字符串归一化映射到 runtime 各自的字段错误,避免输入构造函数重复 trim + 判空。
fn normalize_runtime_settings_user_id(
user_id: String,
@@ -425,6 +428,7 @@ pub fn build_runtime_profile_invite_code_admin_upsert_input(
admin_user_id: String,
invite_code: String,
metadata_json: String,
granted_user_tags: Vec<String>,
starts_at_micros: Option<i64>,
expires_at_micros: Option<i64>,
updated_at_micros: i64,
@@ -433,6 +437,7 @@ pub fn build_runtime_profile_invite_code_admin_upsert_input(
let invite_code =
normalize_invite_code(invite_code).ok_or(RuntimeProfileFieldError::MissingInviteCode)?;
let metadata_json = normalize_invite_code_metadata_json(metadata_json)?;
let granted_user_tags = normalize_profile_user_tags(granted_user_tags)?;
crate::commands::validate_runtime_profile_invite_code_validity_window(
starts_at_micros,
expires_at_micros,
@@ -442,6 +447,7 @@ pub fn build_runtime_profile_invite_code_admin_upsert_input(
admin_user_id,
invite_code,
metadata_json,
granted_user_tags,
starts_at_micros,
expires_at_micros,
updated_at_micros,
@@ -770,6 +776,27 @@ pub fn normalize_invite_code_metadata_json(
serde_json::to_string(&parsed).map_err(|_| RuntimeProfileFieldError::InvalidInviteCodeMetadata)
}
pub fn normalize_profile_user_tags(
values: Vec<String>,
) -> Result<Vec<String>, RuntimeProfileFieldError> {
let mut tags = Vec::new();
for value in values {
let Some(tag) = normalize_optional_string(Some(value)) else {
continue;
};
if tag.chars().count() > PROFILE_USER_TAG_MAX_CHARS {
return Err(RuntimeProfileFieldError::InvalidUserTag);
}
if !tags.iter().any(|existing| existing == &tag) {
tags.push(tag);
}
if tags.len() > PROFILE_USER_TAG_MAX_COUNT {
return Err(RuntimeProfileFieldError::InvalidUserTag);
}
}
Ok(tags)
}
pub fn validate_runtime_profile_invite_code_validity_window(
starts_at_micros: Option<i64>,
expires_at_micros: Option<i64>,