Skip to main content
Two things are called a form. The dialog that opens when somebody presses New, and a questionnaire that somebody designs inside a running app for other people to fill in. They are built from the same rule: a person is only ever asked for what is theirs to say.

What the create dialog asks

A leave request has fourteen fields. The person asking for the time off fills in four of them. The rest are worked out, stamped, or decided by somebody else — and if the dialog asked for them anyway, it would be asking an employee who approves their own holiday. The compiler works out, per field, who fills it: Two of those have an exception that matters. A field the platform would hide is asked for anyway when it is required and nothing else can fill it — a nomination’s reviewer is the whole record, and a New button that can only say “Reviewer is required” is not a feature. And a command that writes a field beats a guess from its name: confirmed_by looks like a stamp of whoever created the row, but if Confirm sets it to the actor, that is what it is.
owner means “whoever created the record” to the platform. A budget is handed to somebody, so its field is holder; a cost centre has a head. Name the field for what it is, and the dialog does the right thing.

The one you are

A person field the platform would fill in for you but still offers — the owner of anything that appears in a calendar, so HR can file leave on somebody else’s behalf — opens as you. Change it when you are filing for somebody else, and leave it alone otherwise.

Authoring the form

When the rules above are not enough, say what the dialog asks:
views/entities/purchase_request/form.cordango.yaml
An authored form is believed. A field it leaves out is not on the dialog, and a field it names is offered even when a command also collects it — a subscription’s renewal date is typed when the contract is registered and set again by Renew, and both are right. What it cannot do is offer a system, computed or lifecycle field: those are nobody’s to type. Fields the form leaves out are still reachable from the record. A detail section with edit opens the same dialog limited to that slice, which is how HR corrects an approver the employee never saw:
cordango check reports an authored form that leaves out a required field nothing else can fill, and the app stays incomplete until the form offers it: a New button that cannot save is not a feature.

Forms people design

Platform features are currently in invite-only beta. Sign up here to be considered for one of our next phases.
An intake form is a form whose questions are records. Somebody in the vendor team builds “Ask for a tool” for their department; anybody in the company fills it in; a vendor request appears in the team’s queue. Nobody wrote a form in code, and the person filing it never needed the right to create a request. Four entities carry the archetype, named by role: A template says what a submission files with a targetEntity field, and both the template’s own fields and each question can say which field of the filed record they land in with mapsTo:
The compiler and the runtime split the work. The compiler checks the four roles hang together and that every mapsTo names a real field. The runtime stores the response and its answers, projects them into the target record, and links the record back to the submission — one server call, so a submitter needs only the right to create a response, and a failure halfway leaves nothing behind.

The front door

views/screens/request_vendor.cordango.yaml
An intake block lists the forms and runs the one somebody picks. On the filed record, an answers block shows what they said, question by question:

Filling a form in about something

A questionnaire is not always filing something new. A reviewer answering a 360 request, an inspector checking an asset, are filling a form about a record that exists. Put the intake block in that record’s detail and name, with via, the submission’s reference back to it:
views/entities/feedback_request/detail.cordango.yaml
The submission is written pointing at the record the block sits on. The template files nothing on its own — the answers are the point — and a rollup on the request counts them, so the reviewer sees where they are and HR sees who has not answered.

What is not built yet

Row-level permissions. A grant says whether a role reads an entity, not which rows. An employee who may read feedback requests reads all of them; the answers and scores stay unreadable, which is where the anonymity actually lives. Per-row predicates are designed and not built.Reading a core app’s field. A leave request cannot look up the person’s manager in the personnel file, so the app keeps “who approves” on the allowance record HR maintains. A cross-app query is slice Q of the connected runtime plan.