Implement registration invite code flow and admin invite codes

This commit is contained in:
2026-04-30 20:49:38 +08:00
parent 2aef81e51d
commit 42aab671ed
32 changed files with 1241 additions and 179 deletions

View File

@@ -203,6 +203,19 @@ impl From<module_runtime::RuntimeProfileRedeemCodeAdminDisableInput>
}
}
impl From<module_runtime::RuntimeProfileInviteCodeAdminUpsertInput>
for RuntimeProfileInviteCodeAdminUpsertInput
{
fn from(input: module_runtime::RuntimeProfileInviteCodeAdminUpsertInput) -> Self {
Self {
admin_user_id: input.admin_user_id,
invite_code: input.invite_code,
metadata_json: input.metadata_json,
updated_at_micros: input.updated_at_micros,
}
}
}
impl From<module_runtime::RuntimeReferralInviteCenterGetInput>
for RuntimeReferralInviteCenterGetInput
{
@@ -886,6 +899,26 @@ pub(crate) fn map_runtime_profile_redeem_code_admin_procedure_result(
))
}
pub(crate) fn map_runtime_profile_invite_code_admin_procedure_result(
result: RuntimeProfileInviteCodeAdminProcedureResult,
) -> Result<RuntimeProfileInviteCodeRecord, SpacetimeClientError> {
if !result.ok {
return Err(SpacetimeClientError::Procedure(
result
.error_message
.unwrap_or_else(|| "SpacetimeDB procedure 返回未知错误".to_string()),
));
}
let snapshot = result.record.ok_or_else(|| {
SpacetimeClientError::Procedure("SpacetimeDB procedure 未返回 invite code 快照".to_string())
})?;
Ok(build_runtime_profile_invite_code_record(
map_runtime_profile_invite_code_snapshot(snapshot),
))
}
pub(crate) fn map_runtime_profile_play_stats_procedure_result(
result: RuntimeProfilePlayStatsProcedureResult,
) -> Result<RuntimeProfilePlayStatsRecord, SpacetimeClientError> {
@@ -1784,6 +1817,18 @@ pub(crate) fn map_runtime_profile_redeem_code_snapshot(
}
}
pub(crate) fn map_runtime_profile_invite_code_snapshot(
snapshot: RuntimeProfileInviteCodeSnapshot,
) -> module_runtime::RuntimeProfileInviteCodeSnapshot {
module_runtime::RuntimeProfileInviteCodeSnapshot {
user_id: snapshot.user_id,
invite_code: snapshot.invite_code,
metadata_json: snapshot.metadata_json,
created_at_micros: snapshot.created_at_micros,
updated_at_micros: snapshot.updated_at_micros,
}
}
pub(crate) fn map_runtime_profile_played_world_snapshot(
snapshot: RuntimeProfilePlayedWorldSnapshot,
) -> module_runtime::RuntimeProfilePlayedWorldSnapshot {
@@ -2427,6 +2472,13 @@ pub(crate) fn map_puzzle_run_snapshot(snapshot: DomainPuzzleRunSnapshot) -> Puzz
pub(crate) fn map_puzzle_runtime_level_snapshot(
snapshot: DomainPuzzleRuntimeLevelSnapshot,
) -> PuzzleRuntimeLevelRecord {
let started_at_ms = if snapshot.started_at_ms == 0 {
// 中文注释:旧 run_json 没有计时字段时只补一个可用开始时间,其余限时字段保持旧默认值。
current_unix_millis_for_legacy_puzzle_snapshot()
} else {
snapshot.started_at_ms
};
PuzzleRuntimeLevelRecord {
run_id: snapshot.run_id,
level_index: snapshot.level_index,
@@ -2438,7 +2490,7 @@ pub(crate) fn map_puzzle_runtime_level_snapshot(
cover_image_src: snapshot.cover_image_src,
board: map_puzzle_board_snapshot(snapshot.board),
status: snapshot.status.as_str().to_string(),
started_at_ms: snapshot.started_at_ms,
started_at_ms,
cleared_at_ms: snapshot.cleared_at_ms,
elapsed_ms: snapshot.elapsed_ms,
time_limit_ms: snapshot.time_limit_ms,
@@ -2456,6 +2508,13 @@ pub(crate) fn map_puzzle_runtime_level_snapshot(
}
}
fn current_unix_millis_for_legacy_puzzle_snapshot() -> u64 {
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.map(|duration| duration.as_millis().min(u128::from(u64::MAX)) as u64)
.unwrap_or(1)
}
pub(crate) fn map_puzzle_leaderboard_entry(
snapshot: module_puzzle::PuzzleLeaderboardEntry,
) -> PuzzleLeaderboardEntryRecord {