fix(svc): clamp client list limits to a server ceiling #24

Merged
nalum merged 1 commit from fix/list-limit-ceiling into main 2026-08-13 11:38:29 +00:00
Owner

Client-supplied list limits passed straight through to the table layer, and limit 0 meant unbounded. All eight List RPCs now clamp to a server ceiling (svc.MaxListLimit = 500):

  • svc.List clamps every limit it receives; apikey and webhook handlers (which bypassed svc.List) clamp at the handler.
  • Internal everything-reads move to an explicit svc.ListAll (event occurrence expansion would otherwise silently cap at 500); Table.List(0) callers in hydrate/notify/dispatcher/export are untouched.
  • sqlmock tests pin the SQL: limit 0 → 500, above-ceiling → 500, small limits honoured, ListAll emits no LIMIT clause.

Fixes #18

🤖 Generated with Claude Code

Client-supplied list limits passed straight through to the table layer, and `limit 0` meant unbounded. All eight List RPCs now clamp to a server ceiling (`svc.MaxListLimit = 500`): - `svc.List` clamps every limit it receives; apikey and webhook handlers (which bypassed `svc.List`) clamp at the handler. - Internal everything-reads move to an explicit `svc.ListAll` (event occurrence expansion would otherwise silently cap at 500); `Table.List(0)` callers in hydrate/notify/dispatcher/export are untouched. - sqlmock tests pin the SQL: limit 0 → 500, above-ceiling → 500, small limits honoured, `ListAll` emits no LIMIT clause. Fixes #18 🤖 Generated with [Claude Code](https://claude.com/claude-code)
fix(svc): clamp client list limits to a server ceiling
All checks were successful
check / go (push) Successful in 2m8s
check / web (push) Successful in 1m23s
8954569099
Every entity List RPC passed the client-supplied limit straight to the
table, where 0 means unbounded — any authenticated client could drag a
full table through the interceptors in one call. Only AuditLog clamped
server-side. This generalises that pattern at the svc seam: svc.List now
routes the limit through ClampListLimit (limit <= 0 or above
MaxListLimit, 500, becomes the ceiling), and the two handlers that hit
the table directly (api keys, webhooks) clamp the same way.

Internal everything-reads are deliberately untouched: occurrence
expansion moves to a new svc.ListAll that stays unbounded, and callers
of Table.List(0) (hydration, notify, webhook dispatch, export) keep the
table semantics — the ceiling applies only where a client-supplied
number enters.

Fixes #18
nalum force-pushed fix/list-limit-ceiling from 8954569099
All checks were successful
check / go (push) Successful in 2m8s
check / web (push) Successful in 1m23s
to 3f1925a0ff
Some checks failed
tag / tag (push) Has been cancelled
check / go (push) Successful in 1m48s
check / web (push) Successful in 1m24s
2026-08-13 11:33:33 +00:00
Compare
nalum scheduled this pull request to auto merge when all checks succeed 2026-08-13 11:33:58 +00:00
nalum merged commit 3f1925a0ff into main 2026-08-13 11:38:29 +00:00
nalum deleted branch fix/list-limit-ceiling 2026-08-13 11:38:29 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
eagraiclainne/app!24
No description provided.