What an App reads from a Noun: depth
Representation, field types, relationships, lifecycle states and Events: what an App draws from each fact a Noun declares, traced through one Lease.
An API needs a Noun's types to check a call, and nothing more. An App reads more from the same file: the field that names a record, the field order, each reference, and the Verbs that move it.
One Noun, traced to its screens
leaseclock.com tracks lease renewal dates for small property managers. Its Startup declares two Nouns, Property and Lease, and the Admin reads every fact below from those two files.
---
extends: [Thing]
properties:
residentName: string
residentEmail?: email
listingUrl?: url
startsOn: date
endsOn: date
monthlyRent: number
status: active | renewed | terminated
notes?: text
terms?: json
documents?: string[]
property: Property
verbs:
renew: {}
terminate: {}
---
A Lease is one resident's agreement on one unit of a Property, from signing to renewal.---
properties:
name: string
address?: string
units: integer
---
A Property is one building a manager rents out, unit by unit.| Fact in the file | The API reads it as | The Admin draws from it | Rule |
|---|---|---|---|
The Noun's name, Lease | the route /leases and the type Lease | the key leases, the labels Lease and Leases | key, labels |
The first one-line text field, residentName | a property like any other | the record's name: the page title, every reference cell, every picker choice | representation |
| The order of the properties | nothing | the order of the list columns, at most 7 | list-columns |
Each property's name, such as monthlyRent | the JSON key | the label Monthly Rent | labels |
| Each property's type | the check on every write | the control in each screen | Field kinds and their controls |
A ? on a name | an optional input | a form input that accepts an empty value | required-input |
property: Property | the id of a Property | the Property by its name, linked, and a picker | reference-forward |
status: active | renewed | terminated | the lifecycle, moved by Verbs | a text column and a text box | control-text |
renew: {}, terminate: {} | two routes, each returning an Action | two buttons on each row, the record page and the edit form | verb-action |
Representation: the field that names a record
Every record shows somewhere as one short string: a page title, a cell that points at it, a choice in a picker. The Admin takes the first of name, title, label, email and slug that holds one line of text. Failing those, it takes the first one-line text field, then the id.
Property has name, so a lease's property cell reads 14 Elm Street. Lease has none of the five, so residentName names it: Maya Ortiz. Without one of those five names, the first one-line field wins, so the declared order picks the name.
PlanChoosing the name by hand
In the design, a Noun file names its representation field directly, overriding the guess. Its rule, representation-override, waits for code that serves it.
Fields and relationships
The API ignores the order of properties. The Admin keeps it: the list shows the first 7 short fields in declared order, properties before references. Lease declares 7 short properties before property, so the list leaves property out and the record page shows it.
A property typed with another Noun is a forward reference. The record page and the list show the referenced record by its name and link to it, and the forms offer a picker that searches. The forms never require a reference, even one declared without ?.
| Relationship | Declared in a Noun file | In the Admin |
|---|---|---|
Lease points at one Property | property: Property on Lease | the Property by its name, linked; a searching picker in the forms |
Property holds many Lease records | no key | nothing on the Property record page |
PlanThe other end of a relationship
In the design, the Property record page lists its leases, by each lease's name and its next short fields. Its rule, related-list, waits: no Noun-file key declares the other end of a relationship.
Lifecycle states
status: active | renewed | terminated lists the lifecycle in order. create starts every lease at active, and only a Verb moves it. The Admin shows status as text in the list and on the record page.
The create and edit forms offer status as a one-line text box. The hub's Noun-file rule says no create or update input takes it.
PlanStates moved only by Verbs
In the design, the forms leave status out, and a Verb button is the only way to change it. Its rule, state-moves-by-verb, waits. So does blocked-action, which removes a screen or the delete button for a blocked standard Verb: no Noun-file key blocks one.
Verbs and Events
Each Verb beyond create, get, list, update and delete becomes a button labeled from its name: renew reads Renew. The button runs the Verb on its record, and the Verb's rules decide.
A completed call shows a notice and reloads the record (verb-result). A refused one shows the Verb's reason and leaves the screen as it was (refusal-message).
Each completed Verb also records an Event, such as Lease.renewed. No printed rule draws a screen part from an Event: the reload after a Verb shows what it changed. A Verb's declared inputs are the subject of Verb inputs: what a form needs.
Publish my App
Say "publish my app" and your App goes out on your own Domain, every Customer runs the newest build, and the last build stays ready to restore.
Field kinds and their controls
Every field type a Noun file takes, with its control in the Admin's list, record page and forms, and its JSON and Markdown renderings.