mod admin;
mod contrib_graph;
mod files;
mod health;
mod helpers;
mod index_config;
mod indexes;
mod indexes_relocate;
mod reindex_handlers;
mod router;
mod routing;
mod search;
mod search_global;
mod state;
mod state_impl;
mod status;
mod tickers;
mod typeahead;
#[cfg(test)]
mod tests_1073;
#[cfg(test)]
mod tests_829;
#[cfg(test)]
mod tests_chunks;
#[cfg(test)]
mod tests_contrib_graph;
#[cfg(test)]
mod tests_denylist;
#[cfg(test)]
mod tests_grep;
#[cfg(test)]
mod tests_health;
#[cfg(test)]
mod tests_index;
#[cfg(test)]
mod tests_index_config;
#[cfg(test)]
mod tests_list;
#[cfg(test)]
mod tests_search;
#[cfg(test)]
mod tests_stall;
#[cfg(test)]
mod tests_state;
pub use admin::LogsTailParams;
pub use files::ChunksParams;
pub use reindex_handlers::ReindexRequest;
pub use router::{CreateIndexRequest, IndexFileRequest, RemoveFileRequest};
pub use routing::SearchSimilarRequest;
pub use search_global::GlobalSearchRequest;
pub use state::{DaemonEvent, SearchAppState, WarmBootSummary};
use axum::{
response::Redirect,
routing::{delete, get, post},
Router,
};
use std::sync::Arc;
use admin::{
admin_stop_handler, get_config_handler, logs_tail_handler, patch_config_handler,
status_stream_handler,
};
use contrib_graph::{graph_neighbors_handler, ingest_graph_handler};
use files::{get_index_chunks_handler, index_file_handler, remove_file_handler};
use health::health_handler;
use index_config::{index_config_handler, patch_index_config_handler};
use indexes::{create_index_handler, list_indexes_handler, relocate_index_handler};
use reindex_handlers::{reindex_handler, reindex_stream_handler};
use routing::search_similar_handler;
use search::{delete_index_handler, global_search_handler, search_handler};
use status::{graph_handler, graph_stats_handler, index_status_handler};
use tickers::{spawn_disk_size_ticker, spawn_idle_chunk_eviction_ticker, spawn_status_ticker};
use files::{call_chain_handler, global_grep_handler, grep_handler};
use typeahead::typeahead_handler;
#[doc(hidden)]
pub use typeahead::{
typeahead_handler as typeahead_handler_for_tests, TypeaheadParams as TypeaheadParamsForTests,
};
use self::health::upgrade_handler;
pub fn build_router(state: SearchAppState) -> Router {
use crate::service::query_timeout::{apply_query_timeout, QueryTimeoutConfig};
use crate::service::ui::{
chat_handler, list_chat_providers, ui_asset_handler, ui_index_handler,
};
let state_arc = Arc::new(state);
spawn_status_ticker(Arc::clone(&state_arc));
spawn_disk_size_ticker(Arc::clone(&state_arc));
spawn_idle_chunk_eviction_ticker(Arc::clone(&state_arc));
let limiter = crate::service::concurrency::ConcurrencyLimiter::from_env();
let query_timeout_cfg = QueryTimeoutConfig::from_env();
let interactive_limited = Router::new()
.route("/search", post(global_search_handler))
.route("/grep", post(global_grep_handler))
.route("/indexes/{id}/grep", post(grep_handler))
.route("/indexes/{id}/search", post(search_handler))
.route("/indexes/{id}/search_similar", post(search_similar_handler))
.route("/indexes/{id}/typeahead", get(typeahead_handler))
.route_layer(axum::middleware::from_fn(apply_query_timeout))
.layer(axum::Extension(Arc::clone(&query_timeout_cfg)))
.route_layer(axum::middleware::from_fn(
crate::service::concurrency::apply_limiter,
))
.layer(axum::Extension(Arc::clone(&limiter)))
.with_state(Arc::clone(&state_arc));
let bulk_limited = Router::new()
.route("/indexes/{id}/index-file", post(index_file_handler))
.route("/indexes/{id}/remove-file", post(remove_file_handler))
.route("/indexes/{id}/reindex", post(reindex_handler))
.route(
"/indexes/{id}/graph",
post(ingest_graph_handler)
.layer(axum::extract::DefaultBodyLimit::max(64 * 1024 * 1024)),
)
.route_layer(axum::middleware::from_fn(
crate::service::concurrency::apply_limiter,
))
.layer(axum::Extension(Arc::clone(&limiter)))
.with_state(Arc::clone(&state_arc));
let free = Router::new()
.route("/", get(|| async { Redirect::permanent("/ui/") }))
.route("/health", get(health_handler))
.route("/logs/tail", get(logs_tail_handler))
.route("/admin/stop", post(admin_stop_handler))
.route("/status/stream", get(status_stream_handler))
.route(
"/indexes",
get(list_indexes_handler).post(create_index_handler),
)
.route(
"/indexes/{id}",
delete(delete_index_handler).patch(relocate_index_handler),
)
.route("/ui", get(|| async { Redirect::permanent("/ui/") }))
.route("/ui/", get(ui_index_handler))
.route("/ui/{*path}", get(ui_asset_handler))
.route("/chat", post(chat_handler))
.route("/api/chat/providers", get(list_chat_providers))
.route("/indexes/{id}/status", get(index_status_handler))
.route(
"/indexes/{id}/config",
get(index_config_handler).patch(patch_index_config_handler),
)
.route("/indexes/{id}/graph", get(graph_handler))
.route("/indexes/{id}/graph/stats", get(graph_stats_handler))
.route(
"/indexes/{id}/graph/neighbors",
get(graph_neighbors_handler),
)
.route("/indexes/{id}/reindex/stream", get(reindex_stream_handler))
.route("/indexes/{id}/chunks", get(get_index_chunks_handler))
.route("/indexes/{id}/call_chain", get(call_chain_handler))
.route(
"/config",
get(get_config_handler).patch(patch_config_handler),
)
.route("/upgrade", post(upgrade_handler))
.with_state(Arc::clone(&state_arc));
let mut router = free.merge(interactive_limited).merge(bulk_limited);
if let Some(metrics_state) = state_arc.metrics.clone() {
router = router
.route("/metrics", get(crate::service::metrics::metrics_handler))
.layer(axum::Extension(metrics_state));
}
router = router.layer(axum::middleware::from_fn(
crate::service::metrics::request_metrics_middleware,
));
trusty_common::server::with_standard_middleware(router)
}