Modules, forms, virtual tables
The three core nouns of xly's metadata model. A reader who internalises these can navigate the rest of the framework. The vocabulary is not always consistent in the codebase — same concept, different names in different files — so part of this page is reconciling the synonyms.
Module
The unit of "a configurable thing in the system".
-
One row per module in
gdsmodule. - Carries the URL fragment (
sName), display names (sChinese,sEnglish,sBig5), tree position (sParentId,sAllId), product edition (sVersionFlowId, see Slice 2), optional CRUD procedure names (sSaveProName,sDeleteProName,sProcName,sCalcProName,sSaveProNameBefore). - 1,358 rows in the current live DB.
The Java codebase calls this concept "module", "model", "models", and
"modle" (typo, common). The variable sModelsId and method
getModelConfigByModleId both take a module sId, despite the naming.
See the naming caution in Slice 1.
Form
The screen layout for a module — header + N field definitions.
-
Master: one row per form in
gdsconfigformmaster. Carries the backing object (sTbName), backing-object type (sType∈{table, view, proc}), default SQL fragments (sSqlStr,sWhere,sOrder), grid behaviour (bGrd,iPageSize), jurisdiction column. -
Slave: one row per field in
gdsconfigformslave. Carries the field name (sName— matches a column in the backing object), control type (sControlName), display labels, validation rules, default value, dropdown SQL, button instructions. - A module is linked to its form via
gdsconfigformmaster.sParentId = gdsmodule.sId— semantic FK, no enforcement. (Note:gdsmodule.sFormIdexists but is empty for most modules and is not the canonical link.) - 2,022 master rows, 159,371 slave rows in the current live DB.
The form is the user-visible artefact: when a PM "creates a screen" in
BACK, what they're really doing is INSERTing a gdsconfigformmaster row
plus 5-50 gdsconfigformslave rows.
Virtual table
xly's term (and table prefix) for a "table" that is itself defined as
metadata, not as a CREATE TABLE statement.
- One row per virtual table in
gdsconfigtbmaster. - One row per virtual column in
gdsconfigtbslave. - 307 master rows, 14,385 slave rows in the current live DB.
Virtual tables are how PMs declare "I want this kind of thing" without asking an engineer. Most virtual tables back to a real physical table (the framework supports the migration step, or it pre-creates a generic "wide" table the PM populates), but the abstraction the runtime sees is the metadata declaration, not the underlying storage.
This is distinct from a database view: a virtual table is metadata; a
view is a CREATE VIEW SQL object. Both can back a form (via
gdsconfigformmaster.sType = 'table' or 'view'). See Slice 3
for the view-backed case.
How they fit together
gdsmodule (module, 1 row)
└── (joined via sParentId)
gdsconfigformmaster (form-master, 1 row per form)
├── gdsconfigformslave (fields, N rows)
├── gdsconfigformcustomslave (per-tenant fields, N or 0)
└── gdsconfigformuserslave (per-user tweaks, N or 0)
gdsmodule.sName → registered route in gdsroute (URL whitelist)
gdsmodule.sFormId → (mostly empty — historical)
Every form has exactly one module. Every module should have at most one
form, but a few have several gdsconfigformmaster rows pointing at the
same sParentId — those represent screens with multiple panels or
sub-tabs.
Three nouns, one engine
The runtime — BusinessBaseController and BusinessBaseServiceImpl,
documented in Slice 1 — knows how to
render any module / form / virtual-table combination. There is no
per-module Java code. PMs creating new modules are creating new rows;
they are not creating new code paths.