mirror of
https://github.com/ruvnet/RuView
synced 2026-08-09 20:21:43 +00:00
Squashed 'vendor/ruvector/' content from commit b64c2172
git-subtree-dir: vendor/ruvector git-subtree-split: b64c21726f2bb37286d9ee36a7869fef60cc6900
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
use axum::{
|
||||
routing::{delete, get, post},
|
||||
Router,
|
||||
};
|
||||
use tower::ServiceBuilder;
|
||||
use tower_http::{
|
||||
compression::CompressionLayer,
|
||||
cors::CorsLayer,
|
||||
trace::{DefaultMakeSpan, DefaultOnResponse, TraceLayer},
|
||||
};
|
||||
use tracing::Level;
|
||||
|
||||
use super::{
|
||||
handlers::{
|
||||
convert_document, delete_pdf_job, get_health, get_ocr_results, get_ocr_usage,
|
||||
get_pdf_status, process_latex, process_pdf, process_strokes, process_text,
|
||||
stream_pdf_results,
|
||||
},
|
||||
middleware::{auth_middleware, rate_limit_middleware},
|
||||
state::AppState,
|
||||
};
|
||||
|
||||
/// Create the main application router with all routes and middleware
|
||||
pub fn router(state: AppState) -> Router {
|
||||
// API v3 routes
|
||||
let api_routes = Router::new()
|
||||
// Image processing
|
||||
.route("/v3/text", post(process_text))
|
||||
// Digital ink processing
|
||||
.route("/v3/strokes", post(process_strokes))
|
||||
// Legacy equation processing
|
||||
.route("/v3/latex", post(process_latex))
|
||||
// Async PDF processing
|
||||
.route("/v3/pdf", post(process_pdf))
|
||||
.route("/v3/pdf/:id", get(get_pdf_status))
|
||||
.route("/v3/pdf/:id", delete(delete_pdf_job))
|
||||
.route("/v3/pdf/:id/stream", get(stream_pdf_results))
|
||||
// Document conversion
|
||||
.route("/v3/converter", post(convert_document))
|
||||
// History and usage
|
||||
.route("/v3/ocr-results", get(get_ocr_results))
|
||||
.route("/v3/ocr-usage", get(get_ocr_usage))
|
||||
// Apply auth and rate limiting to all API routes
|
||||
.layer(
|
||||
ServiceBuilder::new()
|
||||
.layer(axum::middleware::from_fn_with_state(
|
||||
state.clone(),
|
||||
auth_middleware,
|
||||
))
|
||||
.layer(axum::middleware::from_fn_with_state(
|
||||
state.clone(),
|
||||
rate_limit_middleware,
|
||||
)),
|
||||
);
|
||||
|
||||
// Health check (no auth required)
|
||||
let health_routes = Router::new().route("/health", get(get_health));
|
||||
|
||||
// Combine all routes
|
||||
Router::new()
|
||||
.merge(api_routes)
|
||||
.merge(health_routes)
|
||||
.layer(
|
||||
ServiceBuilder::new()
|
||||
// Tracing layer
|
||||
.layer(
|
||||
TraceLayer::new_for_http()
|
||||
.make_span_with(DefaultMakeSpan::new().level(Level::INFO))
|
||||
.on_response(DefaultOnResponse::new().level(Level::INFO)),
|
||||
)
|
||||
// CORS layer
|
||||
.layer(CorsLayer::permissive())
|
||||
// Compression layer
|
||||
.layer(CompressionLayer::new()),
|
||||
)
|
||||
.with_state(state)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use axum::body::Body;
|
||||
use axum::http::{Request, StatusCode};
|
||||
use tower::ServiceExt;
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_health_endpoint() {
|
||||
let state = AppState::new();
|
||||
let app = router(state);
|
||||
|
||||
let response = app
|
||||
.oneshot(
|
||||
Request::builder()
|
||||
.uri("/health")
|
||||
.body(Body::empty())
|
||||
.unwrap(),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(response.status(), StatusCode::OK);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user