Skip to content

Entities and Relationships ​

An entity is a record type: Customer, Invoice, Leave Request. Creating an entity creates a real database table in your workspace and a complete create, read, update and delete API for it, with audit columns, paging and filtering. The Entity Designer defines the fields, relationships, indexes and constraints. This page documents the Explorer nodes Entities and Relationships under Data. For the layers that read entities see Data Views, Data Services and Data Providers.

Entities ​

Where to find it ​

Workspace > Data > Entities lists the entities. Opening one opens the Entity Designer. Entities that belong to an application also appear under that application in the Explorer.

Immediate changes ​

Unlike pages, forms and workflows, the Entity Designer has no draft and no publish step. Every change you make is applied to the database at once: adding a field adds a column, adding an index creates the index. There is no undo for a column that has already received data. Change entities that hold real data with care, and prefer adding fields to changing or removing them.

What every entity has ​

Each table is created with these columns, which are not listed among your fields:

ColumnDescription
tenant_idThe workspace. Part of the primary key. Every query is scoped to it.
idThe record id. How it is generated is chosen when the entity is created.
created_by, created_atWho created the record and when.
updated_by, updated_atWho last changed it and when.
deleted_by, deleted_atOnly when soft delete is on. A deleted record is marked, not removed.

The primary key is (tenant_id, id) unless you replace it (see Primary key).

Create an entity ​

FieldDescription
Entity nameFor example Customer. An entity with an existing name is refused: Entity already exists: <name>.
Table nameDefaults to a snake_case form of the name.
CategoryMaster, Transaction, Configuration or Audit. A label for organising entities.
Primary keyThe id strategy. Fixed at creation. See below.
Sequence nameOnly for the sequence strategy. Required (pkSequenceName is required when pkStrategy is 'sequence'). Entities that use the same sequence name share one sequence.
Soft deleteRecords are marked deleted instead of removed. Can be switched on later with POST /api/v1/entities/{id}/enable-soft-delete.
Describe the entityA sentence such as "An invoice entity with number, amount, due date and status". Generate with AI drafts the entity with its fields.

Id strategies

StrategyId
snowflake (default)A 64-bit number generated by the platform before the insert, unique across servers.
identityA database identity column.
uuidA random UUID.
sequenceA named database sequence.

Entity list ​

Columns: Name (with description), Table, Category, Status. Actions: create, Clone (asks for a New entity name and a New table name, and copies the entity definition), and delete. Entities shipped by a plugin show as owned by the plugin and are changed through the plugin.

Fields tab ​

FieldDescription
Field namesnake_case. A duplicate is refused: Field already exists: <name>.
Data typestring, text, integer, long, decimal, boolean, date, datetime, time, json, uuid, enum, file, image, binary, currency, email. An unknown type is refused: Unknown data type: <type>.
LengthFor string.
Enum valuesFor enum, comma separated.
RequiredThe column is not null.
UniqueAdds a unique constraint on the field.
Display fieldThe field shown when this entity is referenced from another, for example in a lookup.
Formula fieldThe value is computed. Formula, for example quantity * unit_price, may reference only other stored fields.

A field that takes part in a relationship cannot be removed: Field "<name>" is used by an active relationship — drop the relationship first.

Relationships tab ​

A canvas of the entity and the entities it connects to, and a form to add a relationship.

FieldDescription
Relationship typeone_to_one, one_to_many, many_to_one, many_to_many, self_referencing.
Other entityThe entity on the other side.
From field (FK column)The field in this entity that holds the other record's id.
On deletecascade, restrict, set_null, no_action. Hierarchical relationships support only cascade and restrict: hierarchical relationships only support onDelete 'cascade' or 'restrict'.

Indexes tab ​

Choose one or more fields and optionally Unique, then add the index. Existing indexes are listed with a unique marker and a drop control.

Constraints tab ​

A check constraint stated as a predicate over the entity's fields.

FieldDescription
Constraint namesnake_case.
Predicate (JSON)A leaf {"field","operator","value"} with operators eq, ne, gt, gte, lt, lte, in, is_null, is_not_null, or a combination with {"and": [...]} and {"or": [...]}. Never free-text SQL.

Primary key ​

The Fields tab shows currently: id (default) or the current key columns. Select fields to build a composite or business key, then Set primary key. Only required (not-null) fields can be selected: Field "<name>" must be required (not null) before it can be part of the primary key. The id column and its generation strategy stay as they were; only the primary key constraint changes.

Metadata tab ​

FieldDescription
DescriptionFree text.
CategoryAs above.
Icon, ColorUsed by the Explorer and generated screens.
CacheableA metadata flag. No caching layer is wired to it yet.
Full-text searchA metadata flag. No search index is built from it yet.

History tab ​

The schema change log: each field, index, relationship and constraint change with who and when.

Data API ​

Every entity is served at /api/v1/entities/{name}/records: GET (paged, filtered, sorted through the query engine), POST, GET, PUT, DELETE /{id}, PATCH /bulk, and GET /{id}/activity for the record's change history. Reads and writes go through the permission checks in Permissions, the rules that apply to the entity, and the audit trail. Definitions: /api/v1/entities, /api/v1/entities/{id}/fields, /relationships, /indexes, /constraints, /primary-key, /history, /clone.

Errors ​

MessageCause
DDL failed for "<context>": <cause>The database refused the change, for example a type change that existing data cannot satisfy. Nothing was changed.
Entity already exists, Field already exists, Unknown data typeAs above.

CLI ​

erp plugin op entity-list, entity-get; erp artifact ... --type entities; entities ship in a plugin under spk-assembly/metadata/entities/*.json (schema: Reference: entity definition). Entity-level jobs have their own schemas: aggregation, cadence, compliance, status-date sweep, cross-plugin action, document generator.

Relationships ​

Where to find it ​

Workspace > Data > Relationships opens the entity relationship diagram (ERD).

What it shows ​

All entities as boxes with their relationships as lines. Selecting an entity lists its fields with these columns: Field (the primary key is marked), Type, Nullable, Unique, Indexed, Display. Relationships are created and removed on an entity's Relationships tab (see above).

Data Views, Data Services and Data Providers, Data Model overview, Add an entity, Business Rules.