Skip to content

fix: clamp public prompts pagination#1130

Open
kuishou68 wants to merge 3 commits intof:mainfrom
kuishou68:fix/1129-prompts-pagination-clamp
Open

fix: clamp public prompts pagination#1130
kuishou68 wants to merge 3 commits intof:mainfrom
kuishou68:fix/1129-prompts-pagination-clamp

Conversation

@kuishou68
Copy link
Copy Markdown

@kuishou68 kuishou68 commented Apr 3, 2026

Closes #1129

Summary

  • normalize invalid page / perPage values on the public prompts API
  • clamp oversized perPage requests to a public maximum of 100
  • add focused tests for invalid, oversized, and valid pagination inputs

Why

The public GET /api/prompts endpoint previously passed unbounded query params directly into Prisma pagination, which allowed oversized reads and payloads.

Testing

  • not run in this sandbox
  • added focused Vitest coverage for the pagination parser

Summary by CodeRabbit

  • Tests

    • Added comprehensive tests validating pagination parameter handling, covering invalid, missing, decimal, oversized, and valid values to ensure consistent defaults and enforced upper limits.
  • Refactor

    • Centralized pagination parsing and validation so API responses consistently apply sensible defaults, preserve valid inputs, and cap items per page for predictable paging behavior.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 3, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4e65b41e-d695-4052-aa94-333f8ddb4665

📥 Commits

Reviewing files that changed from the base of the PR and between 1c12904 and cbef419.

📒 Files selected for processing (2)
  • src/app/api/prompts/__tests__/route.test.ts
  • src/app/api/prompts/route.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/app/api/prompts/route.ts
  • src/app/api/prompts/tests/route.test.ts

📝 Walkthrough

Walkthrough

Adds a pagination parser and constants for the public /api/prompts endpoint, replaces inline parsing in the GET handler with parsePublicPromptPagination, and adds Vitest coverage for edge cases and valid inputs.

Changes

Cohort / File(s) Summary
Pagination Parser Implementation
src/app/api/prompts/route.ts
Adds DEFAULT_PUBLIC_PROMPTS_* and MAX_PUBLIC_PROMPTS_* constants, a paginationSchema/parsePublicPromptPagination(searchParams) helper that coerces/clamps page and perPage to positive integers with defaults and caps, and updates the GET route to use the helper for skip/take and returned pagination fields.
Test Suite
src/app/api/prompts/__tests__/route.test.ts
Adds Vitest tests covering malformed, zero/decimal/non-numeric, oversized, and valid page/perPage query values to verify defaulting and clamping behavior of parsePublicPromptPagination.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 I nibble at queries, tidy and spry,
Clamp perPage tallies so responses stay spry.
Defaults in pocket, malformed ones shooed,
Tests hop along proving each rule.
A small patch, safe bounds — a rabbit-approved crew!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: clamp public prompts pagination' directly and clearly summarizes the main change: adding clamping logic to pagination parameters on the public prompts endpoint.
Linked Issues check ✅ Passed The PR fully addresses all coding requirements from issue #1129: normalizing page/perPage to positive integers, clamping perPage to 100, defaulting malformed values, and implementing a pagination parser with comprehensive Vitest test coverage.
Out of Scope Changes check ✅ Passed All changes are in-scope: pagination constants and schema definition in route.ts, the parsePublicPromptPagination export, GET route refactoring to use the helper, and comprehensive test coverage for the pagination logic.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/app/api/prompts/route.ts (1)

22-33: Consider moving query validation to a small Zod schema for route consistency.

The logic works, but this route family guideline prefers Zod-based request validation and would make this parser contract explicit and easier to evolve.

As per coding guidelines, "Use Zod for request validation in API routes".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/api/prompts/route.ts` around lines 22 - 33, Replace the ad-hoc
parsing in parsePublicPromptPagination with a small Zod schema that validates
and coerce query values: define a Zod object schema (e.g.,
PublicPromptQuerySchema) with optional string/number fields for "page" and
"perPage", apply transforms/coercions to positive integers and default to
DEFAULT_PUBLIC_PROMPTS_PAGE and DEFAULT_PUBLIC_PROMPTS_PER_PAGE, then use
schema.parse/coerce on Object.fromEntries(searchParams) inside
parsePublicPromptPagination and compute perPage = Math.min(parsed.perPage,
MAX_PUBLIC_PROMPTS_PER_PAGE); keep the same return shape ({ page, perPage }) and
preserve the existing constants (DEFAULT_PUBLIC_PROMPTS_PAGE,
DEFAULT_PUBLIC_PROMPTS_PER_PAGE, MAX_PUBLIC_PROMPTS_PER_PAGE).
src/app/api/prompts/__tests__/route.test.ts (1)

5-18: Add malformed-number regression cases to lock parser intent.

Please add cases like "2.5" and "10abc" to ensure malformed values fall back to defaults rather than being partially parsed.

➕ Suggested test additions
 describe("parsePublicPromptPagination", () => {
+  it("defaults malformed numeric tokens", () => {
+    const params = new URLSearchParams({ page: "2.5", perPage: "10abc" });
+    expect(parsePublicPromptPagination(params)).toEqual({ page: 1, perPage: 24 });
+  });
+
   it("defaults invalid values", () => {
     const params = new URLSearchParams({ page: "0", perPage: "NaN" });
     expect(parsePublicPromptPagination(params)).toEqual({ page: 1, perPage: 24 });
   });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/api/prompts/__tests__/route.test.ts` around lines 5 - 18, Add
