Skip to content

Model a domain

A Nomos domain declares four things:

  1. Aggregates — business things with one continuing identity.
  2. Birth — the facts required to give a root aggregate its durable life.
  3. Private directives — consequences Nomos may apply after admission.
  4. Public intents — the business verbs applications and people use.

The starter’s public intent coordinates two private consequences atomically:

export const commissionAsset = intent("commissionAsset")
.payload(z.object({
name: z.string().min(1),
rfidQrIdentity: z.string().min(1),
}))
.directs(createCommissionedAsset, ({ name }) => ({ name }))
.directs(claimRfidQrIdentity, ({ rfidQrIdentity }) => ({ value: rfidQrIdentity }))
.atomically();
export const estateLanguage = language("estate", [commissionAsset]);

Application developers see commissionAsset. They do not need to know which aggregates or private directives implement it. That separation lets the domain evolve without turning the UI into a second model.

Prefer a small business verb over a bag-of-fields update method. commissionAsset(...) states a durable business event; updateEstate(Map values) merely moves unvalidated bits and forces every caller to learn the aggregate’s internals.