use axum::{ extract::{Path, State}, Json, }; use serde::Deserialize; use serde_json::{json, Value}; use crate::{ app::AppState, error::{AppError, AppResult}, services::{club as club_svc, objective as obj_svc, profile as profile_svc}, }; pub async fn get_objectives(State(state): State) -> AppResult> { let profile = profile_svc::get_active_profile(&state.pool).await?; let objectives = obj_svc::get_objectives_with_progress(&state.pool, &profile.id, &state.obj_defs).await?; Ok(Json(json!({ "objectives": objectives }))) } pub async fn get_objective( State(state): State, Path(objective_id): Path, ) -> AppResult> { let profile = profile_svc::get_active_profile(&state.pool).await?; let all = obj_svc::get_objectives_with_progress(&state.pool, &profile.id, &state.obj_defs).await?; let obj = all .into_iter() .find(|o| o.definition.id == objective_id) .ok_or_else(|| AppError::NotFound(format!("objective '{objective_id}' not found")))?; Ok(Json(json!({ "objective": obj }))) } pub async fn post_claim_objective_by_id( State(state): State, Path(objective_id): Path, ) -> AppResult> { let profile = profile_svc::get_active_profile(&state.pool).await?; let club = club_svc::get_club_by_profile(&state.pool, &profile.id).await?; let reward = obj_svc::claim_objective( &state.pool, &profile.id, &club.id, &state.obj_defs, &objective_id, ) .await?; Ok(Json(json!({ "claimed": true, "reward": reward }))) } #[derive(Deserialize)] pub struct ClaimRequest { pub objective_id: String, } pub async fn post_claim_objective( State(state): State, Json(req): Json, ) -> AppResult> { let profile = profile_svc::get_active_profile(&state.pool).await?; let club = club_svc::get_club_by_profile(&state.pool, &profile.id).await?; let reward = obj_svc::claim_objective( &state.pool, &profile.id, &club.id, &state.obj_defs, &req.objective_id, ) .await?; Ok(Json(json!({ "claimed": true, "reward": reward }))) }