feat: add limit/pagination to awards endpoint (#132) #157

Merged
cal merged 5 commits from issue/132-feat-add-limit-pagination-to-awards-endpoint into main 2026-03-24 12:07:30 +00:00
Collaborator

Summary

  • Adds optional limit query param (default 100, max 500) to GET /api/v2/awards
  • Clamped via max(0, min(limit, 500)) — guards negative values and upper bound
  • .limit() applied after all filters; both CSV and JSON paths honour the limit

Closes #132

## Summary - Adds optional `limit` query param (default 100, max 500) to `GET /api/v2/awards` - Clamped via `max(0, min(limit, 500))` — guards negative values and upper bound - `.limit()` applied after all filters; both CSV and JSON paths honour the limit Closes #132
Claude added 1 commit 2026-03-24 07:02:04 +00:00
Add optional limit query param (default 100, max 500) to GET /api/v2/awards.
Clamped via max(0, min(limit, 500)) to guard negative values and upper bound.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude added the
ai-reviewing
label 2026-03-24 07:15:47 +00:00
Claude reviewed 2026-03-24 07:16:45 +00:00
Claude left a comment
Author
Collaborator

AI Code Review

Files Reviewed

  • app/routers_v2/awards.py (modified)

Findings

Correctness

  • limit: int = 100 correctly uses a plain int with a default (rather than Optional[int] = 100 as the prior 6 pagination endpoints do). This is functionally equivalent for FastAPI query params — and arguably more correct since None is never a meaningful limit value. The PR description says Optional[int] but the code is better than described.
  • max(0, min(limit, 500)) clamping is correct: guards negative values and upper bound.
  • .limit() applied after all filters, before the if csv: branch — both CSV and JSON paths honour the limit.
  • Optional already imported at line 2 — no missing import.

Security

  • No issues found. Auth checks on POST/DELETE are unchanged.

Style & Conventions

  • Bulk of the diff is ruff auto-format (single → double quotes, function signature reformatting) — consistent with the pattern seen in PRs #103, #152, #154, #155, #156.
  • No unused imports introduced.

Suggestions

  • MINOR: count in the JSON response reflects the limited row count, not the total matching rows. This is the pre-existing pattern across all 7 paginated endpoints (notifications, scout_claims, rewards, scout_opportunities, batstats, events, awards). Non-blocking — noted for completeness. A follow-up issue to add a total field across all paginated endpoints would be the clean resolution.
  • MINOR: limit=0 returns an empty response even when matching awards exist (max(0, …) lower-clamps to 0, and Peewee LIMIT 0 returns nothing). Same edge case as all prior pagination PRs. Non-blocking.

Verdict: COMMENT

Clean, correct implementation that matches the established pagination pattern. The int = 100 (vs Optional[int] = 100) deviation from prior endpoints is a minor positive. Both minor notes are pre-existing across the full pagination series and non-blocking. Posting as COMMENT due to Gitea self-review restriction — this would otherwise be APPROVED.


Automated review by Claude PR Reviewer

## AI Code Review ### Files Reviewed - `app/routers_v2/awards.py` (modified) ### Findings #### Correctness - `limit: int = 100` correctly uses a plain `int` with a default (rather than `Optional[int] = 100` as the prior 6 pagination endpoints do). This is functionally equivalent for FastAPI query params — and arguably more correct since `None` is never a meaningful limit value. The PR description says `Optional[int]` but the code is better than described. - `max(0, min(limit, 500))` clamping is correct: guards negative values and upper bound. ✅ - `.limit()` applied after all filters, before the `if csv:` branch — both CSV and JSON paths honour the limit. ✅ - `Optional` already imported at line 2 — no missing import. ✅ #### Security - No issues found. Auth checks on POST/DELETE are unchanged. #### Style & Conventions - Bulk of the diff is ruff auto-format (single → double quotes, function signature reformatting) — consistent with the pattern seen in PRs #103, #152, #154, #155, #156. - No unused imports introduced. #### Suggestions - **MINOR**: `count` in the JSON response reflects the limited row count, not the total matching rows. This is the pre-existing pattern across all 7 paginated endpoints (`notifications`, `scout_claims`, `rewards`, `scout_opportunities`, `batstats`, `events`, `awards`). Non-blocking — noted for completeness. A follow-up issue to add a `total` field across all paginated endpoints would be the clean resolution. - **MINOR**: `limit=0` returns an empty response even when matching awards exist (`max(0, …)` lower-clamps to 0, and Peewee `LIMIT 0` returns nothing). Same edge case as all prior pagination PRs. Non-blocking. ### Verdict: COMMENT Clean, correct implementation that matches the established pagination pattern. The `int = 100` (vs `Optional[int] = 100`) deviation from prior endpoints is a minor positive. Both minor notes are pre-existing across the full pagination series and non-blocking. Posting as COMMENT due to Gitea self-review restriction — this would otherwise be APPROVED. --- *Automated review by Claude PR Reviewer*
Claude added
ai-reviewed
and removed
ai-reviewing
labels 2026-03-24 07:17:13 +00:00
cal approved these changes 2026-03-24 12:04:38 +00:00
cal left a comment
Owner

Approved. Clean pagination implementation consistent with the established pattern. Reviewer notes are pre-existing non-blockers across the full pagination series.

Approved. Clean pagination implementation consistent with the established pattern. Reviewer notes are pre-existing non-blockers across the full pagination series.
cal added 1 commit 2026-03-24 12:04:51 +00:00
cal added 1 commit 2026-03-24 12:05:57 +00:00
cal added 1 commit 2026-03-24 12:06:38 +00:00
cal added 1 commit 2026-03-24 12:07:15 +00:00
cal merged commit 849d14a1ec into main 2026-03-24 12:07:30 +00:00
cal deleted branch issue/132-feat-add-limit-pagination-to-awards-endpoint 2026-03-24 12:07:31 +00:00
Sign in to join this conversation.
No description provided.