ServerDynamic Objects
Architecture
Data flow, service relationships, and layer composition for Dynamic Objects.
Request Flow
Layered Architecture
Unlike CRUD which uses a global layer, Dynamic Objects use a Request-Scoped Layer built via buildDynamicObjectsLayer.
1. Discovery Layer (EntityMetadataService)
- Fetches entity and field definitions from
EntityandFieldtables - Caches definitions to avoid DB lookups per request
- Handles field type resolution (PICKLIST, LOOKUP, FORMULA)
2. Validation Layer (ValidationService)
- Converts
Fielddefinitions to JSON Schema using AJV - Caches validators using
(tenantId, entityName)key - Invalidates cache on field/entity changes
3. Execution Layer (DynamicRepository)
- Uses dynamic Prisma calls or raw SQL for tenant tables
- Maintains Prisma-like syntax for consistency
- Handles tenant-specific connection
4. Orchestration Layer (OperationHandlerService)
- Coordinates pre-flows, hooks, repository, post-flows
- Handles formula field computation
- Manages audit field updates
Request-Scoped Layer
Dynamic Objects build their layer per-request:
import { buildDynamicObjectsLayer } from "./layers";
app.use("*", async (c, next) => {
const org = c.get("org");
// Build tenant-specific layer
const layer = await buildDynamicObjectsLayer(org);
// Execute route with layer
await next();
});This ensures each tenant gets their own:
- Prisma client connected to their database
- Cached metadata
- Isolated execution context