Mechanical enforcement of input-schema invariants — every "just don't do X" rule that is detectable gets detected and raised, upgrading conventions to invariants.
The runner invokes assert_valid_input_schema!/2 automatically on an
action's first run (memoized per action). The memoization lives in
:persistent_term and survives dev code reloads, so editing an input
schema in a running server does not re-trigger the check until restart —
another reason host apps should also call it from a CI test on every
action's input module for compile-adjacent feedback:
for action <- MyApp.Actions.all(), input = action.input() do
Enact.Guardrails.assert_valid_input_schema!(input,
mode: Keyword.get(action.config(), :mode, :create)
)
end
Summary
Functions
Walks an input module recursively (through its embeds, with a cycle guard for self-referential schemas) and raises a teaching error on
Functions
Walks an input module recursively (through its embeds, with a cycle guard for self-referential schemas) and raises a teaching error on:
- any scalar field with a non-nil default (embed fields excluded —
their structural
[]/nildefaults are fine) - a primary key at any level
- associations at any level — embeds only
- top-level module only: missing
changeset/3orfields/1exports, or missingfrom_subject/1whenmode: :patchis given (nested item modules are exempt — they implementchangeset/2forcast_embed)
Options: :mode — the referencing action's mode; :patch requires
from_subject/1.