ORM
How core/orm turns Fields into tables and how records are read and written.
Role
core/orm owns the model registry, PostgreSQL access, schema sync from FieldDefinition, security-aware CRUD, and mutation/outbox paths.
From Fields to tables
On install and module update (-i / -u), registered models run additive schema sync from registered model metadata: new columns, indexes, and unique constraints are created. Types map Char → varchar/text, Boolean, Integer, relations, and so on.
dropStaleColumnUniques removes single-column UNIQUE constraints when a field no longer declares Unique: true — it does not drop columns or tables. There is no boot-time schema_migrate repair pass; schema changes happen during module load only.
Pre-alpha. Sync is additive. Renaming or removing fields does not automatically drop old columns. Plan manual SQL on shared databases.
Records as maps
Public APIs search/create/write with maps. Addon authors still declare typed structs for Field metadata via the SDK.
SDK boundary
Addon code should import sumeru/core/sdk (sdk.Model tags). Registration is generated by make generate. Keep direct ORM imports for core/engine work.
Computed fields and read_group
orm.RegisterCompute derives field values on read (see Models & fields). orm.ReadGroup and the read_group JSON-RPC method provide sum/count aggregation with the same ACL and record rules as search.
Compile and run
cd sumerugo test ./test/orm/...cd ../sumeru_custom_addons && make run
What not to do
- Do not bypass the mutation pipeline with ad-hoc SQL for business rows unless you accept outbox/event divergence.
- Do not change FieldType meanings in addons. Extend models instead.
Next step
See load order in Module loader, or practical fields in Models & fields.