#[cfg(feature = "server")]
use axum::{
middleware,
routing::{delete, get, post, put},
Extension, Router,
};
#[cfg(feature = "server")]
use super::handlers;
#[cfg(feature = "server")]
use crate::server::auth::{middleware as auth_middleware, JwtManager};
#[cfg(feature = "server")]
use crate::server::config::{CorsConfig, RateLimitConfig};
#[cfg(feature = "server")]
use crate::server::middleware::{rate_limit_middleware, RateLimiter};
#[cfg(feature = "server")]
use crate::server::queue::WorkQueue;
#[cfg(feature = "server")]
use crate::server::storage::UserStorage;
#[cfg(feature = "server")]
use crate::server::Storage;
#[cfg(feature = "server")]
use std::sync::Arc;
#[cfg(feature = "server")]
use tower_http::cors::{Any, CorsLayer};
#[cfg(feature = "server")]
pub fn create_router(
user_storage: Arc<dyn UserStorage>,
jwt_manager: Arc<JwtManager>,
storage: Arc<dyn Storage>,
queue: Arc<dyn WorkQueue>,
cors_config: Option<CorsConfig>,
rate_limit_config: RateLimitConfig,
) -> Router {
let auth_layer = auth_middleware::AuthLayer::new(Arc::clone(&jwt_manager));
let rate_limiter = RateLimiter::new(rate_limit_config);
let cors_layer = if let Some(cors) = cors_config {
let mut layer = CorsLayer::new();
if cors.allowed_origins.is_empty() || cors.allowed_origins.contains(&"*".to_string()) {
layer = layer.allow_origin(Any);
} else {
use axum::http::HeaderValue;
let origins: Vec<HeaderValue> = cors
.allowed_origins
.iter()
.filter_map(|o| o.parse().ok())
.collect();
layer = layer.allow_origin(origins);
}
if cors.allowed_methods.is_empty() {
layer = layer.allow_methods(Any);
} else {
use axum::http::Method;
let methods: Vec<Method> = cors
.allowed_methods
.iter()
.filter_map(|m| m.parse().ok())
.collect();
layer = layer.allow_methods(methods);
}
if cors.allow_credentials {
layer = layer.allow_credentials(true);
}
layer = layer.allow_headers(Any);
Some(layer)
} else {
None
};
let public_routes = Router::new()
.route("/health", get(handlers::monitoring::health_check))
.route("/ready", get(handlers::monitoring::readiness_check))
.route("/live", get(handlers::monitoring::liveness_check))
.route("/version", get(handlers::health::version))
.route("/metrics", get(handlers::monitoring::metrics))
.route("/stats", get(handlers::monitoring::stats))
.route("/api/v1/auth/login", post(handlers::auth::login))
.route("/api/v1/auth/register", post(handlers::auth::register));
let protected_routes = Router::new()
.route("/api/v1/auth/me", get(handlers::auth::get_current_user))
.route("/api/v1/auth/refresh", post(handlers::auth::refresh_token))
.route(
"/api/v1/workflows",
get(handlers::workflows::list_workflows),
)
.route(
"/api/v1/workflows",
post(handlers::workflows::create_workflow),
)
.route(
"/api/v1/workflows/:id",
get(handlers::workflows::get_workflow),
)
.route(
"/api/v1/workflows/:id",
put(handlers::workflows::update_workflow),
)
.route(
"/api/v1/workflows/:id",
delete(handlers::workflows::delete_workflow),
)
.route(
"/api/v1/workflows/:id/versions",
get(handlers::workflows::list_workflow_versions),
)
.route(
"/api/v1/workflows/:id/versions/:version",
get(handlers::workflows::get_workflow_version),
)
.route(
"/api/v1/workflows/validate",
post(handlers::workflows::validate_workflow),
)
.route(
"/api/v1/executions",
get(handlers::executions::list_executions),
)
.route(
"/api/v1/executions",
post(handlers::executions::create_execution),
)
.route(
"/api/v1/executions/:id",
get(handlers::executions::get_execution),
)
.route(
"/api/v1/executions/:id/cancel",
post(handlers::executions::cancel_execution),
)
.route(
"/api/v1/executions/:id/logs",
get(handlers::executions::get_execution_logs),
)
.route(
"/api/v1/schedules",
get(handlers::schedules::list_schedules),
)
.route(
"/api/v1/schedules",
post(handlers::schedules::create_schedule),
)
.route(
"/api/v1/schedules/:id",
get(handlers::schedules::get_schedule),
)
.route(
"/api/v1/schedules/:id",
put(handlers::schedules::update_schedule),
)
.route(
"/api/v1/schedules/:id",
delete(handlers::schedules::delete_schedule),
)
.route(
"/api/v1/schedules/:id/trigger",
post(handlers::schedules::trigger_schedule),
)
.route(
"/api/v1/organizations",
get(handlers::organizations::list_organizations),
)
.route(
"/api/v1/organizations",
post(handlers::organizations::create_organization),
)
.route(
"/api/v1/organizations/:id",
get(handlers::organizations::get_organization),
)
.route(
"/api/v1/organizations/:id",
put(handlers::organizations::update_organization),
)
.route(
"/api/v1/organizations/:id",
delete(handlers::organizations::delete_organization),
)
.route("/api/v1/teams", get(handlers::organizations::list_teams))
.route("/api/v1/teams", post(handlers::organizations::create_team))
.route("/api/v1/teams/:id", get(handlers::organizations::get_team))
.route(
"/api/v1/teams/:id",
put(handlers::organizations::update_team),
)
.route(
"/api/v1/teams/:id",
delete(handlers::organizations::delete_team),
)
.route(
"/api/v1/teams/:id/members",
post(handlers::organizations::add_team_member),
)
.route(
"/api/v1/teams/:id/members/:user_id",
delete(handlers::organizations::remove_team_member),
)
.route(
"/api/v1/teams/:id/members",
get(handlers::organizations::get_team_members),
)
.route("/api/v1/api-keys", get(handlers::api_keys::list_api_keys))
.route("/api/v1/api-keys", post(handlers::api_keys::create_api_key))
.route("/api/v1/api-keys/:id", get(handlers::api_keys::get_api_key))
.route(
"/api/v1/api-keys/:id",
put(handlers::api_keys::update_api_key),
)
.route(
"/api/v1/api-keys/:id",
delete(handlers::api_keys::revoke_api_key),
)
.route(
"/api/v1/api-keys/:id/rotate",
post(handlers::api_keys::rotate_api_key),
)
.route(
"/api/v1/executions/:id/stream",
get(handlers::websocket::execution_stream),
)
.route("/api/v1/queue/stats", get(handlers::queue::get_queue_stats))
.route_layer(middleware::from_fn(move |req, next| {
auth_middleware::auth_middleware(auth_layer.clone(), req, next)
}));
let web_ui_routes = Router::new()
.route("/", get(handlers::static_files::serve_index))
.route("/*path", get(handlers::static_files::serve_static));
let mut router = Router::new()
.merge(public_routes)
.merge(protected_routes)
.merge(web_ui_routes)
.with_state(Arc::clone(&storage))
.layer(Extension(storage))
.layer(Extension(queue))
.layer(Extension(user_storage))
.layer(Extension(jwt_manager));
router = router.route_layer(middleware::from_fn(move |req, next| {
rate_limit_middleware(rate_limiter.clone(), req, next)
}));
if let Some(cors) = cors_layer {
router = router.layer(cors);
}
router
}