From c64479e73dd8d255ace753358387ceaea41b8780 Mon Sep 17 00:00:00 2001 From: delchev Date: Mon, 7 Sep 2026 14:44:44 +0300 Subject: [PATCH] forms: a relation.field may cross models State what the forms section left open: the one-hop hop may reach an entity another module owns, which is what lets a document's form show a field of its counterparty (an invoice's Send form showing the customer's address). Same one-hop path a notify recipient takes, checked against the owner's model at generation, and a field the owner does not declare must be reported rather than leaving a control bound to nothing. Co-Authored-By: Claude Opus 5 --- docs/spec/processes.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/spec/processes.md b/docs/spec/processes.md index b0cec9f..443f99b 100644 --- a/docs/spec/processes.md +++ b/docs/spec/processes.md @@ -171,6 +171,10 @@ forms: Generates one form per `forms[]` entry. Controls are typed by looking each field up against the bound entity (string to a text input, integer / decimal to a number input, boolean to a checkbox, date to a date picker, and so on). Actions become buttons, coloured by name (approve to positive; reject / decline / delete / cancel to negative; save / submit to emphasised). +A `relation.field` entry reads a field of a one-hop to-one relation, read-only — the related record is loaded *for* the form rather than typed into it. The relation may be **cross-model**, which is what lets a document's form show a field of the entity another module owns: an invoice's Send form showing the customer's address, so the clerk sees an empty one before pressing Send. It is the same one-hop path a [notify](/spec/glue#notifications) recipient takes; the relation's `model:` must be declared in [`uses`](/spec/relations#reuse-dont-redefine--uses), and the referenced field is checked against the **owner's** model when the application is generated. + +A conforming generator MUST report a field the owner model does not declare rather than dropping the control: a control bound to a value nothing ever provides looks exactly like a record that has no value. + ## actions — custom buttons Developer-defined buttons that open a custom page — the escape hatch when a workflow or a generated screen is not enough: