Skip to main content
Version: v5.7.0

Entity

Included from Basic tier

An entity is a minimal estate node: anything worth recording in the estate — a database schema, a rack, a building — without the automation an asset carries. It has no template, so nothing runs against it: no actions, changes, MintModel or background tasks. It lives under a project, environment, asset or another entity — "/projects/shop/environments/prod/entities/orders_schema" — and parents entities only. It has no type; classify entities with metadata.

An entity carries the basic node constructs: its own properties and settings documents (merged into the converge as the entity layer, and versioned in properties history), metadata, asset owners, maintenance windows, bookmarks, vault secrets it owns (opschain vault store <entity-path> …), archive, and soft delete / restore / destroy / export. Authorisation is by path like every node, 404-on-deny. Entities are part of core OpsChain: no entitlement and no count limit — they never count against the asset limit.

Served by the v2 EntityService (ListEntities, GetEntity, CreateEntity, BulkCreateEntities, UpdateEntity, DeleteEntity) and by the v1 node-path lanes under the entities collection segment (see opschain docs resources/node). Creates, updates and deletes record the node event family (api:nodes:create, api:nodes:update, api:nodes:deleted, …) with kind: entity in the event data.

From the CLI​

opschain entity drives the same service (opschain docs cli/entity):

opschain entity create shop/environments/prod --code orders_schema --name "Orders schema"
opschain entity bulk-create shop/environments/prod/entities/orders_schema --file tables.yaml
opschain entity list shop/environments/prod/entities/orders_schema --search order
opschain entity show shop/environments/prod/entities/orders_schema
opschain entity update shop/environments/prod/entities/orders_schema --archived
opschain entity delete shop/environments/prod/entities/orders_schema --confirm

