# Issue 979 Action-Backed Create Route

Status: implementation design for the remaining generic create-screen bridge

## Problem

Issue #979 now has the backend Flow-owned create preview, action dispatch,
field mapping, synthetic preview lookup, child fan-out, rollback, and pack
authoring guidance in place. The remaining generic frontend gap is narrower:
the normal `ObjectView` create route still saves through direct SObject create.
That is correct for ordinary "New Record" and clone flows, but not for
metadata-defined create-from-source actions whose copied, inherited, or child
fan-out behavior is owned by a standard action Flow.

For those actions, preview and Save must share `_System_StandardAction`,
`_System_ActionSchema`, `_System_ObjectFieldMapping`, action defaults, guards,
and Flow execution. URL prefill compatibility cannot be promoted into the
authoritative path because direct SObject create would skip the action Flow and
could trust client-stamped values that the server must recompute.

## Current Evidence

- `POST /services/data/v63.0/actions/standard/{name}/preview` returns
  no-DML parent and child create images through the standard-action dispatcher.
- `GET /services/data/v63.0/actions/standard` exposes `previewEndpoint` and
  field-bound `_System_ActionSchema` metadata including `uiMode`,
  `targetObject`, `targetFieldAPIName`, `prefillSourceFieldAPIName`, defaults,
  and input guard summaries.
- `MetadataRecordForm` already renders only createable fields for create mode,
  filters read-only fields on submit, and can carry hidden create defaults.
- `ObjectView` currently combines UI API create defaults, clone defaults, and
  URL parameters into `initialData`, then calls direct `dataAPI.createRecord`.
- App-pack renderers such as Lead Convert can consume `previewEndpoint`
  directly, but that does not give every metadata-defined create-from-source
  action a generic create-screen path.

## Design Goals

- Keep the server action/Flow path as the source of truth for final Save.
- Use only metadata-owned field bindings from `_System_ActionSchema`.
- Let the normal target object create layout render editable fields.
- Show preview failures before Save and block action-backed Save when the
  preview contract fails.
- Preserve ordinary direct-create behavior for non-action create pages.
- Fail closed for ambiguous or unsupported action shapes.

## Route Contract

The generic entry point is the existing target create route:

```text
/object/:targetObject/new?actionName=<standardActionName>&sourceObject=<object>&sourceRecordId=<id>
```

The route parameters are context selectors, not field values. `ObjectView`
must not treat them as authoritative target-field prefill data.

On load, `ObjectView` resolves the named standard action from
`GET /actions/standard` and validates:

- the action has an `endpoint` and `previewEndpoint`;
- the source object is in `action.targetObjects`;
- exactly one route target object can be derived from create-mode action schema
  rows or the preview parent image;
- any hidden input needed for source context can be derived from
  `prefillSourceFieldAPIName` or an explicit `targetFieldAPIName=Id` binding;
- every editable create-layout field that will be submitted through the action
  has a matching `uiMode=create`, `targetObject`, `targetFieldAPIName` action
  input.

If any of those checks fail, the page renders a normal error state instead of
falling back to URL prefill or direct create.

## Preview Contract

For action-backed create pages, `ObjectView` calls `previewEndpoint` with the
metadata-derived hidden/source inputs and any current create-field values whose
action inputs are known. Initial preview may omit user-entered create values;
the endpoint already skips required-input validation for preview while still
rejecting unknown inputs and unsupported preview shapes.

The parent preview field map is merged into create defaults before rendering
the form. Field editability remains controlled by describe/layout metadata:

- createable layout fields render as editable controls;
- hidden createable fields may be carried only when they came from metadata
  action bindings or server defaults;
- non-createable or server-owned preview fields may be shown as read-only
  summary data, but are not submitted as direct field payload.

Child preview is summary-first: object label, count, and optional row samples
after server-side read/FLS projection. Synthetic `preview-*` IDs are never
shown as durable record IDs.

Preview errors are visible above the form and disable Save for the
action-backed route. Ordinary direct-create pages keep their existing default
and validation behavior.

## Save Contract

`MetadataRecordForm` needs an async create override for action-backed routes.
The override receives the cleaned create payload that the form would otherwise
send to direct SObject create. `ObjectView` converts that payload into action
inputs using `_System_ActionSchema`:

- hidden/source inputs come from the source record and action defaults;
- create-field inputs are mapped by `(targetObject, targetFieldAPIName)` to
  input API names;
- denied guarded inputs are omitted unless the server has an allowed default;
- unknown form fields are not sent to the action.

Save calls `dataAPI.executeStandardAction(action.endpoint, [input])`. It does
not call `dataAPI.createRecord` for action-backed create pages.

After success, `ObjectView` navigates to the first output whose `referenceTo`
matches the target object and has a returned record id. If no such output is
declared, it returns to the target list with a success message rather than
inventing an id.

The server remains authoritative: even if an editable previewed value is sent
as an action input, the Flow/action path recomputes server-owned copied and
inherited values and owns child fan-out transaction semantics.

## Fail-Closed Cases

The generic route must refuse to render an action-backed create form when:

- no `previewEndpoint` is advertised;
- the preview parent object conflicts with the route target object;
- multiple target objects are equally plausible for parent create fields;
- a required non-defaulted action input has no generic renderer or source
  binding;
- a form field would need to be submitted but lacks a target-field action input;
- action input guards deny a path that the page would otherwise render;
- preview returns `isSuccess=false` or throws an unsupported-shape error.

These failures should tell the admin/author what metadata is missing. They
must not silently downgrade to direct SObject create.

## Compatibility Boundaries

Legacy `NavigateToNewRecord` URL prefill remains compatibility behavior for
old layout actions. It is not the #979 action-backed create contract.

App-pack renderers such as Lead Convert may keep bespoke UI when the workflow
needs richer mode controls. They still use the same `previewEndpoint` and
`executeStandardAction` server paths; the generic route is the fallback for
metadata-defined create-from-source actions that fit the field-bound schema.

The #945 `config.*Preview` producer issue is adjacent but separate. It produces
arbitrary renderer config payloads. This design covers record-create preview
images and action-backed Save for #979.

## Implementation Plan

1. Add a small `standardActionCreateRoute` helper module that derives source
   inputs, target field mappings, blocked guarded inputs, and submit payloads
   from `StandardAction` metadata.
2. Extend `MetadataRecordForm` with an async create override, preserving direct
   SObject create as the default.
3. Teach `ObjectView` to detect the action-backed route query parameters, load
   the source record, call `previewEndpoint`, merge parent preview fields into
   create defaults, render child/read-only summary data, and block Save on
   preview errors.
4. On action-backed Save, execute the standard action and navigate by declared
   output reference.
5. Add frontend unit coverage for helper fail-closed behavior, preview
   hydration, direct-create preservation, and action-backed Save not calling
   `createRecord`.

## Review Checklist

- No source or target object names hardcoded in platform frontend code.
- No frontend field-copy table or URL-param authoritative mapping.
- Preview and Save read the same standard action metadata.
- Direct create and clone behavior remain unchanged when no action route
  context is present.
- Unsupported metadata shapes fail closed with visible errors.
- Tests use synthetic object/action names.