regression tests to lock parser intent: update
src/app/api/prompts/__tests__/route.test.ts to include cases that pass malformed
numeric strings to parsePublicPromptPagination so they fall back to defaults
rather than being partially parsed. Specifically add a test calling
parsePublicPromptPagination(new URLSearchParams({ page: "2.5", perPage: "50" }))
and asserting { page: 1, perPage: 50 }, and another calling
parsePublicPromptPagination(new URLSearchParams({ page: "2", perPage: "10abc"
})) and asserting { page: 2, perPage: 24 } (use the existing default perPage 24
and clamp rules); reference the parsePublicPromptPagination function in your
assertions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/app/api/prompts/route.ts`:
- Around line 16-33: The current manual parser (parsePositiveInt) accepts
malformed numbers like "2.5" or "10abc" and page has no upper bound; replace
this with Zod validation inside parsePublicPromptPagination: define a Zod schema
(e.g., paginationSchema) that parses searchParams.get("page") and
searchParams.get("perPage") as integers (z.coerce.number().int().positive())
with safe defaults (DEFAULT_PUBLIC_PROMPTS_PAGE,
DEFAULT_PUBLIC_PROMPTS_PER_PAGE), enforce a max for perPage using
MAX_PUBLIC_PROMPTS_PER_PAGE, and enforce a sensible max for page (add or reuse a
MAX_PUBLIC_PROMPTS_PAGE constant) to prevent unbounded skips; then return {
page, perPage } from parsePublicPromptPagination using values validated by the
Zod schema and remove/replace parsePositiveInt usage.

---

Nitpick comments:
In `@src/app/api/prompts/__tests__/route.test.ts`:
- Around line 5-18: Add regression tests to lock parser intent: update
src/app/api/prompts/__tests__/route.test.ts to include cases that pass malformed
numeric strings to parsePublicPromptPagination so they fall back to defaults
rather than being partially parsed. Specifically add a test calling
parsePublicPromptPagination(new URLSearchParams({ page: "2.5", perPage: "50" }))
and asserting { page: 1, perPage: 50 }, and another calling
parsePublicPromptPagination(new URLSearchParams({ page: "2", perPage: "10abc"
})) and asserting { page: 2, perPage: 24 } (use the existing default perPage 24
and clamp rules); reference the parsePublicPromptPagination function in your
assertions.

In `@src/app/api/prompts/route.ts`:
- Around line 22-33: Replace the ad-hoc parsing in parsePublicPromptPagination
with a small Zod schema that validates and coerce query values: define a Zod
object schema (e.g., PublicPromptQuerySchema) with optional string/number fields
for "page" and "perPage", apply transforms/coercions to positive integers and
default to DEFAULT_PUBLIC_PROMPTS_PAGE and DEFAULT_PUBLIC_PROMPTS_PER_PAGE, then
use schema.parse/coerce on Object.fromEntries(searchParams) inside
parsePublicPromptPagination and compute perPage = Math.min(parsed.perPage,
MAX_PUBLIC_PROMPTS_PER_PAGE); keep the same return shape ({ page, perPage }) and
preserve the existing constants (DEFAULT_PUBLIC_PROMPTS_PAGE,
DEFAULT_PUBLIC_PROMPTS_PER_PAGE, MAX_PUBLIC_PROMPTS_PER_PAGE).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c77fbe2a-088b-4b1c-8927-5c50c19f572d

📥 Commits

Reviewing files that changed from the base of the PR and between 4ab7cf1 and 1c12904.

📒 Files selected for processing (2)
  • src/app/api/prompts/__tests__/route.test.ts
  • src/app/api/prompts/route.ts

Comment thread src/app/api/prompts/route.ts Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

api: clamp public /api/prompts pagination parameters

1 participant