ITADN

feat(collections): custom views should pre-project `fields=` to dodge the 200-record refusal; HTTP 400 needs a help affordance

#1833Openisamu 创建于 2026-06-27
I
isamucommented
## Summary Users authoring a custom collection view via the standard "drop an HTML file in `views/`" workflow hit an opaque **HTTP 400** at runtime once their collection grows past the unselective `getItems` limit (200 records). The view's `fetch(dataUrl)` returns no JSON, the view-side `if (!res.ok)` handler surfaces only `データ読込に失敗: HTTP 400` ("data load failed: HTTP 400"), and the user has no in-product affordance to understand or recover. Two reproductions surfaced from end-user feedback this week: 1. Collection grew past the unselective threshold; existing custom view stopped loading. 2. New custom-view author was unaware that `fields=` / `ids=` are required at scale. ## Reproduction 1. Create / grow any user collection beyond 200 records. 2. Open a custom view whose `fetch` call passes the raw `dataUrl` with no query string. 3. The view shows `データ読込に失敗: HTTP 400`. ## Root cause (already known, recording for tracking) `server/agent/mcp-tools/manageCollection.ts:154-155` refuses the call: ``` manageCollection: refused — '<slug>' has <N> records, over the unselective limit of 200. Pass ids for specific records or fields to project only the columns you need. ``` `server/api/routes/collections.ts:416-421` (`sendToolResult`) sees the refusal string is not JSON and converts it to a `400 { error: <string> }`. The view's `fetch` wrapper has no special-case for this body shape and falls through to its generic "HTTP <status>" toast. ## Proposed fixes Two complementary changes, ordered by impact: ### 1. Teach the custom-view authoring skill to include `fields=` by default The skill that scaffolds a custom view (the one Claude follows when authoring `views/<slug>.html`) should: - Default to constructing the fetch URL as `fetch(dataUrl + "?fields=<comma-joined cols the view actually reads>")`. - Include a short comment in the generated HTML explaining **why** (the 200-record threshold), so a human-edited view doesn't drift back to the raw form. - For views that genuinely need full records, the skill should call this out and suggest `ids=` with a windowed fetch pattern. This is the highest-leverage fix because it prevents the bug at authoring time and matches the existing manageCollection contract (callers must project). ### 2. Surface a "ask for help" affordance on the 400 toast When a custom view's data fetch returns a non-2xx and the response body is a string (not the expected records JSON): - Show the **server's actual error message** to the user instead of just `HTTP <status>` — they currently lose all context. - Add a **"解決策を尋ねる" / "Ask for help"** button on the error toast that opens a chat draft seeded with: the view file path, the collection slug, the server's refusal string, and a prompt like "How do I fix this error in this view?" — closes the loop without forcing the user to copy/paste. This pairs well with the existing chat-from-view affordance (#1752) — the seed prompt is structured the same way. ### 3. (Optional) Server-side: include `fields` / `ids` hint in the 400 JSON The server already includes the descriptive refusal text in the string body; restating it as a structured field (`{ error, hint, suggestedAction }`) would let the view auto-render a more useful inline message without having to parse the human-readable string. Lower priority than #1 and #2. ## Files involved - `server/agent/mcp-tools/manageCollection.ts:154-155` (refusal site) - `server/api/routes/collections.ts:416-421` (`sendToolResult` 400-mapping) - The custom-view scaffolding flow (skill / help docs that explain how to write `views/<slug>.html`) ## Notes This issue records anonymised end-user feedback; the specific collection slug and view filename are intentionally omitted.
0 条评论