Appearance
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:
| Column | Description |
|---|---|
tenant_id | The workspace. Part of the primary key. Every query is scoped to it. |
id | The record id. How it is generated is chosen when the entity is created. |
created_by, created_at | Who created the record and when. |
updated_by, updated_at | Who last changed it and when. |
deleted_by, deleted_at | Only 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
| Field | Description |
|---|---|
| Entity name | For example Customer. An entity with an existing name is refused: Entity already exists: <name>. |
| Table name | Defaults to a snake_case form of the name. |
| Category | Master, Transaction, Configuration or Audit. A label for organising entities. |
| Primary key | The id strategy. Fixed at creation. See below. |
| Sequence name | Only for the sequence strategy. Required (pkSequenceName is required when pkStrategy is 'sequence'). Entities that use the same sequence name share one sequence. |
| Soft delete | Records are marked deleted instead of removed. Can be switched on later with POST /api/v1/entities/{id}/enable-soft-delete. |
| Describe the entity | A sentence such as "An invoice entity with number, amount, due date and status". Generate with AI drafts the entity with its fields. |
Id strategies
| Strategy | Id |
|---|---|
snowflake (default) | A 64-bit number generated by the platform before the insert, unique across servers. |
identity | A database identity column. |
uuid | A random UUID. |
sequence | A 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
| Field | Description |
|---|---|
| Field name | snake_case. A duplicate is refused: Field already exists: <name>. |
| Data type | string, 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>. |
| Length | For string. |
| Enum values | For enum, comma separated. |
| Required | The column is not null. |
| Unique | Adds a unique constraint on the field. |
| Display field | The field shown when this entity is referenced from another, for example in a lookup. |
| Formula field | The 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.
| Field | Description |
|---|---|
| Relationship type | one_to_one, one_to_many, many_to_one, many_to_many, self_referencing. |
| Other entity | The entity on the other side. |
| From field (FK column) | The field in this entity that holds the other record's id. |
| On delete | cascade, 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.
| Field | Description |
|---|---|
| Constraint name | snake_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
| Field | Description |
|---|---|
| Description | Free text. |
| Category | As above. |
| Icon, Color | Used by the Explorer and generated screens. |
| Cacheable | A metadata flag. No caching layer is wired to it yet. |
| Full-text search | A 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
| Message | Cause |
|---|---|
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 type | As 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).
Related
Data Views, Data Services and Data Providers, Data Model overview, Add an entity, Business Rules.
