fix: compute the /mangas total only on the first page

GET /mangas recomputed count(*) over FILTER_WHERE (up to five correlated
subqueries) on every page, so pagination cost scaled with catalog size. The
total doesn't change as a caller walks pages, so compute it once at offset 0
and return null thereafter (the envelope already serialises total as
Option<i64>; the frontend types it number|null and the library route ignores
it).

Bump to 0.124.7.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
MechaCat02
2026-07-07 21:14:15 +02:00
parent ce9a727c73
commit ebf0b8289b
7 changed files with 85 additions and 22 deletions

View File

@@ -99,6 +99,42 @@ async fn list_returns_total_count_independent_of_pagination(pool: PgPool) {
assert_eq!(body["page"]["total"], 3);
}
#[sqlx::test(migrations = "./migrations")]
async fn list_total_is_computed_only_on_the_first_page(pool: PgPool) {
let h = common::harness(pool);
let (_, cookie) = common::register_user(&h.app).await;
for title in ["One Piece", "Berserk", "Vinland Saga"] {
seed(&h.app, &cookie, title).await;
}
// Page 1 (offset 0): total is the full population.
let body0 = common::body_json(
h.app
.clone()
.oneshot(common::get("/api/v1/mangas?limit=2&offset=0"))
.await
.unwrap(),
)
.await;
assert_eq!(body0["page"]["total"], 3);
// Page 2 (offset 2): total is omitted (null) — the correlated count is
// not recomputed on every page. Items still paginate correctly.
let body1 = common::body_json(
h.app
.oneshot(common::get("/api/v1/mangas?limit=2&offset=2"))
.await
.unwrap(),
)
.await;
assert!(
body1["page"]["total"].is_null(),
"total should be null past the first page, got {}",
body1["page"]["total"]
);
assert_eq!(body1["items"].as_array().unwrap().len(), 1);
}
#[sqlx::test(migrations = "./migrations")]
async fn search_via_trigram_tolerates_typos(pool: PgPool) {
let h = common::harness(pool);