Skip to main content

Class & attribute options

The class document

{
"_id": "Task",
"~class": "class",
"name": "Task",
"description": "A unit of work",
"parentClass": "Item",
"schema": { "title": { "name": "title", "type": "string", "config": { "mandatory": true } } },
"triggers": [],
"simple": false,
"ephemeral": false,
"tenants": ["workspace"]
}
FieldTypeMeaning
_idstringThe class id. Class.create uses the name. Replication filters and internalDocs.extraDocIds address the class by this id.
~class"class"The document type. "~self" is reserved for the bootstrap class model.
namestringThe class name used in SQL, selectors, hooks and getClass.
descriptionstring, optionalFor humans and the workbench.
parentClassstring, optionalThe id of a parent class; the workbench and validation use it to relate classes.
schemamap of attribute modelsAttribute name to { name, type, config, description? }.
triggersarrayTrigger models; see Trigger and job document models.
simpleboolean, optionalDocuments stored as given: no validation, triggers, relation checks or encryption. Cannot encrypt a field.
ephemeralboolean, optionalDocuments purged when the stack next opens; never replicated.
tenantsstring[], optionalThe tenant spaces this class belongs to. A tenant is a stack. Static on purpose, so replication scoping can be derived before any data exists.
defaultScopestring, optionalThe access scope documents of this class seal under when they state no ~scope of their own. See Scope your data.

Class.create

Class.create(stack, name, type, description?, schema?)
ParameterTypeNotes
stackClientStackThe stack the class lives in.
namestringBecomes name and _id.
type"class"The document type.
descriptionstringOptional.
schemamap of attribute modelsOptional; attributes can be added afterwards with Attribute.create.

Related: Class.fetch(stack, className, options?) and stack.getClass(name, fresh?) load an existing class with a live subscription; stack.getClassSnapshot(name) loads it without one; Class.buildFromModel(stack, model, { subscribe: false }) builds a detached class from a model.

Attribute.create

Attribute.create(classObj, name, type, description?, config?)

Writes the attribute into the class document and rebuilds the class's validator. The same shape, { name, type, config, description? }, is what schema holds in a class document or a patch.

Attribute types

TypeZod validatorType-specific configuration
stringz.string()maxLength
integerz.number()min, max
decimalz.number() with a precision refinementmin, max, precision (maximum decimal places)
booleanz.boolean()
datestored as givenformat, min, max
enumz.enum(values)values: a non-empty array of { value }
objectz.object({})
foreign_keyz.string() with an async existence checktargetClass: the class the referenced document must belong to
referencebound to a domaindomain: the domain name. Cannot be an array.

Where a reference attribute may live follows from the domain's cardinality: on the target class of a 1:N domain, on the source class of an N:1 domain, on either side of a 1:1 domain, and nowhere for N:N. Attribute.create refuses the rest.

Configuration keys every type accepts

KeyTypeEffect
mandatorybooleanA write without the attribute is refused. Otherwise the attribute is optional and may be null.
defaultValuethe attribute's typeStamped when the attribute is absent from a write. Also stamped onto existing documents when the attribute is added to a class they belong to.
isArraybooleanThe attribute holds an array of the type. foreign_key arrays check every id.
primaryKeybooleanPart of the class's natural key. addOrUpdateCard(params) and getByPrimaryKeys(params) look documents up by every primary-key attribute together, and uniqueCheck refuses a duplicate.
encryptedbooleanStored as an AES-GCM payload under the stack's document key; see Encrypt fields.

Validation runs asynchronously against the hydrated Zod schema (classObj.schemaZOD), because a foreign_key field's existence check reads the database. A non-mandatory attribute accepts null as well as absence: undefined does not survive JSON, so null is how a client clears a stored field.

Domain.create

Domain.create(stack, id, name, type, relation, sourceClass, targetClass, description?)
ParameterTypeNotes
idstring or nullnull mints one.
namestringThe domain name used by reference attributes and useDomain.
type"domain"The document type.
relation"1:1", "1:N", "N:1", "N:N"Cardinality, enforced on addRelation.
sourceClass, targetClassClassThe two ends.

A relation document carries ~domain (the domain name) instead of ~class, plus sourceClass, targetClass, sourceId and targetId. domain.addRelation(document, referenceId), getRelations(selector?, fields?, skip?, limit?), deleteRelation(sourceId, targetId) and validateRelation(document, referenceId) are the domain's methods.

Document fields

Every document written through the pipeline carries:

FieldSet by
_idRandom with a class prefix (Task-x7f3k2m9q1w4) unless you pass one to stack.createDoc.
_revPouchDB.
~classThe class name.
~createTimestampOn creation.
~updateTimestampOn update.
activetrue on creation; false after deleteCard or deleteDocument. Reads honour it by default.
~scopeOptional, set by you. The access scope the document's encrypted attributes seal under; overrides the class's defaultScope.

The generated API reference lists every method of Class, Attribute and Domain with its signature.