Files
OpenFUT-Core/src/routes/upgrades.rs
T
2026-08-07 12:03:21 -07:00

125 lines
3.7 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
use crate::extractors::GameId;
use axum::{
extract::{Path, State},
Json,
};
use serde::Deserialize;
use serde_json::{json, Value};
use crate::{
app::AppState,
error::AppResult,
services::{club as club_svc, profile as profile_svc, upgrades as upgrade_svc},
};
/// GET /chemistry-styles — list all available styles with their stat boosts.
pub async fn get_chemistry_styles(State(state): State<AppState>) -> AppResult<Json<Value>> {
Ok(Json(json!({
"chemistry_styles": *state.chem_styles,
"total": state.chem_styles.len(),
})))
}
#[derive(Deserialize)]
pub struct ApplyChemStyleRequest {
pub style_id: String,
}
/// POST /collection/:owned_card_id/chemistry-style
pub async fn post_apply_chemistry_style(
State(state): State<AppState>,
game: GameId,
Path(owned_card_id): Path<String>,
Json(req): Json<ApplyChemStyleRequest>,
) -> AppResult<Json<Value>> {
let profile = profile_svc::get_active_profile(&state.pool, game.as_str()).await?;
let club = club_svc::get_club_by_profile(&state.pool, &profile.id).await?;
let updated = upgrade_svc::apply_chemistry_style(
&state.pool,
&club.id,
&owned_card_id,
&req.style_id,
&state.chem_styles,
)
.await?;
let style = state
.chem_styles
.iter()
.find(|s| s.id == updated.chemistry_style);
Ok(Json(json!({
"owned_card_id": updated.id,
"card_id": updated.card_id,
"chemistry_style": updated.chemistry_style,
"style_details": style,
})))
}
#[derive(Deserialize)]
pub struct ChangePositionRequest {
pub position: String,
}
/// POST /collection/:owned_card_id/position — costs 500 coins.
pub async fn post_change_position(
State(state): State<AppState>,
game: GameId,
Path(owned_card_id): Path<String>,
Json(req): Json<ChangePositionRequest>,
) -> AppResult<Json<Value>> {
let profile = profile_svc::get_active_profile(&state.pool, game.as_str()).await?;
let club = club_svc::get_club_by_profile(&state.pool, &profile.id).await?;
let updated = upgrade_svc::change_position(
&state.pool,
&club.id,
&owned_card_id,
&req.position,
)
.await?;
let card_def = state.card_db.get(&updated.card_id);
Ok(Json(json!({
"owned_card_id": updated.id,
"card_id": updated.card_id,
"original_position": card_def.map(|c| &c.position),
"position_override": updated.position_override,
"cost_coins": upgrade_svc::POSITION_CHANGE_COST,
})))
}
#[derive(Deserialize)]
pub struct ApplyTrainingRequest {
/// OVR points to add. Must be 13. Total capped at +3.
pub boost: i64,
}
/// POST /collection/:owned_card_id/training — applies a training boost (up to +3 OVR total).
pub async fn post_apply_training(
State(state): State<AppState>,
game: GameId,
Path(owned_card_id): Path<String>,
Json(req): Json<ApplyTrainingRequest>,
) -> AppResult<Json<Value>> {
let profile = profile_svc::get_active_profile(&state.pool, game.as_str()).await?;
let club = club_svc::get_club_by_profile(&state.pool, &profile.id).await?;
let updated =
upgrade_svc::apply_training(&state.pool, &club.id, &owned_card_id, req.boost).await?;
let card_def = state.card_db.get(&updated.card_id);
let base_overall = card_def.map(|c| c.overall as i64).unwrap_or(0);
Ok(Json(json!({
"owned_card_id": updated.id,
"card_id": updated.card_id,
"base_overall": base_overall,
"training_bonus": updated.training_bonus,
"effective_overall": base_overall + updated.training_bonus,
"max_bonus": upgrade_svc::MAX_TRAINING_BONUS,
})))
}