XP thresholds (500→1200→2000→…→11000→+2500/level) drive automatic level increases. add_xp_with_levelup() replaces bare add_xp() in match processing: for each level gained it grants level×500 coins and milestone packs (bronze@5, silver@10, gold@15, rare_gold@20, gold every 5 after). GET /profile now returns computed level (recalculated from XP so it stays consistent), xp_to_next_level, and xp_for_next_level so the dashboard can render a progress bar without a second call. POST /matches/result response gains level_ups array (empty when no level-up occurred) with new_level, coins_granted, pack_granted per event. Four new tests: profile level fields, level_for_xp boundary checks, level-up event in match result, milestone pack unit test. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+28
-3
@@ -1,9 +1,34 @@
|
||||
use crate::{
|
||||
app::AppState, error::AppResult, models::profile::Profile, services::profile as profile_svc,
|
||||
app::AppState,
|
||||
error::AppResult,
|
||||
models::profile::{level_for_xp, XP_THRESHOLDS},
|
||||
services::profile as profile_svc,
|
||||
};
|
||||
use axum::{extract::State, Json};
|
||||
use serde_json::{json, Value};
|
||||
|
||||
pub async fn get_profile(State(state): State<AppState>) -> AppResult<Json<Profile>> {
|
||||
pub async fn get_profile(State(state): State<AppState>) -> AppResult<Json<Value>> {
|
||||
let profile = profile_svc::get_active_profile(&state.pool).await?;
|
||||
Ok(Json(profile))
|
||||
let computed_level = level_for_xp(profile.xp);
|
||||
|
||||
let next_level = computed_level + 1;
|
||||
let xp_for_next = if next_level as usize <= XP_THRESHOLDS.len() {
|
||||
XP_THRESHOLDS[next_level as usize - 1]
|
||||
} else {
|
||||
let overflow_base = XP_THRESHOLDS.last().copied().unwrap_or(0);
|
||||
let levels_past = next_level - XP_THRESHOLDS.len() as i64;
|
||||
overflow_base + levels_past * 2500
|
||||
};
|
||||
let xp_to_next = (xp_for_next - profile.xp).max(0);
|
||||
|
||||
Ok(Json(json!({
|
||||
"id": profile.id,
|
||||
"username": profile.username,
|
||||
"level": computed_level,
|
||||
"xp": profile.xp,
|
||||
"xp_to_next_level": xp_to_next,
|
||||
"xp_for_next_level": xp_for_next,
|
||||
"created_at": profile.created_at,
|
||||
"updated_at": profile.updated_at,
|
||||
})))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user