Skip to main content

systemprompt_api/routes/content/
query.rs

1use axum::extract::State;
2use axum::http::StatusCode;
3use axum::response::{IntoResponse, Response};
4use axum::{Extension, Json};
5use systemprompt_content::{ContentError, SearchRequest, SearchService};
6use systemprompt_models::RequestContext;
7use systemprompt_runtime::AppContext;
8
9pub async fn query_handler(
10    Extension(_req_ctx): Extension<RequestContext>,
11    State(ctx): State<AppContext>,
12    Json(request): Json<SearchRequest>,
13) -> Response {
14    log_search_start(&request.query);
15
16    let search_service = match SearchService::new(ctx.db_pool()) {
17        Ok(service) => service,
18        Err(e) => return handle_service_error(&e),
19    };
20
21    execute_search(&search_service, &request).await
22}
23
24fn log_search_start(query: &str) {
25    tracing::info!(query = %query, "Searching");
26}
27
28fn handle_service_error(e: &ContentError) -> Response {
29    tracing::error!(error = %e, "Failed to create search service");
30    internal_error(&e.to_string())
31}
32
33async fn execute_search(service: &SearchService, request: &SearchRequest) -> Response {
34    match service.search(request).await {
35        Ok(response) => {
36            tracing::info!(total = response.total, "Search completed");
37            Json(response).into_response()
38        },
39        Err(e) => {
40            tracing::error!(error = %e, "Search error");
41            internal_error(&e.to_string())
42        },
43    }
44}
45
46fn internal_error(message: &str) -> Response {
47    (
48        StatusCode::INTERNAL_SERVER_ERROR,
49        Json(serde_json::json!({"error": message})),
50    )
51        .into_response()
52}