use axum::Router; use uuid::Uuid; use erp_core::error::AppResult; use erp_core::events::EventBus; use erp_core::module::ErpModule; use crate::handler::{auth_handler, user_handler}; /// Auth module implementing the `ErpModule` trait. /// /// Manages identity, authentication, and user CRUD within the ERP platform. /// This module has no dependencies on other business modules. pub struct AuthModule; impl AuthModule { pub fn new() -> Self { Self } /// Build public (unauthenticated) routes for the auth module. /// /// These routes do not require a valid JWT token. /// The caller wraps this into whatever state type the application uses. pub fn public_routes() -> Router where crate::auth_state::AuthState: axum::extract::FromRef, S: Clone + Send + Sync + 'static, { Router::new() .route("/auth/login", axum::routing::post(auth_handler::login)) .route("/auth/refresh", axum::routing::post(auth_handler::refresh)) } /// Build protected (authenticated) routes for the auth module. /// /// These routes require a valid JWT token, verified by the middleware layer. /// The caller wraps this into whatever state type the application uses. pub fn protected_routes() -> Router where crate::auth_state::AuthState: axum::extract::FromRef, S: Clone + Send + Sync + 'static, { Router::new() .route("/auth/logout", axum::routing::post(auth_handler::logout)) .route( "/users", axum::routing::get(user_handler::list_users).post(user_handler::create_user), ) .route( "/users/{id}", axum::routing::get(user_handler::get_user) .put(user_handler::update_user) .delete(user_handler::delete_user), ) } } impl Default for AuthModule { fn default() -> Self { Self::new() } } #[async_trait::async_trait] impl ErpModule for AuthModule { fn name(&self) -> &str { "auth" } fn version(&self) -> &str { env!("CARGO_PKG_VERSION") } fn dependencies(&self) -> Vec<&str> { // Auth is a foundational module with no business-module dependencies. vec![] } fn register_routes(&self, router: Router) -> Router { // The ErpModule trait uses Router<()> (no state type). // Actual route registration with typed state is done // via public_routes() and protected_routes(), called by erp-server. router } fn register_event_handlers(&self, _bus: &EventBus) { // Phase 2: subscribe to events from other modules if needed } async fn on_tenant_created(&self, _tenant_id: Uuid) -> AppResult<()> { // Phase 2+: create default roles and admin user for new tenant Ok(()) } async fn on_tenant_deleted(&self, _tenant_id: Uuid) -> AppResult<()> { // Phase 2+: soft-delete all users belonging to the tenant Ok(()) } fn as_any(&self) -> &dyn std::any::Any { self } }