feat(agent-bff): expose the action form endpoint#1748
Conversation
|
Coverage Impact ⬆️ Merging this pull request will increase total coverage on Modified Files with Diff Coverage (6)
🛟 Help
|
d10c98b to
a65f89e
Compare
636b46b to
5a335a9
Compare
Add POST /v1/:collection/actions/:action/form: resolve the action via
the read-model action allow-list, load its form through agent-client
(tryToSetFields skips unknown submitted values), and return
{ fields, canExecute, requiredFields, skippedFields, layout }. No
activity log is written.
Extract shared token-guard/read-model/callAgent/decodeSegment helpers so
the new action middleware and the data middleware share one read-model
store.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…vives agent-client filters recordIds with .filter(Boolean) before serializing, so a valid numeric primary key of 0 was silently dropped and the form loaded as an unscoped/global action. Coerce ids to strings on the way in. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ry, read-model rethrow - action-routes-middleware: non-POST and non-matching path fall through to next - agent-action-client: real factory wires createRemoteAgentClient().collection().action() - agent-route-helpers: resolveReadModel rethrows a non-schema error unchanged Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
5a335a9 to
a916daa
Compare
Review note —
|
…tionLayoutRoot The comment claimed a layout-shape test guarded against agent-client renaming ActionLayoutRoot's element field, but none existed. Add a test that builds a real ActionLayoutRoot and asserts extractRawLayout unwraps it, plus the empty-layout fallback branch. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Addressed in ae6772e — took the first option (real drift guard). Added
Also tightened the code comment to name the guarding test. Full suite green (618 tests, run in-band). |

Fixes PRD-673
What
Adds
POST /v1/:collection/actions/:action/formtoagent-bff. It loads a Smart Action form without failing on unknown UI-supplied values and returns the fields a UI needs to render (including the layout). No activity log is written.Response shape:
How
isActionAllowed). Since the endpoint map is the allow-list, an absent action cannot be told from a known-but-disallowed one → every non-exposed action maps tounknown_action(404);action_not_allowed(403) has no local trigger, mirroring thecollection/relationprecedent.createRemoteAgentClient().collection().action()), so the stateful/hooks/load+/hooks/changelogic is not reimplemented.tryToSetFieldsskips unknown submitted values and returns them asskippedFields.loadActionForm,tryToSetFields) is wrapped on its own; field/layout reads and mapping stay outside so a local bug surfaces as a 500. Fields and layout are read aftertryToSetFieldsbecause a change hook rebuilds them.src/http/agent-route-helpers.ts(token guard, read-model resolution,callAgent,decodeSegment) so the new action middleware and the existing data middleware share one cache.Decisions / deviations from the ticket
See the planning-decisions comment on PRD-673 for the full list. Highlights:
layout= rawForestServerActionFormLayoutElement[]array. The spec is self-contradictory (prose says "ActionLayoutRootserialized", example shows{type,component,elements}, actualJSON.stringifyyields{layout:[...]}). We return the raw element array.enumValuespresent only forEnumfields (matches the MCP tool + ACenumValues?; the spec example showsnulleverywhere).recordIds: []accepted for global/bulk actions (spec AC only covers missing recordIds); non-array →400 invalid_requestwith no agent call.Europe/Paris(cannot forward the resolved timezone without an agent-client change, forbidden here). Tracked in PRD-768.agent-bffyet (PRD-637); the test asserts the action is never executed / only form hooks are called.Tests
test/action/action-routes-middleware.test.ts+test/action/action-form-mapper.test.ts: full response shape incl. layout, skipped values,canExecutetrue/false, post-change-hook read ordering,recordIdsmissing/non-array/[],valuesnon-object,unknown_action404, agent failures on load andtryToSetFields→ PRD-670, 401/503.Lint ✓ · build ✓ · 565/565 tests ✓.
🤖 Generated with Claude Code
Note
Expose POST action form endpoint in agent-bff
POST /agent/v1/:collection/actions/:action/formroute in action-routes-middleware.ts that loads an action form from the agent, applies submitted values viatryToSetFields, and returns fields,canExecute,requiredFields,skippedFields, and layout.ActionFormto a response object, includingenumValuesonly forEnum-typed fields.decodeSegment,resolveReadModel,requireAgentToken,callAgent) into agent-route-helpers.ts, replacing duplicated logic in the data routes middleware.Macroscope summarized ae6772e.