feat: v0.3.0 — standardize codebase, centralize infra, merge QR into CMS
- Enforce axum best practices across all 13 workspace crates (max 200 LOC/file, no comments, no unwrap, clean architecture) - Fix domain→infrastructure dependency inversions in imphnen-iam and imphnen-dimentorin - Extract imphnen-storage (MinIO) and imphnen-email (Lettre) as standalone crates - Centralize all config in ENV struct: CDN_URL, CORS_ALLOWED_ORIGINS - Centralize SMTP through imphnen-email; remove dead HackathonConfig - Centralize database: QR crate now shares main DB pool (single DATABASE_URL) - Rename QR users table to qr_users to avoid collision with main users table - Merge imphnen-qr into imphnen-cms/src/qr (13 crates, down from 14) - Restructure imphnen-hackathon flat modules into clean architecture - Remove all stale env vars from .env.example (SurrealDB, QR_JWT, Hackathon infra) - Fix Dockerfile to include all current workspace crates - Bump all crate versions 0.2.0 → 0.3.0 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
2ae43b3bcc
commit
331a4a4e88
@@ -1,28 +1,28 @@
|
||||
use std::sync::Arc;
|
||||
use async_trait::async_trait;
|
||||
use uuid::Uuid;
|
||||
use imphnen_utils::AppError;
|
||||
use crate::gacha_claims::domain::{
|
||||
GachaClaimDetail, GachaClaimEntity, GachaClaimRepository, GachaClaimService,
|
||||
GachaClaimDetail, GachaClaimEntity, GachaClaimRepository, GachaClaimService,
|
||||
};
|
||||
use async_trait::async_trait;
|
||||
use imphnen_utils::AppError;
|
||||
use std::sync::Arc;
|
||||
use uuid::Uuid;
|
||||
|
||||
pub struct GachaClaimServiceImpl {
|
||||
repo: Arc<dyn GachaClaimRepository>,
|
||||
repo: Arc<dyn GachaClaimRepository>,
|
||||
}
|
||||
|
||||
impl GachaClaimServiceImpl {
|
||||
pub fn new(repo: Arc<dyn GachaClaimRepository>) -> Self {
|
||||
Self { repo }
|
||||
}
|
||||
pub fn new(repo: Arc<dyn GachaClaimRepository>) -> Self {
|
||||
Self { repo }
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl GachaClaimService for GachaClaimServiceImpl {
|
||||
async fn get_claim(&self, id: Uuid) -> Result<GachaClaimDetail, AppError> {
|
||||
self.repo.find_by_id(id).await
|
||||
}
|
||||
async fn get_claim(&self, id: Uuid) -> Result<GachaClaimDetail, AppError> {
|
||||
self.repo.find_by_id(id).await
|
||||
}
|
||||
|
||||
async fn create_claim(&self, entity: GachaClaimEntity) -> Result<(), AppError> {
|
||||
self.repo.create(entity).await
|
||||
}
|
||||
async fn create_claim(&self, entity: GachaClaimEntity) -> Result<(), AppError> {
|
||||
self.repo.create(entity).await
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,33 +1,32 @@
|
||||
use crate::gacha_items::domain::gacha_item::GachaItemEntity;
|
||||
use chrono::{DateTime, Utc};
|
||||
use imphnen_entities::UsersDetailQueryDto;
|
||||
use serde_json::Value;
|
||||
use uuid::Uuid;
|
||||
use imphnen_entities::UsersDetailQueryDto;
|
||||
use crate::gacha_items::domain::gacha_item::GachaItemEntity;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct GachaClaimEntity {
|
||||
pub id: Uuid,
|
||||
pub user_id: Uuid,
|
||||
pub gacha_item_id: Uuid,
|
||||
pub claim_id: Uuid,
|
||||
pub claim_type: String,
|
||||
pub status: String,
|
||||
pub quantity: i32,
|
||||
pub metadata: Option<Value>,
|
||||
pub is_deleted: bool,
|
||||
pub claimed_at: DateTime<Utc>,
|
||||
pub created_at: DateTime<Utc>,
|
||||
pub updated_at: DateTime<Utc>,
|
||||
pub deleted_at: Option<DateTime<Utc>>,
|
||||
pub id: Uuid,
|
||||
pub user_id: Uuid,
|
||||
pub gacha_item_id: Uuid,
|
||||
pub claim_id: Uuid,
|
||||
pub claim_type: String,
|
||||
pub status: String,
|
||||
pub quantity: i32,
|
||||
pub metadata: Option<Value>,
|
||||
pub is_deleted: bool,
|
||||
pub claimed_at: DateTime<Utc>,
|
||||
pub created_at: DateTime<Utc>,
|
||||
pub updated_at: DateTime<Utc>,
|
||||
pub deleted_at: Option<DateTime<Utc>>,
|
||||
}
|
||||
|
||||
/// Denormalized struct for claim detail responses with nested user and item data.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct GachaClaimDetail {
|
||||
pub id: Uuid,
|
||||
pub user: UsersDetailQueryDto,
|
||||
pub item: GachaItemEntity,
|
||||
pub is_deleted: bool,
|
||||
pub created_at: DateTime<Utc>,
|
||||
pub updated_at: DateTime<Utc>,
|
||||
pub id: Uuid,
|
||||
pub user: UsersDetailQueryDto,
|
||||
pub item: GachaItemEntity,
|
||||
pub is_deleted: bool,
|
||||
pub created_at: DateTime<Utc>,
|
||||
pub updated_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use async_trait::async_trait;
|
||||
use uuid::Uuid;
|
||||
use imphnen_utils::AppError;
|
||||
use super::gacha_claim::{GachaClaimDetail, GachaClaimEntity};
|
||||
use async_trait::async_trait;
|
||||
use imphnen_utils::AppError;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[async_trait]
|
||||
pub trait GachaClaimRepository: Send + Sync {
|
||||
async fn find_by_id(&self, id: Uuid) -> Result<GachaClaimDetail, AppError>;
|
||||
async fn create(&self, entity: GachaClaimEntity) -> Result<(), AppError>;
|
||||
async fn find_by_id(&self, id: Uuid) -> Result<GachaClaimDetail, AppError>;
|
||||
async fn create(&self, entity: GachaClaimEntity) -> Result<(), AppError>;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use async_trait::async_trait;
|
||||
use uuid::Uuid;
|
||||
use imphnen_utils::AppError;
|
||||
use super::gacha_claim::{GachaClaimDetail, GachaClaimEntity};
|
||||
use async_trait::async_trait;
|
||||
use imphnen_utils::AppError;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[async_trait]
|
||||
pub trait GachaClaimService: Send + Sync {
|
||||
async fn get_claim(&self, id: Uuid) -> Result<GachaClaimDetail, AppError>;
|
||||
async fn create_claim(&self, entity: GachaClaimEntity) -> Result<(), AppError>;
|
||||
async fn get_claim(&self, id: Uuid) -> Result<GachaClaimDetail, AppError>;
|
||||
async fn create_claim(&self, entity: GachaClaimEntity) -> Result<(), AppError>;
|
||||
}
|
||||
|
||||
@@ -1,41 +1,41 @@
|
||||
use imphnen_libs::ZodValidate;
|
||||
use imphnen_iam::users::infrastructure::http::dto::UsersDetailItemDto;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use utoipa::ToSchema;
|
||||
use crate::gacha_claims::domain::gacha_claim::GachaClaimDetail;
|
||||
use crate::gacha_items::infrastructure::http::dto::GachaItemDto;
|
||||
use imphnen_iam::users::infrastructure::http::dto::UsersDetailItemDto;
|
||||
use imphnen_libs::ZodValidate;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use utoipa::ToSchema;
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
pub struct GachaClaimCreateRequestDto {
|
||||
pub user_id: String,
|
||||
pub item_id: String,
|
||||
pub user_id: String,
|
||||
pub item_id: String,
|
||||
}
|
||||
|
||||
impl ZodValidate for GachaClaimCreateRequestDto {
|
||||
fn zod_validate(value: &serde_json::Value) -> Result<Self, String> {
|
||||
serde_json::from_value(value.clone()).map_err(|e| e.to_string())
|
||||
}
|
||||
fn zod_validate(value: &serde_json::Value) -> Result<Self, String> {
|
||||
serde_json::from_value(value.clone()).map_err(|e| e.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, ToSchema)]
|
||||
pub struct GachaClaimDetailDto {
|
||||
pub id: String,
|
||||
pub user: UsersDetailItemDto,
|
||||
pub item: GachaItemDto,
|
||||
pub is_deleted: bool,
|
||||
pub created_at: String,
|
||||
pub updated_at: String,
|
||||
pub id: String,
|
||||
pub user: UsersDetailItemDto,
|
||||
pub item: GachaItemDto,
|
||||
pub is_deleted: bool,
|
||||
pub created_at: String,
|
||||
pub updated_at: String,
|
||||
}
|
||||
|
||||
impl From<GachaClaimDetail> for GachaClaimDetailDto {
|
||||
fn from(detail: GachaClaimDetail) -> Self {
|
||||
GachaClaimDetailDto {
|
||||
id: detail.id.to_string(),
|
||||
user: UsersDetailItemDto::from(&detail.user),
|
||||
item: GachaItemDto::from(detail.item),
|
||||
is_deleted: detail.is_deleted,
|
||||
created_at: detail.created_at.to_rfc3339(),
|
||||
updated_at: detail.updated_at.to_rfc3339(),
|
||||
}
|
||||
}
|
||||
fn from(detail: GachaClaimDetail) -> Self {
|
||||
GachaClaimDetailDto {
|
||||
id: detail.id.to_string(),
|
||||
user: UsersDetailItemDto::from(&detail.user),
|
||||
item: GachaItemDto::from(detail.item),
|
||||
is_deleted: detail.is_deleted,
|
||||
created_at: detail.created_at.to_rfc3339(),
|
||||
updated_at: detail.updated_at.to_rfc3339(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
use std::sync::Arc;
|
||||
use axum::{Extension, extract::Path, http::HeaderMap, response::IntoResponse};
|
||||
use imphnen_libs::{AppState, ValidatedJson};
|
||||
use imphnen_utils::{ApiSuccess, ApiMessage};
|
||||
use imphnen_entities::ResponseSuccessDto;
|
||||
use imphnen_iam::{PermissionsEnum, require_permissions};
|
||||
use imphnen_utils::AppError;
|
||||
use uuid::Uuid;
|
||||
use super::dto::{GachaClaimCreateRequestDto, GachaClaimDetailDto};
|
||||
use crate::gacha_claims::domain::{GachaClaimEntity, GachaClaimService};
|
||||
use axum::{Extension, extract::Path, http::HeaderMap, response::IntoResponse};
|
||||
use imphnen_entities::ResponseSuccessDto;
|
||||
use imphnen_iam::{PermissionsEnum, require_permissions};
|
||||
use imphnen_libs::{AppState, ValidatedJson};
|
||||
use imphnen_utils::AppError;
|
||||
use imphnen_utils::{ApiMessage, ApiSuccess};
|
||||
use std::sync::Arc;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[utoipa::path(
|
||||
get,
|
||||
@@ -22,17 +22,17 @@ use crate::gacha_claims::domain::{GachaClaimEntity, GachaClaimService};
|
||||
tag = "Gacha"
|
||||
)]
|
||||
pub async fn get_gacha_claim_by_id(
|
||||
headers: HeaderMap,
|
||||
Extension(state): Extension<AppState>,
|
||||
Extension(service): Extension<Arc<dyn GachaClaimService>>,
|
||||
Path(id): Path<String>,
|
||||
headers: HeaderMap,
|
||||
Extension(state): Extension<AppState>,
|
||||
Extension(service): Extension<Arc<dyn GachaClaimService>>,
|
||||
Path(id): Path<String>,
|
||||
) -> Result<impl IntoResponse, AppError> {
|
||||
require_permissions!(headers, state, [PermissionsEnum::ReadDetailGachaClaims], {
|
||||
let uuid = Uuid::parse_str(&id)
|
||||
.map_err(|e| AppError::BadRequestError(format!("Invalid UUID: {e}")))?;
|
||||
let detail = service.get_claim(uuid).await?;
|
||||
Ok(ApiSuccess(GachaClaimDetailDto::from(detail)))
|
||||
})
|
||||
require_permissions!(headers, state, [PermissionsEnum::ReadDetailGachaClaims], {
|
||||
let uuid = Uuid::parse_str(&id)
|
||||
.map_err(|e| AppError::BadRequestError(format!("Invalid UUID: {e}")))?;
|
||||
let detail = service.get_claim(uuid).await?;
|
||||
Ok(ApiSuccess(GachaClaimDetailDto::from(detail)))
|
||||
})
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
@@ -46,32 +46,34 @@ pub async fn get_gacha_claim_by_id(
|
||||
tag = "Gacha"
|
||||
)]
|
||||
pub async fn post_create_gacha_claim(
|
||||
headers: HeaderMap,
|
||||
Extension(state): Extension<AppState>,
|
||||
Extension(service): Extension<Arc<dyn GachaClaimService>>,
|
||||
ValidatedJson(payload): ValidatedJson<GachaClaimCreateRequestDto>,
|
||||
headers: HeaderMap,
|
||||
Extension(state): Extension<AppState>,
|
||||
Extension(service): Extension<Arc<dyn GachaClaimService>>,
|
||||
ValidatedJson(payload): ValidatedJson<GachaClaimCreateRequestDto>,
|
||||
) -> Result<impl IntoResponse, AppError> {
|
||||
require_permissions!(headers, state, [PermissionsEnum::CreateGachaClaims], {
|
||||
let user_id = Uuid::parse_str(&payload.user_id)
|
||||
.map_err(|e| AppError::BadRequestError(format!("Invalid user_id UUID: {e}")))?;
|
||||
let item_id = Uuid::parse_str(&payload.item_id)
|
||||
.map_err(|e| AppError::BadRequestError(format!("Invalid item_id UUID: {e}")))?;
|
||||
let entity = GachaClaimEntity {
|
||||
id: Uuid::new_v4(),
|
||||
user_id,
|
||||
gacha_item_id: item_id,
|
||||
claim_id: Uuid::new_v4(),
|
||||
claim_type: "standard".to_string(),
|
||||
status: "claimed".to_string(),
|
||||
quantity: 1,
|
||||
metadata: None,
|
||||
is_deleted: false,
|
||||
claimed_at: chrono::Utc::now(),
|
||||
created_at: chrono::Utc::now(),
|
||||
updated_at: chrono::Utc::now(),
|
||||
deleted_at: None,
|
||||
};
|
||||
service.create_claim(entity).await?;
|
||||
Ok(ApiMessage::created("Gacha claim created"))
|
||||
})
|
||||
require_permissions!(headers, state, [PermissionsEnum::CreateGachaClaims], {
|
||||
let user_id = Uuid::parse_str(&payload.user_id).map_err(|e| {
|
||||
AppError::BadRequestError(format!("Invalid user_id UUID: {e}"))
|
||||
})?;
|
||||
let item_id = Uuid::parse_str(&payload.item_id).map_err(|e| {
|
||||
AppError::BadRequestError(format!("Invalid item_id UUID: {e}"))
|
||||
})?;
|
||||
let entity = GachaClaimEntity {
|
||||
id: Uuid::new_v4(),
|
||||
user_id,
|
||||
gacha_item_id: item_id,
|
||||
claim_id: Uuid::new_v4(),
|
||||
claim_type: "standard".to_string(),
|
||||
status: "claimed".to_string(),
|
||||
quantity: 1,
|
||||
metadata: None,
|
||||
is_deleted: false,
|
||||
claimed_at: chrono::Utc::now(),
|
||||
created_at: chrono::Utc::now(),
|
||||
updated_at: chrono::Utc::now(),
|
||||
deleted_at: None,
|
||||
};
|
||||
service.create_claim(entity).await?;
|
||||
Ok(ApiMessage::created("Gacha claim created"))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,20 +1,29 @@
|
||||
use std::sync::Arc;
|
||||
use axum::{Router, routing::{get, post}, Extension};
|
||||
use sea_orm::DatabaseConnection;
|
||||
use super::handlers::{get_gacha_claim_by_id, post_create_gacha_claim};
|
||||
use crate::gacha_claims::application::GachaClaimServiceImpl;
|
||||
use crate::gacha_claims::domain::GachaClaimService;
|
||||
use crate::gacha_claims::infrastructure::persistence::PostgresGachaClaimRepository;
|
||||
use super::handlers::{get_gacha_claim_by_id, post_create_gacha_claim};
|
||||
use axum::{
|
||||
Extension, Router,
|
||||
routing::{get, post},
|
||||
};
|
||||
use sea_orm::DatabaseConnection;
|
||||
use std::sync::Arc;
|
||||
|
||||
fn build_service(db: DatabaseConnection, state: std::sync::Arc<imphnen_libs::AppState>) -> Arc<dyn GachaClaimService> {
|
||||
let repo = Arc::new(PostgresGachaClaimRepository::new(db, state));
|
||||
Arc::new(GachaClaimServiceImpl::new(repo))
|
||||
fn build_service(
|
||||
db: DatabaseConnection,
|
||||
state: std::sync::Arc<imphnen_libs::AppState>,
|
||||
) -> Arc<dyn GachaClaimService> {
|
||||
let repo = Arc::new(PostgresGachaClaimRepository::new(db, state));
|
||||
Arc::new(GachaClaimServiceImpl::new(repo))
|
||||
}
|
||||
|
||||
pub fn gacha_claim_router(db: DatabaseConnection, state: std::sync::Arc<imphnen_libs::AppState>) -> Router {
|
||||
let service = build_service(db, state);
|
||||
Router::new()
|
||||
.route("/detail/{id}", get(get_gacha_claim_by_id))
|
||||
.route("/create", post(post_create_gacha_claim))
|
||||
.layer(Extension(service))
|
||||
pub fn gacha_claim_router(
|
||||
db: DatabaseConnection,
|
||||
state: std::sync::Arc<imphnen_libs::AppState>,
|
||||
) -> Router {
|
||||
let service = build_service(db, state);
|
||||
Router::new()
|
||||
.route("/detail/{id}", get(get_gacha_claim_by_id))
|
||||
.route("/create", post(post_create_gacha_claim))
|
||||
.layer(Extension(service))
|
||||
}
|
||||
|
||||
+87
-83
@@ -1,105 +1,109 @@
|
||||
use std::sync::Arc;
|
||||
use crate::gacha_claims::domain::{
|
||||
gacha_claim::{GachaClaimDetail, GachaClaimEntity},
|
||||
repository::GachaClaimRepository,
|
||||
};
|
||||
use crate::gacha_items::domain::gacha_item::GachaItemEntity;
|
||||
use async_trait::async_trait;
|
||||
use sea_orm::prelude::*;
|
||||
use sea_orm::ActiveValue;
|
||||
use uuid::Uuid;
|
||||
use imphnen_utils::AppError;
|
||||
use imphnen_entities::seaorm::gacha::gacha_claims::{
|
||||
Entity as GachaClaimsEntity, ActiveModel as GachaClaimsActiveModel,
|
||||
ActiveModel as GachaClaimsActiveModel, Entity as GachaClaimsEntity,
|
||||
};
|
||||
use imphnen_entities::seaorm::gacha::gacha_items::Entity as GachaItemsEntity;
|
||||
use imphnen_libs::AppState;
|
||||
use crate::gacha_claims::domain::{
|
||||
gacha_claim::{GachaClaimDetail, GachaClaimEntity},
|
||||
repository::GachaClaimRepository,
|
||||
};
|
||||
use crate::gacha_items::domain::gacha_item::GachaItemEntity;
|
||||
use imphnen_utils::AppError;
|
||||
use sea_orm::ActiveValue;
|
||||
use sea_orm::prelude::*;
|
||||
use std::sync::Arc;
|
||||
use uuid::Uuid;
|
||||
|
||||
pub struct PostgresGachaClaimRepository {
|
||||
db: Arc<DatabaseConnection>,
|
||||
state: Arc<AppState>,
|
||||
db: Arc<DatabaseConnection>,
|
||||
state: Arc<AppState>,
|
||||
}
|
||||
|
||||
impl PostgresGachaClaimRepository {
|
||||
pub fn new(db: DatabaseConnection, state: Arc<AppState>) -> Self {
|
||||
Self {
|
||||
db: Arc::new(db),
|
||||
state,
|
||||
}
|
||||
}
|
||||
pub fn new(db: DatabaseConnection, state: Arc<AppState>) -> Self {
|
||||
Self {
|
||||
db: Arc::new(db),
|
||||
state,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl GachaClaimRepository for PostgresGachaClaimRepository {
|
||||
async fn find_by_id(&self, id: Uuid) -> Result<GachaClaimDetail, AppError> {
|
||||
let claim = GachaClaimsEntity::find_by_id(id)
|
||||
.one(self.db.as_ref())
|
||||
.await
|
||||
.map_err(|e| AppError::InternalServerError(e.to_string()))?
|
||||
.ok_or_else(|| AppError::NotFoundError("Gacha claim not found".to_string()))?;
|
||||
async fn find_by_id(&self, id: Uuid) -> Result<GachaClaimDetail, AppError> {
|
||||
let claim = GachaClaimsEntity::find_by_id(id)
|
||||
.one(self.db.as_ref())
|
||||
.await
|
||||
.map_err(|e| AppError::InternalServerError(e.to_string()))?
|
||||
.ok_or_else(|| AppError::NotFoundError("Gacha claim not found".to_string()))?;
|
||||
|
||||
let user = self.state.user_lookup_service
|
||||
.get_user_by_id(claim.user_id, self.state.as_ref())
|
||||
.await
|
||||
.map(|info| info.basic_info)
|
||||
.map_err(|e| AppError::InternalServerError(format!("Failed to fetch user: {e}")))?;
|
||||
let user = self
|
||||
.state
|
||||
.user_lookup_service
|
||||
.get_user_by_id(claim.user_id, self.state.as_ref())
|
||||
.await
|
||||
.map(|info| info.basic_info)
|
||||
.map_err(|e| {
|
||||
AppError::InternalServerError(format!("Failed to fetch user: {e}"))
|
||||
})?;
|
||||
|
||||
let item_model = GachaItemsEntity::find_by_id(claim.gacha_item_id)
|
||||
.one(self.db.as_ref())
|
||||
.await
|
||||
.map_err(|e| AppError::InternalServerError(e.to_string()))?
|
||||
.ok_or_else(|| AppError::NotFoundError("Gacha item not found".to_string()))?;
|
||||
let item_model = GachaItemsEntity::find_by_id(claim.gacha_item_id)
|
||||
.one(self.db.as_ref())
|
||||
.await
|
||||
.map_err(|e| AppError::InternalServerError(e.to_string()))?
|
||||
.ok_or_else(|| AppError::NotFoundError("Gacha item not found".to_string()))?;
|
||||
|
||||
let item = GachaItemEntity {
|
||||
id: item_model.id,
|
||||
item_code: item_model.item_code,
|
||||
name: item_model.name,
|
||||
description: item_model.description,
|
||||
rarity: item_model.rarity,
|
||||
type_: item_model.type_,
|
||||
category: item_model.category,
|
||||
value: item_model.value,
|
||||
weight: item_model.weight,
|
||||
stock: item_model.stock,
|
||||
is_limited: item_model.is_limited,
|
||||
metadata: item_model.metadata,
|
||||
is_deleted: item_model.deleted_at.is_some(),
|
||||
created_at: item_model.created_at,
|
||||
updated_at: item_model.updated_at,
|
||||
deleted_at: item_model.deleted_at,
|
||||
};
|
||||
let item = GachaItemEntity {
|
||||
id: item_model.id,
|
||||
item_code: item_model.item_code,
|
||||
name: item_model.name,
|
||||
description: item_model.description,
|
||||
rarity: item_model.rarity,
|
||||
type_: item_model.type_,
|
||||
category: item_model.category,
|
||||
value: item_model.value,
|
||||
weight: item_model.weight,
|
||||
stock: item_model.stock,
|
||||
is_limited: item_model.is_limited,
|
||||
metadata: item_model.metadata,
|
||||
is_deleted: item_model.deleted_at.is_some(),
|
||||
created_at: item_model.created_at,
|
||||
updated_at: item_model.updated_at,
|
||||
deleted_at: item_model.deleted_at,
|
||||
};
|
||||
|
||||
Ok(GachaClaimDetail {
|
||||
id: claim.id,
|
||||
user,
|
||||
item,
|
||||
is_deleted: claim.deleted_at.is_some(),
|
||||
created_at: claim.created_at,
|
||||
updated_at: claim.updated_at,
|
||||
})
|
||||
}
|
||||
Ok(GachaClaimDetail {
|
||||
id: claim.id,
|
||||
user,
|
||||
item,
|
||||
is_deleted: claim.deleted_at.is_some(),
|
||||
created_at: claim.created_at,
|
||||
updated_at: claim.updated_at,
|
||||
})
|
||||
}
|
||||
|
||||
async fn create(&self, entity: GachaClaimEntity) -> Result<(), AppError> {
|
||||
let active_model = GachaClaimsActiveModel {
|
||||
id: ActiveValue::Set(entity.id),
|
||||
user_id: ActiveValue::Set(entity.user_id),
|
||||
gacha_item_id: ActiveValue::Set(entity.gacha_item_id),
|
||||
claim_id: ActiveValue::Set(entity.claim_id),
|
||||
claim_type: ActiveValue::Set(entity.claim_type),
|
||||
status: ActiveValue::Set(entity.status),
|
||||
quantity: ActiveValue::Set(entity.quantity),
|
||||
metadata: ActiveValue::Set(entity.metadata),
|
||||
created_at: ActiveValue::Set(entity.created_at),
|
||||
updated_at: ActiveValue::Set(entity.updated_at),
|
||||
deleted_at: ActiveValue::Set(entity.deleted_at),
|
||||
claimed_at: ActiveValue::Set(entity.claimed_at),
|
||||
};
|
||||
async fn create(&self, entity: GachaClaimEntity) -> Result<(), AppError> {
|
||||
let active_model = GachaClaimsActiveModel {
|
||||
id: ActiveValue::Set(entity.id),
|
||||
user_id: ActiveValue::Set(entity.user_id),
|
||||
gacha_item_id: ActiveValue::Set(entity.gacha_item_id),
|
||||
claim_id: ActiveValue::Set(entity.claim_id),
|
||||
claim_type: ActiveValue::Set(entity.claim_type),
|
||||
status: ActiveValue::Set(entity.status),
|
||||
quantity: ActiveValue::Set(entity.quantity),
|
||||
metadata: ActiveValue::Set(entity.metadata),
|
||||
created_at: ActiveValue::Set(entity.created_at),
|
||||
updated_at: ActiveValue::Set(entity.updated_at),
|
||||
deleted_at: ActiveValue::Set(entity.deleted_at),
|
||||
claimed_at: ActiveValue::Set(entity.claimed_at),
|
||||
};
|
||||
|
||||
GachaClaimsEntity::insert(active_model)
|
||||
.exec(self.db.as_ref())
|
||||
.await
|
||||
.map_err(|e| AppError::InternalServerError(e.to_string()))?;
|
||||
GachaClaimsEntity::insert(active_model)
|
||||
.exec(self.db.as_ref())
|
||||
.await
|
||||
.map_err(|e| AppError::InternalServerError(e.to_string()))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user