Lists, Enums & Virtual Properties
Lists
An entity type can declare ordered sub-entity collections via has_list. This allows grouping child entities directly inside a parent entity's representation.
Declaring a List
Each has_list relationship instance carries:
| Field | Type | Required | Description |
|---|---|---|---|
name | system_name | yes | Identifier for the list |
label | localized map | yes | Display name |
description | localized map | no | Description |
The target of the relationship is the entity type whose instances populate the list.
"has_list": [
{
"properties": {
"name": "ingredients",
"label": { "en_us": "Ingredients" }
},
"target": "entity_type/ingredient_item"
}
]
Wire Format
In entity responses, list contents appear under the lists field:
{
"lists": {
"ingredients": [
{
"id": "<uuid>",
"type_id": "<uuid>",
"root_id": "<uuid>",
"@key": "flour",
"properties": { "name": "Flour", "amount": 500 }
},
{
"id": "<uuid>",
"type_id": "<uuid>",
"root_id": "<uuid>",
"@key": "sugar",
"properties": { "name": "Sugar", "amount": 200 }
}
]
}
}
When creating or updating an entity, list items can be supplied inline:
{
"lists": {
"ingredients": [
{ "key": "flour", "properties": { "name": "Flour", "amount": 500 } },
{ "key": "sugar", "properties": { "name": "Sugar", "amount": 200 } }
]
}
}
List Item Key Spaces
List item keys are scoped to a sub key space tied to (list-item type, owner entity). A list item keyed step1 under procedure/A does not collide with step1 under procedure/B. See Key Spaces for the full model.
Enums
The system supports enum types for defining a fixed set of named values. Enums are implemented as entities, which means they are versioned, queryable, and can be extended without breaking existing data.
The enums Entity
An enum definition:
| Field | Description |
|---|---|
name | System identifier (key) |
label | Localized display name |
description | Localized description |
The enum_entry Entity
An individual value within an enum. Enum entries carry a source field pointing to their parent enums entity.
| Field | Description |
|---|---|
value | String value (the wire-format token) |
label | Localized display name |
int_mapping | Integer mapping for the value |
Creating an Enum
- Create an
enumsentity:
{
"type_name": "entity_type/enums",
"key": "fruit_color",
"properties": {
"name": "fruit_color",
"label": { "en_us": "Fruit Color" }
}
}
- Create
enum_entryentities pointing to the enum:
[
{
"type_name": "entity_type/enum_entry",
"properties": { "value": "red", "label": { "en_us": "Red" }, "int_mapping": 1 },
"source": "enums/fruit_color"
},
{
"type_name": "entity_type/enum_entry",
"properties": { "value": "green", "label": { "en_us": "Green" }, "int_mapping": 2 },
"source": "enums/fruit_color"
},
{
"type_name": "entity_type/enum_entry",
"properties": { "value": "yellow", "label": { "en_us": "Yellow" }, "int_mapping": 3 },
"source": "enums/fruit_color"
}
]
Creating an enum_property_type
An enum_property_type entity links a property type to a specific enums definition via its enum_ref property:
{
"type_name": "entity_type/enum_property_type",
"key": "fruit_color",
"properties": {
"name": "fruit_color",
"label": { "en_us": "Fruit Color" },
"enum_ref": "enums/fruit_color"
}
}
Wire Format
Both input and output use the plain string value:
{ "properties": { "color": "red" } }
Internally, the engine resolves the string "red" to the stable root_id UUID of the matching enum_entry and stores that UUID. On read, the stored UUID is resolved back to the value string. This means:
- Enum entry labels and int mappings can change without breaking stored references.
- Even the string value itself can be renamed -- the reference is always by UUID.
Using an Enum Property
Declare it on an entity type via has_prop:
"has_prop": [
{
"properties": { "name": "color", "label": { "en_us": "Color" } },
"target": "enum_property_type/fruit_color"
}
]
See Property Types for more details.
Virtual Properties
An entity type can declare computed, read-only properties via has_virtual_prop. These are evaluated on demand via a Lua script and never stored in the database.
Declaration
Each has_virtual_prop instance carries:
| Field | Description |
|---|---|
name | Property identifier |
label | Localized display name |
description | Localized description |
script | Lua script; return value is the computed property value |
The target of the relationship defines the output type (e.g. string_property_type/generic).
"has_virtual_prop": [
{
"properties": {
"name": "adjusted_weight",
"label": { "en_us": "Adjusted Weight" },
"script": "return tostring(self.properties[\"weight\"] * 2)"
},
"target": "string_property_type/generic"
}
]
Behavior
- Virtual properties appear in entity responses alongside regular properties.
- They cannot be set or updated directly -- they are always computed from the current entity state.
- The
selfvariable in the script refers to the current entity instance. See Lua Scripting for the scripting reference.
Virtual properties are useful for derived values, formatted display strings, or calculations that depend on multiple properties of the same entity.