Schema Editor
Inspect and customize entity schemas and field definitions.
Prefer a guided tutorial?
Follow the Define a Custom Entity Type hands-on tutorial, then return here for the full reference.
The Schema Editor is an administrative application for viewing and editing ControlBird's entity type definitions. Every entity is an instance of an entity type, and each type declares a set of named fields with specific data types and storage scopes. With the Schema Editor you can create new entity types, manage field inheritance through type hierarchies, add and remove direct fields, and save those changes so they persist.
Schema Editor vs Model Builder
These two tools solve different problems. The Schema Editor defines the structure of the data model: which entity types exist and what fields they carry. The Model Builder is for creating entity instances and visual layouts. Use the Schema Editor to define what data exists; use the Model Builder to define how it looks.
Access & Requirements
Opening the Schema Editor requires schema-editing permission, so it is intended for administrators and developers shaping the data model rather than day-to-day operators.
Core Concepts
A schema describes an entity type and the fields it owns. ControlBird distinguishes between the fields a type declares directly and the full set of fields it has after inheritance, and it exposes both views in the editor.
| Concept | What it represents |
|---|---|
| Direct schema | Only the fields defined at that type level, plus the list of parent types it inherits from. |
| Complete schema | The resolved schema including every field from the type and all of its ancestors. Drives the total field count and the inherited fields view. |
| Field definition | A single field: its name, data kind, default value, rank, and storage scope. |
| Inheritance | The parent types a type inherits from. A child type combines its own direct fields with all direct and inherited fields of its parents. |
How types and fields are identified
Each entity type and each field is assigned a stable identifier when it is created. These identifiers cannot be renamed afterward.
The Workspace
The editor is a two-panel layout. The left panel is a searchable, paginated tree of entity types; the right panel shows the schema of whichever type you select.
- Type tree (left): root entity types and their descendants, built from inheritance relationships. Roots are paginated 25, 50, or 100 per page.
- Entity header (right): the selected type's name, type ID, parent names, direct field count, and total field count.
- Direct Fields: a sortable, editable table of fields declared on the selected type.
- Inherited Fields: a read-only table of fields contributed by parent types.
- Add Field: a form for declaring a new field on the current type.
Keyboard shortcuts
| Shortcut | Action |
|---|---|
Ctrl+F | Focus the tree search. |
Ctrl+N | Open the create entity type form. |
Escape | Deselect the current type. |
Field Data Types
Each field has a kind (its data type) which determines the value it can hold and its default. The available kinds are:
| Kind | Holds | Default value |
|---|---|---|
String | Text values. | Empty string. |
Int | Integer values. | 0 |
Float | Floating-point values. | 0.0 |
Bool | True/false flags. | false |
Timestamp | Points in time. | Epoch. |
EntityReference | A reference to a single entity. | null |
EntityList | An ordered list of entity references. | Empty array. |
Choice | One option from a fixed set. | Index into the choices array. |
Blob | Raw binary data. | Empty byte array. |
Decimal | Fixed-precision decimal values. | '0' |
Choice fields
A Choice field carries a choices array of options plus a default index. You enter the options as a comma-separated list and pick which one is selected by default. A choice field must have at least one option, and the default index must fall within [0, choices.length - 1].
Storage Scope
Every field has a storage scope that controls whether it is persisted. This is the most important property to get right, because it decides whether a field survives a restart.
| Scope | Behavior |
|---|---|
Runtime | Live, in-memory value only. Not persisted and not part of the saved schema. |
Configuration | Persisted, so it survives restarts and is part of the saved schema. |
Structural fields (Name, Parent, and Children) are handled separately from the schema and are not treated as Configuration-scoped fields.
Runtime fields do not survive restarts
Use Configuration scope for anything you expect to persist (setpoints, enable flags, references). Reserve Runtime scope for live, derived, or transient values such as a current reading or a computed status: those are rebuilt at runtime and never persisted.
Field Rank
Rank is a numeric sort order that controls how fields are displayed. Fields are sorted by rank, then alphabetically by name as a tie-breaker. Fields without an explicit rank fall back to the order in which they were defined.
Assign ranks explicitly
Duplicate ranks are resolved by the secondary sort on field name, which can produce an order you did not intend. Assign explicit ranks to fields you care about ordering, especially in types with many fields.
How Schemas Are Persisted
When you save a schema, the definitions of every entity type and its Configuration-scoped fields are persisted so they survive a restart. Runtime-scoped fields and structural fields are not persisted. The editor keeps the on-screen tree and field counts in sync after each save.
Editing a Schema: Step by Step
- Open the Schema Editor from the platform UI. It lists all entity types, then loads each type's fields when you select it.
- Browse or search the type tree on the left and click an entity type to select it.
- Review the Direct Fields table (name, kind, rank, storage scope, default or options, and a remove action) and the read-only Inherited Fields table.
- In the Add Field section, enter a field name, select a kind, set the rank and storage scope, and supply kind-specific configuration (a default value, or options for a Choice field).
- Click Add Field. The new field appears in the Direct Fields table.
- Edit field properties inline. Changing rank or storage scope marks the schema as having unsaved changes, and the editor warns you before you navigate away.
- Remove direct fields you no longer need. Inherited fields cannot be modified here; edit the parent type instead.
- Click Save Changes to persist the updated fields, or Reset to discard unsaved edits and reload the saved schema.
Field removal is immediate
Removing a direct field persists immediately and is not gated by a confirmation dialog. Double-check the field before removing it, particularly Configuration-scoped fields whose data is persisted.
Creating a New Entity Type
- Click New Entity Type (or press
Ctrl+N) to open the create form. - Enter the type name and optionally select one or more parent types to inherit fields from.
- Click Create. The new type is assigned an identifier and saved with the parent types you selected.
- The new type appears in the tree, nested under its parent. Select it to begin adding direct fields.
Example: a Choice field on an existing type
Suppose you want to add a status indicator to a type. In the Add Field section, set the name to Status, the kind to Choice, the options to Idle,Processing,Error, and the default index to 0. After saving, the Direct Fields table shows Status with three options and Idle selected by default.
Inheritance in Practice
Selecting a type that inherits from a parent illustrates how the two views work together. The Inherited Fields table shows the fields contributed by the parent type, while the Direct Fields table shows the fields declared on the selected type itself. A type can inherit from more than one parent.
A child type combines its own direct fields with the direct and inherited fields of every parent it inherits from. Circular inheritance is not permitted and is rejected when you save.
Limitations
- Entity type identifiers are assigned on creation and cannot be renamed afterward.
- Inherited fields are read-only here; modify them on the parent type.
- Field names must be unique within a type.
- Choice fields require at least one option, and the default index must be in range.
- Circular inheritance is rejected on save, with an error surfaced in the editor.
- Field removal persists immediately, without a confirmation dialog.
- Very large schemas (more than ~100 types) may impact tree-rendering performance.
Next Steps
With your types defined, populate and lay out instances in the Model Builder, inspect the resulting data in the Database Browser, or review how field changes propagate through the Data Model and Notifications & Reactivity.