Demo guide / Schema

Define types once.
Create atoms of those types.

Records and relationships are both atoms. Types say what those atoms mean. Define a type in Schema, then create instances in Data. Form, JSON, and the local engine operation are the same write.

Three different things

LayerWhat it meansExample
Atom classThe engine’s structural categoryOBJECT or RELATION
User-defined typeNamed fields, roles, and constraintscommerce.Customer, commerce.Subscription
AtomOne stored instance with its own identityNorthwind Labs, or that customer’s Checkout subscription

Record is the console label for an Object type. Relationship is the label for a Relation type. Creating a Customer type does not add a Customer class to the engine.

Schema → Create type → Record

Open Schema in the demo workspace, then Create type → Record. The editor accepts a type name, collection label, namespace, display field, and typed fields. Supported field types are text (string), number, and boolean, with optional allowed values. Uniqueness is a catalog constraint enforced on save, not a check of the currently painted table.

Customer type declaration
{
  "name": "Customer",
  "atomClass": "OBJECT",
  "namespace": "commerce",
  "display": {
    "singular": "Customer",
    "plural": "Customers",
    "labelField": "name"
  },
  "fields": {
    "customer_number": { "type": "string", "required": true },
    "name": { "type": "string", "required": true },
    "active": { "type": "boolean", "required": true }
  },
  "constraints": [
    {
      "kind": "unique",
      "fields": ["customer_number"],
      "scope": "database-and-type"
    }
  ],
  "unknownFields": "reject"
}

Accepting this type creates no records. The metadata names id, type, sourceId, atomClass, and typeId are reserved and cannot be field names. Fields not present in the type are rejected. The JSON tab submits the same catalog operation as the form. This is the local reference engine, not a hosted schema API.

Data → create an atom

Once a type is accepted, open Data and choose New Customer (or New atom, then the type). The form is generated from the catalog. The engine allocates atom identity. Two customers with the same display name stay distinct. Pickers show a label and keep the selected atom id.

Schema → Create type → Relationship

A subscription is one Relationship atom with three named roles: customer, product, and plan. That keeps which plan belongs to which product subscription. Splitting it into unrelated pairwise facts can lose that association.

Subscription type declaration
{
  "name": "Subscription",
  "atomClass": "RELATION",
  "namespace": "commerce",
  "roles": {
    "customer": "Customer",
    "product": "Product",
    "plan": "Plan"
  },
  "fields": {
    "status": {
      "type": "string",
      "required": true,
      "enum": ["active", "paused", "cancelled"]
    }
  },
  "unknownFields": "reject"
}

Every relationship instance must contain exactly those roles. Each participant must exist and match the allowed type. A role may target another relationship type when that is useful, for example attaching a contract document to a particular Subscription atom. The sample also includes two-participant types such as account_owner and depends_on.

The visual builder treats the first role as the start of each forward route to the other roles. Queries may traverse those routes backwards by choosing the inverse direction.

Routes have direction

For a subscription, customer → product is a forward route. Its inverse goes from the product to the customer. A route does not mean every participant can reach every other participant in one hop, and it does not let a query jump between unrelated subscriptions that happen to share a plan.

Use participant filters when a condition belongs to the same relationship. For example, constrain the plan participant to Enterprise while traversing that subscription’s customer-to-product route. The query reference shows the exact syntax.

Changing a type

Use Revise type on a Schema card. That creates a new schema revision. Type identity is preserved; existing atoms are not duplicated. Adding an optional field does not require values on existing records. Making a field required refuses until those atoms already satisfy the rule. Historical snapshots keep the schema that interpreted them.

Validated changes

Each accepted schema change, import, or atom write checks the full candidate before recording it. Invalid field values, unknown types, missing participants, uniqueness conflicts, and duplicate identifiers leave the previous state unchanged.

A record with existing relationships cannot be deleted until those relationships are removed. Removing a relationship does not delete its participants. Relationship fields declared on the type are validated the same way as record fields.

Schema validation establishes the structural rules you define. It does not grant access, verify whether a source is true, or publish a production API. A type named Administrator does not change authorization.
← Getting startedQuery reference →