use axum::{
extract::{Query, State},
http::StatusCode,
Json,
};
use serde::Deserialize;
use super::sessions::ErrorResponse;
use crate::web::state::WebState;
#[derive(Deserialize)]
pub struct SearchQuery {
pub q: String,
pub limit: Option<i64>,
pub cursor: Option<i64>,
pub sort: Option<String>,
pub project: Option<String>,
}
pub async fn global_search(
State(state): State<WebState>,
Query(params): Query<SearchQuery>,
) -> Result<Json<serde_json::Value>, (StatusCode, Json<ErrorResponse>)> {
let limit = params.limit.unwrap_or(50).min(500);
let offset = params.cursor.unwrap_or(0);
let sort = params.sort.as_deref().unwrap_or("relevance");
let results = state
.db
.global_search(¶ms.q, limit, offset, sort, params.project.as_deref())
.await
.map_err(|e| {
(
StatusCode::INTERNAL_SERVER_ERROR,
Json(ErrorResponse {
error: e.to_string(),
}),
)
})?;
let count = results.len();
let next = if count as i64 >= limit {
offset + limit
} else {
0
};
Ok(Json(serde_json::json!({
"query": params.q,
"results": results,
"count": count,
"next": next
})))
}