ENTITY_COMPANY_INTEGRATION_OBJECTS:"MJ: Company Integration Objects" = 'MJ: Company Integration Objects'
The per-connection catalog: read-side types, column contract, and projection.
Every connector and every engine read site names an IntegrationObject's properties directly —
io.Name appears 241 times across the connectors repository, io.Fields 93, io.APIPath 52.
A row loaded for an entity with no registered subclass is a plain BaseEntity: it carries its
values in Fields and exposes them through Get(), and every one of those property reads is
undefined. So the cache cannot hand connectors the entity rows themselves.
It hands them PROJECTIONS instead — plain objects carrying exactly the property surface the read
sites use. That is not a new idea here: IntegrationEngineBase.SeedForTesting already seeds the
shared catalog with "plain objects shaped like the entity (property reads only)" for the same
reason, and the replay tiers exercise metadata-driven connectors through them.
Writes are the other half and do NOT come through here — they go through the store in
@memberjunction/integration-engine, which holds real entity rows and uses Get()/Set()
exclusively. Assigning row.Name = x on a subclass-less BaseEntity silently creates an own
property, Save() sends nothing, and the write is lost with no error anywhere.
The per-connection catalog: read-side types, column contract, and projection.
Every connector and every engine read site names an IntegrationObject's properties directly —
io.Nameappears 241 times across the connectors repository,io.Fields93,io.APIPath52. A row loaded for an entity with no registered subclass is a plainBaseEntity: it carries its values inFieldsand exposes them throughGet(), and every one of those property reads isundefined. So the cache cannot hand connectors the entity rows themselves.It hands them PROJECTIONS instead — plain objects carrying exactly the property surface the read sites use. That is not a new idea here:
IntegrationEngineBase.SeedForTestingalready seeds the shared catalog with "plain objects shaped like the entity (property reads only)" for the same reason, and the replay tiers exercise metadata-driven connectors through them.Writes are the other half and do NOT come through here — they go through the store in
@memberjunction/integration-engine, which holds real entity rows and usesGet()/Set()exclusively. Assigningrow.Name = xon a subclass-lessBaseEntitysilently creates an own property,Save()sends nothing, and the write is lost with no error anywhere.