Fix pricing handler field name compatibility with admin UI

- Accept 'role' alias for 'role_key' and 'tracecoin_amount' alias for 'tracecoins_amount'
- Expose both field names in PackageDto so admin UI and user frontend both work

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Ashwin Kumar 2026-04-02 18:15:42 +02:00
parent 2312f5dfdc
commit 73629fa935

View file

@ -37,8 +37,12 @@ struct PackageDto {
id: Uuid,
name: String,
role_key: String,
// Also expose as 'role' for admin UI compatibility
role: String,
package_type: String,
tracecoins_amount: i32,
// Also expose as 'tracecoin_amount' for admin UI compatibility
tracecoin_amount: i32,
price_inr: i32,
description: Option<String>,
is_active: bool,
@ -47,9 +51,13 @@ struct PackageDto {
#[derive(Deserialize)]
struct CreatePackageBody {
name: String,
role_key: String,
// Accept either role_key or role
role_key: Option<String>,
role: Option<String>,
package_type: Option<String>,
// Accept either tracecoins_amount or tracecoin_amount
tracecoins_amount: Option<i32>,
tracecoin_amount: Option<i32>,
price_inr: i32,
description: Option<String>,
}
@ -58,8 +66,10 @@ struct CreatePackageBody {
struct PatchPackageBody {
name: Option<String>,
role_key: Option<String>,
role: Option<String>,
package_type: Option<String>,
tracecoins_amount: Option<i32>,
tracecoin_amount: Option<i32>,
price_inr: Option<i32>,
description: Option<String>,
is_active: Option<bool>,
@ -115,10 +125,12 @@ async fn public_list_packages(
.into_iter()
.map(|r| PackageDto {
id: r.id,
name: r.name,
role_key: r.role_key,
name: r.name.clone(),
role_key: r.role_key.clone(),
role: r.role_key.clone(),
package_type: r.package_type,
tracecoins_amount: r.tracecoins_amount,
tracecoin_amount: r.tracecoins_amount,
price_inr: r.price_inr,
description: r.description,
is_active: r.is_active,
@ -153,10 +165,12 @@ async fn list_packages(
.into_iter()
.map(|r| PackageDto {
id: r.id,
name: r.name,
role_key: r.role_key,
name: r.name.clone(),
role_key: r.role_key.clone(),
role: r.role_key.clone(),
package_type: r.package_type,
tracecoins_amount: r.tracecoins_amount,
tracecoin_amount: r.tracecoins_amount,
price_inr: r.price_inr,
description: r.description,
is_active: r.is_active,
@ -177,7 +191,10 @@ async fn create_package(
Json(body): Json<CreatePackageBody>,
) -> impl IntoResponse {
let package_type = body.package_type.unwrap_or_else(|| "TRACECOIN_BUNDLE".to_string());
let tracecoins_amount = body.tracecoins_amount.unwrap_or(0);
// Accept tracecoin_amount (admin UI) or tracecoins_amount
let tracecoins_amount = body.tracecoins_amount.or(body.tracecoin_amount).unwrap_or(0);
// Accept role (admin UI) or role_key
let role_key = body.role_key.or(body.role).unwrap_or_else(|| "ALL".to_string());
let row = sqlx::query!(
r#"
@ -186,7 +203,7 @@ async fn create_package(
RETURNING id, name, role_key, package_type, tracecoins_amount, price_inr, description, is_active
"#,
body.name,
body.role_key,
role_key,
package_type,
tracecoins_amount,
body.price_inr,
@ -199,10 +216,12 @@ async fn create_package(
Ok(r) => {
let dto = PackageDto {
id: r.id,
name: r.name,
role_key: r.role_key,
name: r.name.clone(),
role_key: r.role_key.clone(),
role: r.role_key.clone(),
package_type: r.package_type,
tracecoins_amount: r.tracecoins_amount,
tracecoin_amount: r.tracecoins_amount,
price_inr: r.price_inr,
description: r.description,
is_active: r.is_active,
@ -239,9 +258,9 @@ async fn update_package(
};
let name = body.name.unwrap_or(existing.name);
let role_key = body.role_key.unwrap_or(existing.role_key);
let role_key = body.role_key.or(body.role).unwrap_or(existing.role_key);
let package_type = body.package_type.unwrap_or(existing.package_type);
let tracecoins_amount = body.tracecoins_amount.unwrap_or(existing.tracecoins_amount);
let tracecoins_amount = body.tracecoins_amount.or(body.tracecoin_amount).unwrap_or(existing.tracecoins_amount);
let price_inr = body.price_inr.unwrap_or(existing.price_inr);
let description = body.description.or(existing.description);
let is_active = body.is_active.unwrap_or(existing.is_active);