Customization layers
Within Channel 1 (metadata-driven customization, see customization channels), xly supports a layered overlay model. A base form is defined system-wide; tenants and users overlay changes on top without modifying the base. The framework merges the layers at request time and returns one merged form to the SPA.
For the worked example of how this plays out for a custom field, see Slice 4. This page is the canonical overview.
The layers
gdsconfigformmaster ← system default (the form)
↓ overlaid by
gdsconfigformpersonalize ← per-tenant whole-form override
(replaces sSqlStr/sWhere/sOrder)
↓ then base slaves
gdsconfigformslave ← system default fields
↓ overlaid / extended by
gdsconfigformcustomslave ← per-tenant fields (add, hide, override)
↓ optionally further tweaked by
gdsconfigformuserslave ← per-user view preferences
(column order, hidden columns)
Each layer is keyed by sParentId linking up to the layer above. None of
the links are FK-enforced — see no-FK reality.
What each layer answers
| Layer | Scope | Answer to |
|---|---|---|
gdsconfigformmaster |
system-wide | "What does this form look like by default?" |
gdsconfigformpersonalize |
per-tenant | "Does this tenant want a different SQL/where/order?" |
gdsconfigformslave |
system-wide | "What fields does the form have by default?" |
gdsconfigformcustomslave |
per-tenant | "Does this tenant want extra fields, or a hidden field, or a relabelled field?" |
gdsconfigformuserslave |
per-user | "Has this user reordered or hidden columns in their grid?" |
How the merge happens
The framework reads each layer in order and merges by sName (the field
name). For a custom slave row with the same sName as a base slave:
override. For a new sName: append. For a base slave with no
corresponding custom row: pass through unchanged. The merge happens
inside BusinessBaseServiceImpl.getModelBysId (line 181) and the
helpers it calls — BusinessGdsconfigformsServiceImpl.getFormSlaveData
-
getFormCustomSlaveData.
Two database views support the merge by joining the form-master with the relevant slave table:
-
gdsconfigformslavemasterview— base layer -
gdsconfigformcustomslavemasterview— overlay layer
These views are read directly by the service code; the merge logic is in Java rather than SQL.
What the layers can't do
The overlay tables let a tenant add fields to the form, but they do
not (and cannot) ALTER TABLE the underlying physical table. A custom
field beyond what the base table provides has nothing to bind to on save
unless one of the following is true:
- The base table is intentionally "wide" (has spare columns reserved for customization).
- A coordinated manual schema migration adds the column.
- The customization is purely view-related (the field is computed or displayed, not stored).
Case (2) is the typical engineer-led path. Case (1) explains some of the schema's mysteriously over-broad tables. When the customization needs structural change beyond what overlays support, Slice 5 (per-customer SQL overrides) is the next channel up.