refactor: migrate to clean architecture with trait-based DI (v0.2.0)
Complete architectural overhaul across all 12 crates: - Replace validator crate with zod-rs for all DTO validation - Replace manual pagination with paginator-rs/paginator-sea-orm - Migrate all modules (iam, cms, gacha, dimentorin) to clean architecture: domain → application → infrastructure layers - Introduce trait-based DI (Arc<dyn Trait>) at every layer for repositories and services - Delete all v1/ legacy SurrealDB-era code across every crate - Replace opaque response helpers with typed IntoResponse structs (ApiSuccess, ApiCreated, ApiPaginated, ApiMessage) - Remove dual_mode_repository, migration_validation_errors, validator.rs dead code - Zero cargo clippy warnings; release build clean Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
1b3366d735
commit
e432a1a743
+27
-28
@@ -1,28 +1,27 @@
|
||||
[package]
|
||||
name = "imphnen-gateway"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
imphnen-iam.workspace = true
|
||||
imphnen-libs.workspace = true
|
||||
imphnen-utils.workspace = true
|
||||
imphnen-gacha.workspace = true
|
||||
imphnen-entities.workspace = true
|
||||
imphnen-middleware.workspace = true
|
||||
imphnen-cms.workspace = true
|
||||
imphnen-dimentorin.workspace = true
|
||||
axum.workspace = true
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
utoipa.workspace = true
|
||||
lazy_static.workspace = true
|
||||
regex.workspace = true
|
||||
validator.workspace = true
|
||||
axum-test.workspace = true
|
||||
rand.workspace = true
|
||||
tokio.workspace = true
|
||||
chrono.workspace = true
|
||||
anyhow.workspace = true
|
||||
tower-http.workspace = true
|
||||
utoipa-swagger-ui.workspace = true
|
||||
[package]
|
||||
name = "imphnen-gateway"
|
||||
version = "0.2.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
imphnen-iam.workspace = true
|
||||
imphnen-libs.workspace = true
|
||||
imphnen-utils.workspace = true
|
||||
imphnen-gacha.workspace = true
|
||||
imphnen-entities.workspace = true
|
||||
imphnen-middleware.workspace = true
|
||||
imphnen-cms.workspace = true
|
||||
imphnen-dimentorin.workspace = true
|
||||
axum.workspace = true
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
utoipa.workspace = true
|
||||
lazy_static.workspace = true
|
||||
regex.workspace = true
|
||||
axum-test.workspace = true
|
||||
rand.workspace = true
|
||||
tokio.workspace = true
|
||||
chrono.workspace = true
|
||||
anyhow.workspace = true
|
||||
tower-http.workspace = true
|
||||
utoipa-swagger-ui.workspace = true
|
||||
|
||||
+66
-68
@@ -1,41 +1,39 @@
|
||||
use imphnen_cms::v1::landing::events::events_controller;
|
||||
use imphnen_cms::v1::landing::events::events_dto::{EventsDetailItemDto, EventsListItemDto};
|
||||
use imphnen_cms::v1::landing::testimonials::testimonials_controller;
|
||||
use imphnen_cms::v1::landing::testimonials::testimonials_dto::{
|
||||
use imphnen_cms::events::infrastructure::http::handlers as events_controller;
|
||||
use imphnen_cms::events::infrastructure::http::dto::{EventsDetailItemDto, EventsListItemDto};
|
||||
use imphnen_cms::testimonials::infrastructure::http::handlers as testimonials_controller;
|
||||
use imphnen_cms::testimonials::infrastructure::http::dto::{
|
||||
TestimonialsCreateRequestDto, TestimonialsDetailItemDto,
|
||||
TestimonialsListItemDto, TestimonialsUpdateRequestDto,
|
||||
};
|
||||
use imphnen_dimentorin::v1::mentors::{
|
||||
mentors_controller,
|
||||
mentors_dto::{
|
||||
IdentityAndVerification, MentorDetailResponseDto, MentorListResponseDto,
|
||||
MentorRegisterFromTokenRequestDto, MentorRegisterResponseDto,
|
||||
MentorUpdateRequestDto, MentorUserRegisterRequestDto, MentorVerifyRequestDto,
|
||||
MentoringLogistics, MentoringRate, ProfessionalProfile,
|
||||
},
|
||||
use imphnen_dimentorin::mentors::infrastructure::http::handlers as mentors_controller;
|
||||
use imphnen_dimentorin::mentors::infrastructure::http::dto::{
|
||||
IdentityAndVerification, MentorDetailResponseDto, MentorListResponseDto,
|
||||
MentorRegisterFromTokenRequestDto, MentorRegisterResponseDto,
|
||||
MentorUpdateRequestDto, MentorUserRegisterRequestDto, MentorVerifyRequestDto,
|
||||
MentoringLogistics, MentoringRate, ProfessionalProfile,
|
||||
};
|
||||
use imphnen_dimentorin::v1::sessions::{
|
||||
sessions_controller,
|
||||
use imphnen_dimentorin::sessions::infrastructure::http::handlers as sessions_controller;
|
||||
use imphnen_dimentorin::sessions::infrastructure::http::dto::{
|
||||
BookSessionRequestDto, BookSessionResponseDto, MentorAvailabilityDto,
|
||||
SessionFeedbackRequestDto, SessionFeedbackResponseDto, SessionListItemDto,
|
||||
SessionListResponseDto, UpdateSessionStatusRequestDto, UpdateSessionStatusResponseDto,
|
||||
AvailabilitySlotDto,
|
||||
};
|
||||
use imphnen_gacha::v1::gacha_claims::{gacha_claims_controller, GachaClaimItemDto, GachaClaimRequestDto};
|
||||
use imphnen_gacha::v1::gacha_items::{gacha_items_controller, GachaItemDto};
|
||||
use imphnen_gacha::v1::gacha_items::gacha_items_dto::GachaItemRequestDto;
|
||||
use imphnen_gacha::v1::gacha_rolls::{gacha_rolls_controller, GachaRollItemDto};
|
||||
use imphnen_gacha::v1::gacha_rolls::gacha_rolls_dto::GachaRollRequestDto;
|
||||
use imphnen_entities::{PermissionsItemDto, RolesDetailItemDto};
|
||||
use imphnen_entities::{MessageResponseDto, MetaRequestDto, MetaResponseDto, ResponseListSuccessDto, ResponseSuccessDto};
|
||||
use imphnen_iam::v1::auth::auth_dto::{AuthLoginRequestDto, AuthLoginResponsetDto, AuthNewPasswordRequestDto, AuthRefreshTokenRequestDto, AuthResendOtpRequestDto, AuthVerifyEmailRequestDto, TokenDto};
|
||||
use imphnen_iam::v1::permissions::permissions_dto::PermissionsRequestDto;
|
||||
use imphnen_iam::v1::roles::RolesListItemDto;
|
||||
use imphnen_iam::v1::roles::roles_dto::{RolesRequestCreateDto, RolesRequestUpdateDto};
|
||||
use imphnen_iam::v1::users::UsersDetailItemDto;
|
||||
use imphnen_iam::v1::users::users_dto::{UsersCreateRequestDto, UsersListItemDto, UsersUpdateRequestDto};
|
||||
use imphnen_iam::v1::{auth, permissions, roles, users};
|
||||
use imphnen_iam::v1::users::users_controller::FileUploadSchema;
|
||||
use imphnen_gacha::gacha_claims::infrastructure::http::handlers as gacha_claims_controller;
|
||||
use imphnen_gacha::gacha_claims::infrastructure::http::dto::{GachaClaimDetailDto, GachaClaimCreateRequestDto};
|
||||
use imphnen_gacha::gacha_items::infrastructure::http::handlers as gacha_items_controller;
|
||||
use imphnen_gacha::gacha_items::infrastructure::http::dto::{GachaItemDto, GachaItemCreateRequestDto};
|
||||
use imphnen_gacha::gacha_rolls::infrastructure::http::handlers as gacha_rolls_controller;
|
||||
use imphnen_gacha::gacha_rolls::infrastructure::http::dto::{GachaRollItemDto, GachaRollCreateRequestDto};
|
||||
use imphnen_entities::{MessageResponseDto, ResponseListSuccessDto, ResponseSuccessDto};
|
||||
use imphnen_iam::auth::infrastructure::http::dto::{AuthLoginRequestDto, AuthLoginResponsetDto, AuthNewPasswordRequestDto, AuthRefreshTokenRequestDto, AuthResendOtpRequestDto, AuthVerifyEmailRequestDto, TokenDto};
|
||||
use imphnen_iam::permissions::infrastructure::http::handlers as permissions_controller;
|
||||
use imphnen_iam::permissions::infrastructure::http::dto::{PermissionsCreateRequestDto, PermissionsItemDto};
|
||||
use imphnen_iam::roles::infrastructure::http::handlers as roles_controller;
|
||||
use imphnen_iam::roles::infrastructure::http::dto::{RolesDetailItemDto, RolesListItemDto, RolesCreateRequestDto, RolesUpdateRequestDto};
|
||||
use imphnen_iam::users::infrastructure::http::handlers as users_controller;
|
||||
use imphnen_iam::users::infrastructure::http::dto::{UsersDetailItemDto, UsersCreateRequestDto, UsersListItemDto, UsersUpdateRequestDto, FileUploadSchema};
|
||||
use imphnen_iam::auth::infrastructure::http::handlers as auth_controller;
|
||||
use utoipa::{
|
||||
Modify, OpenApi,
|
||||
openapi::security::{Http, HttpAuthScheme, SecurityScheme, SecurityRequirement},
|
||||
@@ -44,43 +42,44 @@ use utoipa::{
|
||||
#[derive(OpenApi)]
|
||||
#[openapi(
|
||||
paths(
|
||||
auth::auth_controller::post_login,
|
||||
auth::auth_controller::post_login_mentor,
|
||||
auth::auth_controller::post_register,
|
||||
auth::auth_controller::post_verify_email,
|
||||
auth::auth_controller::post_resend_otp,
|
||||
auth::auth_controller::post_refresh_token,
|
||||
auth::auth_controller::post_forgot_password,
|
||||
auth::auth_controller::post_new_password,
|
||||
users::users_controller::post_create_user,
|
||||
users::users_controller::put_update_user,
|
||||
users::users_controller::put_update_user_me,
|
||||
users::users_controller::patch_user_active_status,
|
||||
users::users_controller::delete_user,
|
||||
users::users_controller::get_user_by_id,
|
||||
users::users_controller::get_user_me,
|
||||
users::users_controller::get_user_list,
|
||||
users::users_controller::upload_file,
|
||||
roles::roles_controller::get_role_list,
|
||||
roles::roles_controller::get_role_by_id,
|
||||
roles::roles_controller::post_create_role,
|
||||
roles::roles_controller::put_update_role,
|
||||
roles::roles_controller::delete_role,
|
||||
permissions::permissions_controller::get_permission_list,
|
||||
permissions::permissions_controller::get_permission_by_id,
|
||||
permissions::permissions_controller::post_create_permission,
|
||||
permissions::permissions_controller::put_update_permission,
|
||||
permissions::permissions_controller::delete_permission,
|
||||
gacha_claims_controller::get_detail_gacha_claim,
|
||||
auth_controller::post_login,
|
||||
auth_controller::post_login_mentor,
|
||||
auth_controller::post_register,
|
||||
auth_controller::post_verify_email,
|
||||
auth_controller::post_resend_otp,
|
||||
auth_controller::post_refresh_token,
|
||||
auth_controller::post_forgot_password,
|
||||
auth_controller::post_new_password,
|
||||
users_controller::post_create_user,
|
||||
users_controller::put_update_user,
|
||||
users_controller::put_update_user_me,
|
||||
users_controller::patch_user_active_status,
|
||||
users_controller::delete_user,
|
||||
users_controller::get_user_by_id,
|
||||
users_controller::get_user_me,
|
||||
users_controller::get_user_list,
|
||||
users_controller::upload_file,
|
||||
roles_controller::get_role_list,
|
||||
roles_controller::get_role_by_id,
|
||||
roles_controller::post_create_role,
|
||||
roles_controller::put_update_role,
|
||||
roles_controller::delete_role,
|
||||
permissions_controller::get_permission_list,
|
||||
permissions_controller::get_permission_by_id,
|
||||
permissions_controller::post_create_permission,
|
||||
permissions_controller::put_update_permission,
|
||||
permissions_controller::delete_permission,
|
||||
gacha_claims_controller::get_gacha_claim_by_id,
|
||||
gacha_claims_controller::post_create_gacha_claim,
|
||||
gacha_items_controller::get_gacha_item_list,
|
||||
gacha_items_controller::get_gacha_item_by_id,
|
||||
gacha_items_controller::post_create_gacha_item,
|
||||
gacha_items_controller::put_update_gacha_item,
|
||||
gacha_items_controller::delete_gacha_item,
|
||||
gacha_rolls_controller::get_detail_gacha_roll,
|
||||
gacha_rolls_controller::get_gacha_roll_by_id,
|
||||
gacha_rolls_controller::post_create_gacha_roll,
|
||||
gacha_rolls_controller::post_execute_gacha_roll,
|
||||
gacha_rolls_controller::delete_gacha_roll,
|
||||
events_controller::get_event_list,
|
||||
events_controller::get_event_by_id,
|
||||
events_controller::post_create_event,
|
||||
@@ -109,8 +108,6 @@ use utoipa::{
|
||||
),
|
||||
components(
|
||||
schemas(
|
||||
MetaRequestDto,
|
||||
MetaResponseDto,
|
||||
MessageResponseDto,
|
||||
AuthLoginRequestDto,
|
||||
AuthLoginResponsetDto,
|
||||
@@ -120,25 +117,26 @@ use utoipa::{
|
||||
AuthRefreshTokenRequestDto,
|
||||
ResponseSuccessDto<TokenDto>,
|
||||
RolesListItemDto,
|
||||
RolesRequestCreateDto,
|
||||
RolesRequestUpdateDto,
|
||||
PermissionsRequestDto,
|
||||
RolesDetailItemDto,
|
||||
RolesCreateRequestDto,
|
||||
RolesUpdateRequestDto,
|
||||
PermissionsCreateRequestDto,
|
||||
PermissionsItemDto,
|
||||
UsersDetailItemDto,
|
||||
UsersListItemDto,
|
||||
UsersUpdateRequestDto,
|
||||
UsersCreateRequestDto,
|
||||
FileUploadSchema,
|
||||
GachaClaimItemDto,
|
||||
GachaClaimRequestDto,
|
||||
GachaClaimDetailDto,
|
||||
GachaClaimCreateRequestDto,
|
||||
GachaItemDto,
|
||||
GachaItemRequestDto,
|
||||
GachaItemCreateRequestDto,
|
||||
GachaRollItemDto,
|
||||
GachaRollRequestDto,
|
||||
GachaRollCreateRequestDto,
|
||||
ResponseListSuccessDto<Vec<GachaItemDto>>,
|
||||
ResponseSuccessDto<GachaRollItemDto>,
|
||||
ResponseSuccessDto<GachaItemDto>,
|
||||
ResponseSuccessDto<GachaClaimItemDto>,
|
||||
ResponseSuccessDto<GachaClaimDetailDto>,
|
||||
ResponseSuccessDto<AuthLoginResponsetDto>,
|
||||
ResponseListSuccessDto<Vec<RolesListItemDto>>,
|
||||
ResponseSuccessDto<RolesDetailItemDto>,
|
||||
|
||||
+72
-59
@@ -1,59 +1,72 @@
|
||||
use axum::{
|
||||
Extension,
|
||||
Router,
|
||||
middleware::from_fn,
|
||||
response::Redirect,
|
||||
routing::get,
|
||||
};
|
||||
use imphnen_cms::{
|
||||
events_protected_routes,
|
||||
events_public_routes,
|
||||
testimonials_protected_routes,
|
||||
testimonials_public_routes,
|
||||
};
|
||||
use imphnen_dimentorin::dimentorin_router;
|
||||
use imphnen_gacha::gacha_router;
|
||||
use imphnen_iam::{
|
||||
iam_protected_routes,
|
||||
iam_public_routes,
|
||||
v1::auth::auth_repository::AuthRepoImpl,
|
||||
};
|
||||
use imphnen_libs::PostgresUserLookupService;
|
||||
use imphnen_libs::{AppState, axum::PostgresClients};
|
||||
use imphnen_middleware::{auth_middleware, cors_middleware, rate_limiting_middleware, security_headers_middleware};
|
||||
use std::sync::Arc;
|
||||
use utoipa_swagger_ui::SwaggerUi;
|
||||
|
||||
pub mod docs;
|
||||
pub use docs::{ApiDoc, SecurityAddon, docs_router};
|
||||
|
||||
pub async fn gateway_service(
|
||||
postgres_clients: PostgresClients,
|
||||
) -> Router {
|
||||
let state = AppState {
|
||||
postgres_connection: postgres_clients.main.clone(),
|
||||
user_lookup_service: Arc::new(PostgresUserLookupService::new()),
|
||||
auth_repository: Arc::new(AuthRepoImpl::new()),
|
||||
};
|
||||
|
||||
let public_routes = Router::new()
|
||||
.merge(iam_public_routes().layer(from_fn(rate_limiting_middleware)))
|
||||
.merge(testimonials_public_routes())
|
||||
.merge(events_public_routes());
|
||||
|
||||
let protected_routes = Router::new()
|
||||
.merge(iam_protected_routes())
|
||||
.merge(events_protected_routes())
|
||||
.merge(testimonials_protected_routes())
|
||||
.merge(dimentorin_router())
|
||||
.nest("/gacha", gacha_router())
|
||||
.layer(from_fn(auth_middleware));
|
||||
|
||||
Router::new()
|
||||
.route("/", get(Redirect::to("/docs")))
|
||||
.nest("/v1", public_routes.merge(protected_routes))
|
||||
.merge(SwaggerUi::new("/docs").url("/openapi.json", docs_router()))
|
||||
.layer(cors_middleware())
|
||||
.layer(from_fn(security_headers_middleware))
|
||||
.layer(Extension(state))
|
||||
}
|
||||
use axum::{
|
||||
Extension,
|
||||
Router,
|
||||
middleware::from_fn,
|
||||
response::Redirect,
|
||||
routing::get,
|
||||
};
|
||||
use imphnen_cms::{
|
||||
events_protected_routes,
|
||||
events_public_routes,
|
||||
testimonials_protected_routes,
|
||||
testimonials_public_routes,
|
||||
};
|
||||
use imphnen_dimentorin::{
|
||||
mentors_public_routes, mentors_protected_routes,
|
||||
sessions_public_routes, sessions_protected_routes,
|
||||
};
|
||||
use imphnen_gacha::gacha_router;
|
||||
use imphnen_iam::{
|
||||
auth_public_routes,
|
||||
permissions_protected_routes,
|
||||
roles_protected_routes,
|
||||
users_protected_routes,
|
||||
};
|
||||
use imphnen_libs::services::PostgresAuthRepository as AuthRepoImpl;
|
||||
use imphnen_libs::PostgresUserLookupService;
|
||||
use imphnen_libs::{AppState, axum::PostgresClients};
|
||||
use imphnen_middleware::{auth_middleware, cors_middleware, rate_limiting_middleware, security_headers_middleware};
|
||||
use std::sync::Arc;
|
||||
use utoipa_swagger_ui::SwaggerUi;
|
||||
|
||||
pub mod docs;
|
||||
pub use docs::{ApiDoc, SecurityAddon, docs_router};
|
||||
|
||||
pub async fn gateway_service(
|
||||
postgres_clients: PostgresClients,
|
||||
) -> Router {
|
||||
let state = AppState {
|
||||
postgres_connection: postgres_clients.main.clone(),
|
||||
user_lookup_service: Arc::new(PostgresUserLookupService::new()),
|
||||
auth_repository: Arc::new(AuthRepoImpl::new()),
|
||||
};
|
||||
|
||||
let db = state.postgres_connection.conn.clone();
|
||||
let state_arc = Arc::new(state.clone());
|
||||
|
||||
let public_routes = Router::new()
|
||||
.merge(auth_public_routes(db.clone(), Arc::clone(&state_arc)).layer(from_fn(rate_limiting_middleware)))
|
||||
.merge(testimonials_public_routes(db.clone()))
|
||||
.merge(events_public_routes(db.clone()))
|
||||
.merge(mentors_public_routes(db.clone(), Arc::clone(&state_arc)))
|
||||
.merge(sessions_public_routes(db.clone()));
|
||||
|
||||
let protected_routes = Router::new()
|
||||
.merge(users_protected_routes(db.clone(), Arc::clone(&state_arc)))
|
||||
.merge(roles_protected_routes(db.clone(), Arc::clone(&state_arc)))
|
||||
.merge(permissions_protected_routes(db.clone(), Arc::clone(&state_arc)))
|
||||
.merge(events_protected_routes(db.clone()))
|
||||
.merge(testimonials_protected_routes(db.clone()))
|
||||
.merge(mentors_protected_routes(db.clone(), Arc::clone(&state_arc)))
|
||||
.merge(sessions_protected_routes(db.clone(), Arc::clone(&state_arc)))
|
||||
.nest("/gacha", gacha_router(db.clone(), Arc::clone(&state_arc)))
|
||||
.layer(from_fn(auth_middleware));
|
||||
|
||||
Router::new()
|
||||
.route("/", get(Redirect::to("/docs")))
|
||||
.nest("/v1", public_routes.merge(protected_routes))
|
||||
.merge(SwaggerUi::new("/docs").url("/openapi.json", docs_router()))
|
||||
.layer(cors_middleware())
|
||||
.layer(from_fn(security_headers_middleware))
|
||||
.layer(Extension(state))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user