Member Junction
    Preparing search index...
    CUSTOM_OVERFLOW_COLUMN: "__mj_integration_CustomOverflow" = '__mj_integration_CustomOverflow'

    Name of the per-record custom-overflow column. Written on every integration table alongside the other __mj_integration_* columns when present. Holds a JSON object of the source fields a record returned that have NO field map — the "extra" keys the target table doesn't (yet) have a column for.

    This is the capture half of framework-level custom-column support (gaps.md §2). A source with no schema/describe endpoint (the PropFuel class) can only learn its full field set by reading data; a static catalog then silently drops any extra key at MapSingleRecord (only mapped fields get persisted). Rather than lose them, the unmapped keys are parked here, on the row, in the SAME write as the mapped fields — so capture costs no extra round-trip. A post-sync Runtime-Schema-Updation (RSU) pass later reads this column back out and promotes pervasive keys to real columns (ADD COLUMN + CodeGen + a field map). It does NOT backfill historical values: once the field map exists the key is no longer "unmapped", so the NEXT sync maps it natively and populates the new column with the LIVE source value (a full sync repopulates every row; an incremental fills rows as they next change) — and stops re-capturing it here. The loop converges go-forward.

    Shape mirrors CONTENT_HASH_COLUMN: a JSON-serialized string sidecar, identical in kind to __mj_integration_LastSyncedSnapshot. SS NVARCHAR(MAX) / PG TEXT; the post-sync coverage scan + spread cast ::jsonb on Postgres when they query it.

    This is BACKEND PLUMBING, not user-facing metadata. It is a SYSTEM field — in the same hidden/internal class as __mj_integration_ContentHash & the other __mj_integration_* columns: metadata-registered only so the engine's entity.Set(...)/entity.Fields write path is permitted to touch it (so it is NOT an out-of-band "phantom" column the engine writes blind), but NOT surfaced or managed through the metadata-driven framework — not in forms, not user-mappable, not "a field" anyone works with. It is machinery.

    The things that genuinely ENTER the metadata-driven framework are the columns this gets PROMOTED into: a pervasive key here is turned into a real user-facing, mappable EntityField (IntegrationSchemaSync IOF → RSU ADD COLUMN → CodeGen → md.Refresh) BEFORE the engine maps to it. So: backend staging until promotion, first-class metadata-driven schema after. Only the JSON values parked here are ever transient.

    Gated everywhere by EntityInfo field presence, so it is a no-op on tables that predate the column. RECONCILE CONTRACT (U4): the overflow is reconciled on EVERY sync via reconcileOverflowValue — the record's CURRENT unmapped keys as JSON, or null when it has none. Writing null (rather than skipping the write) is what EVICTS a vanished key. A customs-free sync stays byte-identical NOT by skipping the write but by BaseEntity dirty tracking: Set(column, null) on an already-null column compares null-to-null and produces no UPDATE — only a row that USED to carry overflow and no longer does becomes dirty (the eviction).