11 — Generated CRUD API
The generated CRUD API is the runtime API layer that uses the published entity model to create, read, update, delete, tag, relate, and query entities.
It is not code generation in the traditional sense. It is model-driven runtime behavior.
Goal
Enable a new entity type to become usable without writing bespoke CRUD endpoints.
Example:
- Admin defines entity type
room. - Admin defines properties and hierarchy rules.
- Admin publishes model.
- Runtime API can create, read, update, delete, and list
roomentities. - Frontend can render basic forms and tables for rooms.
Generic Entity Create
Endpoint:
POST /api/entitiesInput:
{
"entityTypeKey": "asset",
"parentEntityId": "uuid",
"templateKey": "bacnet_controller",
"properties": {
"hostname": "AHU-01",
"ip_address": "192.168.1.50",
"bacnet_device_id": 12001
},
"tags": ["criticality_high", "vendor_trend"]
}Backend behavior:
- Resolve published model.
- Resolve entity type.
- Validate parent and hierarchy rules.
- Validate template.
- Validate property values.
- Validate tags.
- Check permissions and root scope.
- Create entity and values in transaction.
- Write audit event.
Generic Entity Update
Endpoint:
PATCH /api/entities/:entityIdShould allow:
- updating display metadata,
- updating property values,
- updating tags,
- optionally moving parent if
entity.moveis allowed.
Dangerous operations such as subtree move should have explicit endpoints.
Generic Entity List
Endpoint:
GET /api/entities?type=asset&parentEntityId=...&q=...Supported filters:
- entity type,
- root scope,
- parent,
- descendants of,
- tags,
- property filters,
- created/updated dates,
- deleted state.
The backend must translate filters safely into SQL.
Property Filtering
Property filters should be explicit and typed.
Example:
{
"filters": [
{
"propertyKey": "ip_address",
"operator": "equals",
"value": "192.168.1.50"
},
{
"propertyKey": "commissioning_status",
"operator": "in",
"value": ["blocked", "in_progress"]
}
]
}Only filterable properties should be queryable.
Avoid Arbitrary Query APIs Initially
Do not expose a completely arbitrary user-defined query language in Alpha.
Start with controlled filters.
Future versions can introduce:
- saved views,
- advanced filters,
- query builder UI,
- reporting DSL,
- external data joins.
Generated API Is Still Governed
The generic API must enforce:
- root scope,
- permissions,
- published model validation,
- lifecycle rules,
- Vault boundaries,
- audit events,
- rate limits where needed.
When To Use Custom APIs
Use custom APIs for workflows with domain behavior.
Examples:
- reveal secret,
- rotate secret,
- launch remote session,
- import from Simpro,
- bulk commissioning workflow,
- approval flow,
- operational report generation.
The generated CRUD API handles common entity data operations. It should not replace application services.