Files
imphnen-backend-service/imphnen-gacha/src/v1/gacha_credits/gacha_credits_service.rs
T

97 lines
4.1 KiB
Rust

use crate::AppState;
use imphnen_entities::ResponseSuccessDto;
use imphnen_utils::{errors::AppError, error_response};
use imphnen_utils::{common_response, success_response, validate_request};
use crate::v1::gacha_credits::gacha_credits_dto::{GachaCreditRequestDto, GachaCreditResponseDto};
use crate::v1::gacha_credits::gacha_credits_repository::GachaCreditRepository;
use axum::http::StatusCode;
use axum::response::Response;
use imphnen_iam::UsersRepository;
use imphnen_utils::extract_email;
pub struct GachaCreditService;
impl GachaCreditService {
pub async fn get_user_credits(headers: &axum::http::HeaderMap, state: &AppState) -> Response {
let repo = GachaCreditRepository::new(state);
let repo_user = UsersRepository::new(state);
let Some(email) = extract_email(headers) else {
return error_response(AppError::AuthenticationError("Unauthorized".into()));
};
let Ok(user) = repo_user.query_user_by_email(email.to_string()).await else {
return error_response(AppError::NotFoundError("User not found".into()));
};
match repo.query_by_user_id(user.id.id.to_raw()).await {
Ok(Some(credit)) => {
let response_dto = GachaCreditResponseDto::from(&credit);
success_response(ResponseSuccessDto { data: response_dto })
}
Ok(None) => {
// Return empty credits if no record exists
let response_dto = GachaCreditResponseDto {
id: "".to_string(),
user_id: user.id.id.to_raw(),
available_rolls: 0,
is_deleted: false,
created_at: None,
updated_at: None,
};
success_response(ResponseSuccessDto { data: response_dto })
}
Err(e) => error_response(AppError::InternalServerError(e.to_string())),
}
}
pub async fn add_user_credits(
headers: &axum::http::HeaderMap,
state: &AppState,
payload: GachaCreditRequestDto,
) -> Response {
if let Err((status, message)) = validate_request(&payload) {
return common_response(status, &message);
}
let repo = GachaCreditRepository::new(state);
let repo_user = UsersRepository::new(state);
let Some(email) = extract_email(headers) else {
return error_response(AppError::AuthenticationError("Unauthorized".into()));
};
let Ok(user) = repo_user.query_user_by_email(email.to_string()).await else {
return error_response(AppError::NotFoundError("User not found".into()));
};
// Ensure the user can only modify their own credits
if payload.user_id != user.id.id.to_raw() {
return error_response(AppError::AuthorizationError("You can only modify your own credits".into()));
}
let amount = payload.amount; // Extract amount before moving payload
match repo.query_add_credit(payload).await {
Ok(_) => common_response(
StatusCode::OK,
&format!("Added {} credits successfully", amount)
),
Err(e) => error_response(AppError::InternalServerError(e.to_string())),
}
}
pub async fn consume_user_credit(headers: &axum::http::HeaderMap, state: &AppState) -> Response {
let repo = GachaCreditRepository::new(state);
let repo_user = UsersRepository::new(state);
let Some(email) = extract_email(headers) else {
return error_response(AppError::AuthenticationError("Unauthorized".into()));
};
let Ok(user) = repo_user.query_user_by_email(email.to_string()).await else {
return error_response(AppError::NotFoundError("User not found".into()));
};
match repo.query_consume_credit(user.id.id.to_raw()).await {
Ok(_) => common_response(StatusCode::OK, "Consumed 1 credit successfully"),
Err(e) => error_response(AppError::BadRequestError(e.to_string())),
}
}
}