Skip to main content

Collections

A collection is a named, typed set of records. Collections are the data store for the domain — every write in the system targets a collection, and every projection reads from one.

Defining fields

Fields are declared with a name and a type. The ! suffix marks a field as required.

domain:
collections:
messages:
fields:
id: id!
text: text!
user_id: id!
channel: text
created_at: timestamp!

Available field types:

TypeDescription
idUnique identifier
textUTF-8 string
intInteger
floatFloating-point number
boolBoolean
timestampISO 8601 datetime
objectNested key-value object

A field declared without ! is optional and may be null.

Invariants

Invariants are structural rules enforced at every write. A write that violates any declared invariant is rejected before it reaches the database.

domain:
collections:
messages:
fields:
id: id!
text: text!
created_at: timestamp!
invariants:
on_fail: abort
structural:
- description: "Message text must not be empty."
rule:
"!==":
- var: text
- ""

on_fail: abort is the only supported mode. Invariants are hard constraints — there is no soft-fail path. If an action step produces a write that would violate an invariant, the entire action is aborted.

Invariant rules use the $expr DSL. The var operator references a field by name on the record being written.

Nested object fields

The object type supports nested structure. Nested fields are declared inline.

domain:
collections:
hello_messages:
fields:
id: id!
moderation:
object:
status: text!
checked_at: timestamp
flagged_reason: text

Object fields are accessed in $expr using dot paths: var: moderation.status.

What writes to collections

Only actions write to collections, via the collections.write provider capability. Projections, flows, and domain capabilities are all read-only. This is enforced at compilation — a projection or flow that references collections.write is a compilation error.

What reads from collections

Projections read from collections via the runtime. The specific scan, filter, and join operations a projection performs are declared in its strategy, not in the collection definition.

What's next

  • Actions: the only writers to collections
  • Projections: reading and deriving views from collections