DSL reference
The quick lookup surface: one line and a minimal snippet per construct. For rules, edge cases and worked examples, follow the links into the specification.
| Construct | What it gives you |
|---|---|
entities | tables + CRUD UI + a generated data layer & API |
| field / relation attributes | uniqueness, layout, read-only, dropdown filtering, cascades |
entities.unique | a business key spanning more than one field or to-one relation |
renamedFrom | a field's former name: the stored column is renamed in place, so the values move with the new name |
entities.dropped | former field / to-one relation names whose columns are removed, data included - a field merely deleted from the file keeps its column |
visibleTo | an allow-list of roles that may read one field, enforced on the wire |
pattern | an input-format regular expression enforced in the UI and server-side |
defaultValue | a field default: column default, satisfies required, and seeds a new row in the UI |
dependsOn | link a dropdown to another, copy a value from the referenced record, or default a line from the open document header |
inlineCreate | false keeps a to-one picker to existing rows - no create-from-the-picker |
function | an explicit presentation role (Document, Setting, ...) |
label | a stored, read-only display name for lookups |
label / countryLabels (field) | what a field is called, and the variants the tenant's country resolves |
number | a platform-numbered, gap-free document field |
checks | cross-field / cross-line validations |
checks: severity: warn / duplicate / itemsCompare | a check the person saving confirms instead of a refusal |
checks: kind: guard | a precondition over an aggregate: block, mark for a task, or reject |
immutableWhen / immutable | reject user writes in a status / append-only |
lifecycle | the whole legal status graph, enforced on every status write |
phases | the enrichment moments an entity announces, so a silent write has a channel a consumer can bind |
locksWithMaster | a child collection that stays writable while its master is locked |
history | a shadow, append-only trail of every write: property, old and new value, who, when, user or system |
hierarchy / leafOnly | tree entities, leaf-only references |
| calculated fields | server + UI-evaluated expressions, date helpers, call-outs |
relations / composition | associations and master-detail compositions |
relations / pickable | which target rows a to-one's picker offers: a failing row listed disabled with a message, or left out |
relations / whenMasterDeleted | whether deleting a master deletes the composition children it owns, or is refused while they exist |
uses | reuse entities owned by another intent model |
related | a read-only register of the records referencing this entity, on its own page |
processes | workflows: user tasks, decisions, waits, boundary timers |
| task assignment | route a user task to a role, the record owner, or a relation walk |
abortOn | cancel the running instance when the document reaches a terminal status |
retry / onError | a declared retry cycle and an error route for a calling step, with {error} recording the final attempt's message on the record |
function: Attachment / Snapshot | a Files panel / immutable versioned printed copies |
| a print placeholder's alternative paths | several paths in one placeholder - the first non-blank one is rendered |
forms | task data-entry pages |
actions | developer-defined buttons opening custom pages |
view | an additional calendar / range page, or a slot-booking page |
documentItemsLayout: chat | render a document's items as a chat thread |
reports | aggregations, charts, dashboard KPI tiles, balance and ledger reports, financial and cash-flow statements, user-set parameters |
scope | which lifecycle rows an aggregating report counts |
widgets | custom KPI / embedded-page dashboard tiles |
notify.forEach | fan the block out over a related collection: one message per row, every bare path resolved against the row |
attach: recordPrint | in a fan-out: attach the ANCHOR record's document, rendered once, to every recipient ({record.<field>} addresses that record) |
payload | the declared envelope an outward-facing message carries (integrations and outbound alike), instead of the record as stored |
| the event axis | what a reacting glue entry binds to: an entity lifecycle event, a declared enrichment phase, or a process step reached / completed |
notifications | email on an event of the axis |
| notify link placeholders | {recordUrl} / {inboxUrl} / {appUrl} - a message that carries the way back into the application |
the notify block / attach: print | send a message about a record - with the record's own document attached - from a process step, a transition or a schedule |
fileName | the name a rendered document is stored or attached under - a pattern over the record's own data |
schedules | cron: notify or generate records per matching row; where values may be moments relative to the firing |
integrations | outbound HTTP on a data change |
inbound | records arriving from outside: a webhook, a queue/topic message, a dropped file |
inbound.accept / inbound.map | read an arrival as an envelope: gate on its type and version, map its keys onto the record, resolve a business key to a relation |
inbound.map collections | an envelope array becomes the composition children of the created record, stored with it as one unit |
imports | an uploaded file (CSV with locale rules, MT940, camt.053) read into rows, whole or not at all, refused when it repeats a duplicate key |
outbound | a record emitted on a queue or a topic when an event fires |
exports | a fixed-width, delimited or XML file over an entity or a report, every run recorded on a ledger entity |
rollups | counts, sums, balance + status maintenance |
settlements | auto-allocation of payments across open invoices |
expansions | generated child rows per day / week / month |
generates | one-click document-from-document cloning |
generates.items.where | which of the source document's rows become target lines - and what an unqualified one costs |
generates.prompt / generates.link | ask for what the source cannot supply (defaults read off the source), and write the source's link row to the new target in the same unit |
generates.event | mint the document on a source event - a status write, a create, or a process step |
generates.event.mode | one target per source (once, default) or one per delivered event (append) |
reversals | a manual Reverse on a posted document - its negated twin, linked both ways |
resolves | fill a to-one from the register row valid on the record's date |
transitions | guarded on-demand status flips (void / cancel / reopen) |
postings | declarative source-document to balanced-document posting - on a status transition, on create for a lifecycle-less source, or on a declared enrichment phase |
aggregates | keyed cross-entity totals materialised into their own entity |
posts | derived ledger rows emitted idempotently on an event |
personal / partner | per-user and per-partner row-scoped surfaces |
seeds | initial data, CSV-backed sets, translations |
multilingual / languages | translation tables + read-time translation overlay, on entity reads and report columns alike |
translatable: false | keeps a key of a multilingual entity out of the translation table, so what a rule matches on cannot be translated out from under it |
permissions | roles |
Snippets
entities
yaml
entities:
- name: Member
icon: user
group: master-data
audit: true
fields:
- { name: id, type: integer, primaryKey: true, generated: true }
- { name: name, type: string, required: true, length: 200 }
relations:
- { name: loans, kind: oneToMany, to: Loan }field / relation attributes
yaml
- { name: code, type: string, unique: true, length: 30 }
- { name: total, type: decimal, precision: 18, scale: 2, readOnly: true }
- { name: period, type: month }
- { name: Number, type: string, number: { series: Sales Invoice, per: Company, stampOn: create } }
- { name: Status, kind: manyToOne, to: OrderStatus, function: EntityStatus, init: 1 }
- { name: City, kind: manyToOne, to: City, dependsOn: { relation: Country, filterBy: Country } }
- { name: Product, kind: manyToOne, to: Product, where: { Type: 1 } }
- { name: Customer, kind: manyToOne, to: Customer, pickable: { when: [registrationNumber != null, address != null], message: "Registration data incomplete" } }
- { name: tags, kind: manyToMany, to: Tag, through: OrderTag } # link entity, namedfunction
yaml
- name: ProjectTimesheet
function: Document # header + line items + status pill + totals
- name: EmployeeTimesheet
function: DocumentItemchecks
yaml
- name: JournalEntry
checks:
- { kind: itemsMin, count: 1, status: 2, message: "An entry needs at least one line" }
- { kind: itemsSumEqual, over: [debit, credit], status: 2, message: "Debits must equal credits" }
- name: JournalEntryItem
checks:
- { kind: exactlyOne, fields: [debit, credit], message: "Exactly one of debit / credit" }
- name: SalesInvoice
checks:
- { kind: compare, field: due, op: ge, than: date, message: "Due cannot be before the invoice date" }
- { kind: requiredWhen, field: Customer.email, when: "sentMethod == 1", status: SENT,
message: "Sent Method is E-mail but the customer has no e-mail address" }processes
yaml
processes:
- name: OrderApproval
trigger: { onCreate: Order }
steps:
- { name: review, kind: userTask, args: { assignee: manager, form: ApproveOrder } }
- { name: decide, kind: decision, args: { if: "action == 'approve'", then: activate, else: cancel } }
- { name: activate, kind: serviceTask, args: { setRelationField: Status, value: 2, next: end } }
- { name: cancel, kind: serviceTask, args: { setRelationField: Status, value: 3, next: end } }
- { name: end, kind: end }A calling step (a delegate: handler or a notify: send) may declare what happens when the call fails:
yaml
- name: notifyOwner
kind: serviceTask
args:
notify: { to: owner.email, subject: "...", body: "..." }
retry: { count: 3, every: PT30S } # three FURTHER attempts, 30s apart
onError: recordFailure # the exhausted failure routes here
next: provisioned
- { name: recordFailure, kind: serviceTask, args: { setField: failureMessage, value: "{error}", next: failed } }reports
yaml
reports:
- name: OrdersByMonth
source: Order
dimensions: ["month(orderDate)"]
measures: ["count(*)", "sum(total)"]
filter: "total > 0"
scope: live # all | draft | live | cancelled | void
parameters: # user-set inputs bound into the WHERE
- { name: fromDate, target: orderDate, op: ge }
- { name: minTotal, target: total, op: ge, initial: "0" }
chart: bar
widget: { value: "sum(total)", at: { "month(orderDate)": now }, label: Revenue (this month) }generates / transitions / reversals
yaml
generates:
- { name: invoice-from-order, from: Order, to: Invoice, map: { Customer: Customer }, sourceStatus: 3 }
# ...or minted with no click at all, at most once per source:
- name: delivery-from-order
from: Order
to: Delivery
event: { onTransition: Order, when: "Status == CONFIRMED" }
map: { Order: id }
transitions:
- { name: VoidInvoice, forEntity: Invoice, from: [ISSUED, SENT], setStatus: VOIDED, when: "Paid == 0", label: Void, icon: ban }
reversals:
- { name: reverseEntry, forEntity: JournalEntry, when: "Status == POSTED", link: Storno, backLink: ReversedBy, negate: [debit, credit] }seeds
yaml
seeds:
- name: statuses
entity: OrderStatus
rows:
- { id: 1, name: DRAFT, stage: draft }
- { id: 2, name: POSTED, stage: live }
- name: countries
entity: Country
file: data/countries.csvPlanned — recognised but not yet implemented
The following are parsed (or reserved) but not yet materialised by a generator; a conforming tool rejects or ignores them with a clear message rather than failing obscurely:
- Reserved
functionvalues for upcoming presentations (Board,Gantt,Timeline). - Cross-model status names and stage scopes — a nomenclature owned by another model is seeded there, so its stages and names cannot be resolved from the referencing file; such references are rejected with the numeric-id fallback named.
- Bridge fields on a generated
manyToManylink — the materialised link entity carries only its key and the two foreign keys; a link with data of its own is authored as an explicit intermediate entity.