diff --git a/src/application/state.rs b/src/application/state.rs index db4864c..222bcd0 100644 --- a/src/application/state.rs +++ b/src/application/state.rs @@ -138,7 +138,11 @@ impl AppState { ai_usage_repo, webauthn: config.webauthn, challenge_store: Arc::new(ChallengeStore::new()), - http_client: reqwest::Client::new(), + #[allow(clippy::expect_used)] + http_client: reqwest::ClientBuilder::new() + .timeout(std::time::Duration::from_secs(30)) + .build() + .expect("failed to build HTTP client"), foursquare_url: config.foursquare_url, foursquare_api_key: config.foursquare_api_key, openrouter_url: config.openrouter_url, diff --git a/src/infrastructure/repositories/pagination.rs b/src/infrastructure/repositories/pagination.rs index 9d87c17..a2a9b61 100644 --- a/src/infrastructure/repositories/pagination.rs +++ b/src/infrastructure/repositories/pagination.rs @@ -54,12 +54,14 @@ where } PageSize::Limited(page_size) => { let limit = i64::from(page_size); - let mut page = request.page(); - let offset = i64::from(page - 1).saturating_mul(limit); - let total = fetch_count(pool, count_query, search).await?; - let mut records = fetch_records::( + // Clamp page to valid range before fetching + let adjusted = (*request).ensure_page_within(total as u64); + let page = adjusted.page(); + let offset = i64::from(page - 1).saturating_mul(limit); + + let records = fetch_records::( pool, base_query, order_clause, @@ -68,20 +70,6 @@ where ) .await?; - if page > 1 && records.is_empty() && total > 0 { - let last_page = ((total + limit - 1) / limit) as u32; - page = last_page.max(1); - let offset = i64::from(page - 1).saturating_mul(limit); - records = fetch_records::( - pool, - base_query, - order_clause, - search, - Some((limit, offset)), - ) - .await?; - } - let mut items = Vec::with_capacity(records.len()); for record in records { items.push(map_fn(record)?);