//! Router assembly and middleware wiring. //! //! [`build_app`] is the single entry point used by both `main.rs` and the //! integration tests. It mounts the health probe and the public `/api` //! display endpoints, then defers every unmatched path to the static SPA //! service, and wraps the whole stack in the HTTP tracing layer. //! //! Extension points for todos 15-18: extend `api::router()` with the OAuth //! and session routes (they receive [`AppState`] via `State` once //! `with_state` runs). Stateful routes MUST be added before the //! `fallback_service` call. use axum::Router; use axum::routing::get; use tower_http::trace::TraceLayer; use crate::state::AppState; use crate::{api, health, static_files}; /// Build the application router. /// /// Returns a state-resolved `Router` ready for `axum::serve` or /// `tower::ServiceExt::oneshot`. pub fn build_app(state: AppState) -> Router { let router: Router = Router::new() .route("/healthz", get(health::healthz)) .route("/oauth/start", get(crate::oauth::start)) .route("/callback", get(crate::oauth::callback)) .nest("/api", api::router(state.sessions().clone())) .fallback_service(static_files::service(state.config().dist_dir())); router.layer(TraceLayer::new_for_http()).with_state(state) }