The shared node verbs take entity paths too: opschain nodes show|create|update, opschain nodes list <path> --include-entities (the subtree with its entities nested at any depth, in one read of NodeService.GetNodeHierarchy with include_entities), opschain properties|settings show|edit|history, and opschain admin nodes delete|restore|destroy|export|import, and opschain vault store|store-file|global (the entity as the secret's owner):

opschain nodes list shop/environments/prod --include-entities
opschain properties show shop/environments/prod/entities/orders_schema
opschain admin nodes restore shop/environments/prod/entities/orders_schema

bulk-create reads EntityCreateItem rows from a YAML or JSON file and splits a file of more than 1000 items into consecutive batches; -o json on any verb emits the Entity fields below (snake_case), and on bulk-create one EntityCreateResult per item.

Entity​

Entity is the typed Entity read shape.

FieldTypeMeaning
archivedbooleanWhether the entity is archived. Toggled through UpdateEntity.
codestringThe record's code: lowercase letters, numbers and underscores, at most 50; unique among the parent's entities.
conversion_statestring"promoted" or "demoted" on a node left behind by a conversion; "" otherwise.
converted_from_idstringThe node this one was converted from; "" when none.
converted_to_idstringThe node this one was converted into; "" when none.
created_attimestampWhen the record was created.
created_bystringUsername of the creating identity.
descriptionstring"" when never set.
idstringThe record's identity.
maintenanceNodeMaintenanceBadgeThe active-maintenance badge; unset while the node is open. An ancestor's window badges the entity too.
namestringDisplay name; unique among the parent's unarchived entities.
node_pathstringThe entity's node path, e.g. "/projects/shop/environments/prod/entities/orders_schema".
parent_pathstringThe parent node's path (a project, environment, asset or entity).
properties_idstringThe entity's own properties document id.
settings_idstringThe entity's own settings document id.
updated_attimestampWhen the record was last updated.

EntityFilter​

EntityFilter is the typed Entity predicate vocabulary.

FieldTypeMeaning
archivedbooleanKeep only archived (true) or unarchived (false) entities; unset keeps both.
codestringExact code match; "" keeps all.
searchstringCase-insensitive substring over name and code; "" keeps all.

EntityCreateItem​

EntityCreateItem is one BulkCreateEntities row under the batch's parent. A batch holds at most 1000 items; a larger batch is refused by name.

FieldTypeMeaning
codestringThe entity's code — the batch's match key under the parent.
descriptionstringFree-text description; "" stores none.
namestringDisplay name.

EntityCreateResult​

EntityCreateResult is one batch item's outcome. A refused item (a bad code, a code or name already taken, a duplicate within the batch, or a path a deleted entity still reserves) fails alone; the rest of the batch is created.

FieldTypeMeaning
codestringThe record's code.
errorstringThe named refusal when outcome is failed; "" otherwise.
node_idstringThe created entity's node id; "" when the item failed.
outcomestringcreated or failed.
  • opschain docs resources/node — the node family, the node-path lanes and the entities collection segment.
  • opschain docs resources/properties — the properties document the entity owns.
  • opschain docs metadata — classifying entities with metadata profiles.

Promote and demote​

PromoteEntity (opschain entity promote) converts an entity into a new asset; DemoteAsset (opschain asset demote) converts an asset into a new entity. A conversion never rewrites a node in place, and it is one transaction — a node is never half-converted:

  • The new node gets its own id and path. The destination (parent_path) and code default to the converted node's own; a promotion's destination must accept assets (a project or an environment — never an entity, asset or infrastructure node), a demotion's any node an entity may live under. Promotion can change the parent, across projects included.
  • The properties document is copied with the lineage entry appended; the settings document is copied as a settings document (settings values never reach properties, lineage or events). Both start the new node's own version history at version 1.
  • Child entities (and their descendants) move under the new node with their paths rewritten, set-based.
  • The old node is left archived: conversion_state is promoted or demoted and converted_to_id names the new node, whose converted_from_id points back (v1 show: conversion_state, converted_to / converted_from {id, path}). It is an ordinary archived node, not locked: it can be edited, have its properties and settings written, be unarchived, deleted and restored like any other. An archived node is not converted ("Cannot promote <path>: it is archived — unarchive it first"). Path-addressed references (RBAC rules, bookmarks, node_ref, workflow targets) keep naming the old node and are not rewritten.
  • A workflow step or trigger aimed at the asset does not block a demotion, exactly as it does not block a delete. New work aimed at the demoted asset answers exactly as it does on any archived asset. Retarget those workflows and triggers after converting.
  • Promotion pins a template version with the asset create checks (the version exists, is unarchived, resolved and not disabled), needs the assets entitlement and room under the asset licence limit, and starts the asset's actions generation after commit exactly as an asset create does. Demotion drops the template pin, actions catalogue, MintModel and background work (the old asset keeps its history) and is refused by name (ERROR_REASON_CONVERSION_PRECONDITION_FAILED, metadata precondition) while the asset has active or queued changes (active_changes), pending approvals (pending_approvals), scheduled activities (scheduled_activities), or a live child an entity may not have (disallowed_children); a destination that cannot hold the new kind or sits under the converted node answers destination.
  • The caller needs update and delete on the converted node and create of the new kind at the destination (update on <destination>/<assets|entities> and on the new node's path); 404-on-deny.
  • Each conversion records api:nodes:promoted or api:nodes:demoted in the same transaction: before and after (id, path, kind), change, moved_nodes, the template identity and, on a demotion, last_change_id — the authoritative audit record.

The lineage entry is appended to the new node's properties under the reserved key opschain_lineage (an array; entries copied from the old node are kept). It is an ordinary, editable property. The old node's own properties are left untouched — its conversion columns and the event record how it was converted.

{
"opschain_lineage": [
{
"change": "promoted",
"at": "2026-12-01T09:00:00Z",
"by": "javery",
"to": "asset",
"from_node": {"id": "0193b7…", "path": "/projects/shop/environments/prod/entities/orders_db"},
"to_node": {"id": "0193c2…", "path": "/projects/shop/environments/prod/assets/orders_db_v2"},
"template_code": "postgres_cluster",
"template_version": "v14"
}
]
}

A demotion entry carries "change": "demoted", "from": "asset", the asset's pinned template_code / template_version and, when the asset ran any change, last_change_id. by is the converting principal's username (the identifier created_by carries).

FieldTypeMeaning
converted_from_pathstringThe path of the node this entity was converted from; "" when none (or since destroyed).
converted_to_pathstringThe path of the node this entity was converted into; "" when none (or since destroyed).

ConvertedNode​

ConvertedNode is one side of a promote or demote (PromoteEntityResponse and DemoteAssetResponse carry old_node, new_node and moved_nodes).

FieldTypeMeaning
conversion_statestring"promoted" or "demoted" on the node left behind; "" on the new node.
idstringThe node's id.
kindstringentity or asset.
node_pathstringThe node's path.