arcly-http 0.1.0

Enterprise-grade NestJS-inspired web framework on axum: zero-lock DI, declarative controllers, multi-tenant data routing, transactional outbox, ABAC, and a self-documenting OpenAPI surface
Documentation
//! Mounts plugin-registered routes as axum handlers.
//!
//! Lives in the `web` layer (not `core`) so the DI engine and plugin
//! lifecycle stay HTTP-agnostic. Reuses `boundary::assemble_context` —
//! plugin routes get exactly the same body cap, trace propagation, and
//! credential extraction as macro routes, from the same code path.

use axum::routing::{on, MethodFilter, MethodRouter};

use crate::core::engine::FrozenDiContainer;
use crate::core::plugins::PluginRoute;
use crate::observability::lean_telemetry::on_request_start;
use crate::web::boundary::{assemble_context, InFlightGuard};

#[doc(hidden)]
pub fn build_plugin_route(
    container: &'static FrozenDiContainer,
    route: &PluginRoute,
) -> MethodRouter {
    let filter = MethodFilter::try_from(axum::http::Method::from(route.method))
        .expect("supported HTTP method");
    let h = route.handler.clone();

    let handler = move |req: axum::extract::Request| {
        let h = h.clone();
        async move {
            let (parts, body) = req.into_parts();
            // Plugin routes have no matched pattern (mounted verbatim) and no
            // static RouteSpec — metrics label by empty pattern, not raw path.
            let ctx = assemble_context(parts, body, Default::default(), container, "", None).await;

            let _guard = on_request_start();
            let _in_flight = InFlightGuard::new();
            h(ctx).await
        }
    };

    on(filter, handler)
}