use std::sync::Arc;
use axum::Extension;
use axum::Json;
use axum::extract::{Path, Query};
use tracing::field::Empty;
use uuid::Uuid;
use toolkit_security::SecurityContext;
use crate::api::rest::handlers::sessions::identity_from_ctx;
use crate::domain::error::Result;
use crate::domain::search::{SearchPage, SearchQuery};
use crate::domain::service::search_service::SearchService;
#[tracing::instrument(
skip(svc, ctx, query),
fields(
session_id = %session_id,
scope = "session",
query_length = Empty,
result_count = Empty,
),
)]
pub async fn get_search_session(
Extension(ctx): Extension<SecurityContext>,
Extension(svc): Extension<Arc<SearchService>>,
Path(session_id): Path<Uuid>,
Query(query): Query<SearchQuery>,
) -> Result<Json<SearchPage>> {
let identity = identity_from_ctx(&ctx)?;
let q_len = query.q.as_deref().map(|s| s.chars().count()).unwrap_or(0);
tracing::Span::current().record("query_length", q_len);
let page = svc.search_in_session(&identity, session_id, &query).await?;
tracing::Span::current().record("result_count", page.items.len());
Ok(Json(page))
}
#[tracing::instrument(
skip(svc, ctx, query),
fields(
scope = "cross_session",
query_length = Empty,
result_count = Empty,
),
)]
pub async fn get_search(
Extension(ctx): Extension<SecurityContext>,
Extension(svc): Extension<Arc<SearchService>>,
Query(query): Query<SearchQuery>,
) -> Result<Json<SearchPage>> {
let identity = identity_from_ctx(&ctx)?;
let q_len = query.q.as_deref().map(|s| s.chars().count()).unwrap_or(0);
tracing::Span::current().record("query_length", q_len);
let page = svc.search_across_sessions(&identity, &query).await?;
tracing::Span::current().record("result_count", page.items.len());
Ok(Json(page))
}
#[cfg(test)]
#[path = "search_tests.rs"]
mod search_tests;