Runtime
Updated
The kernel runs the objects metadata described. CRUD, validation, events, posting, and the API all sit here. The SignalR host is a separate process. The SPA is generated screens plus a ribbon.
Services every script can call#
| Platform service | Role |
|---|---|
| Data service | CRUD on physical tables. A row is Dictionary<string, object?>. Save broadcasts RecordChanged. Delete is guarded — Identity. |
| Metadata service | Introspection of metadata |
| Document manager | Load, save, links between documents |
| Dictionary manager | Typed dictionary rows |
| Data-entity manager | The OData projection — Data entity |
| Register movements / Totals manager | Movements and balances |
| Information-register service | Set / SliceLast / SliceFirst |
| Document posting service | Subtype transitions |
| Accounting period service | The posting boundary: two dates per tenant, not the FiscalPeriod dictionary |
| Outbound gateway / Outbound call | Out by channel name |
| Constant resolver / Global constant manager | Named constants |
Your own services appear as I<Name> — Service.
A kernel totals driver (StockBaseTotalDriver and the rest compiled into Core) has no owner script. A script in a model above is a CoC wrap with next(), not a partial class of the same name.
Scripts call the platform services in the table above. Older architecture notes that list different controller names do not describe this API.
Compiler#
See Scripts. Unchanged entities are not re-emitted (SourceSetHash). Event handlers with the same text are reused. A per-call compile (reuseLoaded: true) returns the loaded assembly; static fields in a reused test survive between runs.
Real-time#
The hub /hubs/zuloone broadcasts RecordChanged { table, recordId, changeType } on Insert/Update/Delete. The SPA subscribes per record and falls back to polling.
Transfer#
Export resolves references to the target's business key. Import resolves them to the local MetaId. Movements are not copied — they are regenerated by reposting.