Unify page-size parameters on _size with table semantics

The stored query lists silently clamped out-of-range ?_size= values
(a request for 5000 quietly returned 1000) and did not accept the max
keyword. They now share the table view semantics via a new
parse_size_limit() helper: blank means default, "max" means the
maximum (max_returned_rows for query lists), negative or non-integer
values are a 400, and values over the maximum are a 400 instead of
being silently clamped.

The /-/allowed and /-/rules debug endpoints renamed their bare
page/page_size parameters to _page/_size, matching the underscore
grammar used by every other system parameter, with the same validation
(400 instead of silently capping page_size at 200). Their HTML debug
pages and next_url/previous_url builders use the new names.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GrHZSypDfMnym1tM5XJAFZ
This commit is contained in:
Claude 2026-07-04 17:54:03 +00:00
commit 3a0ea58557
No known key found for this signature in database
13 changed files with 137 additions and 63 deletions

View file

@ -377,8 +377,8 @@ path always renders the HTML form; `.json` returns JSON.
resources. Items gain a `reason` field if the actor also holds
`permissions-debug`.
- **Parameters:** `action` (required; missing → 400 canonical error, unknown
→ 404), `parent`, `child` (requires `parent`), `page` (default 1),
`page_size` (default 50, silently capped at 200).
→ 404), `parent`, `child` (requires `parent`), `_page` (default 1),
`_size` (default 50, maximum 200, accepts `max`; out-of-range → 400).
- **Response:** `{"action", "actor_id", "page", "page_size", "total",
"items": [{"parent", "child", "resource"}]}` with optional `next_url` /
`previous_url`.
@ -1031,8 +1031,9 @@ databases (`database`/`database_color` are null, `show_database` true).
- **Permissions:** no single gate; results filtered per query by
`view-query` (private queries appear only for their owner).
- **Parameters:** `_size` (default 20 HTML / **50 JSON**, clamped 11000;
non-integer → 400), `_next` (cursor), `q` (substring search over
- **Parameters:** `_size` (default 20 HTML / **50 JSON**; accepts `max`;
values over `max_returned_rows` or non-integers → 400, matching table
`_size` semantics), `_next` (cursor), `q` (substring search over
name/title/description/sql), `is_write` / `is_private` (booleans; invalid →
400 `"is_write must be 0 or 1"`), `source`, `owner_id`.
- **Response** — 200: