From c8984f9515b155d4ae1aa3672980ffc76bdbda84 Mon Sep 17 00:00:00 2001 From: nikit Date: Mon, 6 Jul 2026 20:01:07 -0400 Subject: [PATCH] perf(expenses,study): add skip/limit pagination to list endpoints Both routes hard-capped results at 200 with no way to page past that, so users with more than 200 expenses or study sessions could never see older entries. Accept optional limit (clamped 1-200, default 200 to preserve prior behavior) and skip query params, and return total count alongside the page so callers can tell if more data exists. Fixes #13 --- src/app/api/expenses/route.ts | 9 +++++++-- src/app/api/study/sessions/route.ts | 9 +++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/app/api/expenses/route.ts b/src/app/api/expenses/route.ts index a032679..31f00f5 100644 --- a/src/app/api/expenses/route.ts +++ b/src/app/api/expenses/route.ts @@ -17,6 +17,8 @@ export async function GET(req: NextRequest) { const { searchParams } = new URL(req.url); const from = searchParams.get("from"); const to = searchParams.get("to"); + const limit = Math.min(Math.max(Number(searchParams.get("limit")) || 200, 1), 200); + const skip = Math.max(Number(searchParams.get("skip")) || 0, 0); const filter: Record = { userId }; if (from || to) { @@ -37,9 +39,12 @@ export async function GET(req: NextRequest) { } } - const expenses = await Expense.find(filter).sort({ date: -1 }).limit(200).lean(); + const [expenses, total] = await Promise.all([ + Expense.find(filter).sort({ date: -1 }).skip(skip).limit(limit).lean(), + Expense.countDocuments(filter), + ]); - return NextResponse.json({ expenses }); + return NextResponse.json({ expenses, total, skip, limit }); } export async function POST(req: NextRequest) { diff --git a/src/app/api/study/sessions/route.ts b/src/app/api/study/sessions/route.ts index 709ff8a..3ddd671 100644 --- a/src/app/api/study/sessions/route.ts +++ b/src/app/api/study/sessions/route.ts @@ -18,6 +18,8 @@ export async function GET(req: NextRequest) { const subject = searchParams.get("subject"); const from = searchParams.get("from"); const to = searchParams.get("to"); + const limit = Math.min(Math.max(Number(searchParams.get("limit")) || 200, 1), 200); + const skip = Math.max(Number(searchParams.get("skip")) || 0, 0); const filter: Record = { userId }; if (subject) filter.subject = String(subject); @@ -27,9 +29,12 @@ export async function GET(req: NextRequest) { if (to) (filter.date as Record).$lte = new Date(to); } - const sessions = await StudySession.find(filter).sort({ date: -1 }).limit(200).lean(); + const [sessions, total] = await Promise.all([ + StudySession.find(filter).sort({ date: -1 }).skip(skip).limit(limit).lean(), + StudySession.countDocuments(filter), + ]); - return NextResponse.json({ sessions }); + return NextResponse.json({ sessions, total, skip, limit }); } export async function POST(req: NextRequest) {