# FlowDropSchema

FlowDropSchema is the **documented subset of JSON Schema (Draft 2020-12)** that FlowDrop uses internally to describe interrupt payloads, typed workflow I/O, and node configuration forms. It is rendered to Drupal Form API by `FlowDropSchemaFormBuilder` (`@api`).

It is intentionally a **subset**, not a full JSON Schema implementation. If you need keywords outside this list, validate them yourself in your node processor or interrupt handler — `FlowDropSchemaFormBuilder` will render the unrecognised subtree as a JSON textarea fallback and will not validate the missing constraints.

## Supported keywords

### Type

- `type`: one of `string`, `integer`, `number`, `boolean`, `array`, `object`.
  - A list (e.g. `["string", "null"]`) is also accepted; the first non-`null` member wins.
  - Default when `type` is missing: `string`.

### Common metadata

- `title` — used as the form element label.
- `description` — used as the form element description.
- `default` — pre-fills the form element when no value is supplied.

### Enum

- `enum` (string-only members in practice) — rendered as:
  - Radios when ≤10 options.
  - Select when >10 options.
- On arrays with `items.enum`, rendered as a checkbox group.

### Strings

- `format`: `multiline`, `date`, `date-time`, `email`, `uri`, `url`. Anything else falls back to a textfield.
- `minLength`, `maxLength` — validated.
- `pattern` — validated as a PCRE regex with these limits:
  - Patterns >512 characters are treated as opaque (no validation).
  - Patterns containing an unescaped `#` are treated as opaque.
  - The PHP `pcre.backtrack_limit` provides a backstop against catastrophic backtracking, but pattern authoring is still a trusted-input surface.

### Numbers

- `minimum`, `maximum` — validated.
- `integer` type adds `#step` = 1 to the form element.

### Objects

- `properties` — rendered as a nested fieldset, recursing into each property.
- `required` — used to mark child elements `#required`; also used by the validator to flag missing properties.
- Objects without `properties` (free-form objects) render as a JSON textarea.
- Maximum recursion depth is **12 levels**; deeper schemas render an "Schema too deeply nested" notice instead of an infinite loop.

### Arrays

- `items.enum` (array of strings) — rendered as a checkbox group.
- All other arrays — rendered as a JSON textarea. (Per-item subforms are not currently supported.)

### Presentation hints

- `presentation: confirmation` (on `type: boolean`) — `SchemaFormHandler` swaps the rendered checkbox for a confirm/decline button pair. This is the only FlowDrop-specific hint at the schema level.
- `confirmLabel`, `declineLabel` — used with `presentation: confirmation`.

## NOT supported

These JSON Schema keywords have no effect when consumed by `FlowDropSchemaFormBuilder`:

- Composition: `oneOf`, `anyOf`, `allOf`, `not`, `if`/`then`/`else`.
- References: `$ref`, `$defs`, `$id`, `$anchor`.
- Object extras: `additionalProperties`, `patternProperties`, `propertyNames`, `dependencies`, `dependentRequired`, `dependentSchemas`.
- String extras: `format` values other than the six listed above (no `uuid`, `ipv4`, etc.).
- Array extras: `uniqueItems`, `minItems`, `maxItems`, `contains`, `prefixItems`.
- Value: `const`, `multipleOf`, `exclusiveMinimum`, `exclusiveMaximum`.
- Annotations: `examples`, `readOnly`, `writeOnly`, `deprecated`.

A schema using any of these will still **load** — `FlowDropSchemaFormBuilder` simply ignores the unsupported keys and renders what it can. Where the unsupported keyword would change the rendered widget (e.g. `oneOf` to pick between two object shapes), the result will be a free-form JSON textarea.

## Stability

The FlowDropSchema keyword set is `@api` from 1.4.0:

- Keywords listed under **Supported** will continue to work in the 1.x line.
- New keywords may be added in minor releases.
- Keywords listed under **NOT supported** may be added in minor releases — when they are, their rendering / validation behaviour becomes part of the supported set and won't be removed without a major version bump.

If you want a feature added to the subset, open an issue with a concrete schema example and the form rendering you'd expect.

## Why a subset

A full JSON Schema implementation is a large, fiddly thing — composition, recursion, draft-version differences, format vocabularies. Rather than reimplement that here, FlowDrop ships a small, predictable subset that covers the shapes our HITL and typed-I/O surfaces actually need. If you require full JSON Schema validation outside of form rendering, use a dedicated library (e.g. `opis/json-schema`) in your own code.
