1. Mental Model
Before any worked example, the conceptual map.
The framework is module-driven: every screen a PM creates and every screen
a customer sees is a row in gdsmodule joined to layout rows in
gdsconfigformmaster/slave, permission rows in gdsjurisdiction, and
stored procedures invoked through BusinessBaseController in the runtime.
At a glance
flowchart TB
classDef oos stroke-dasharray:5 5,color:#999
BACK["BACK<br/>builder UI"]
FROUNT["FROUNT<br/>customer UI"]
EXT([External integrators])
HOOKS([Third-party webhooks])
subgraph framework [Framework runtime - in scope]
XENTRY[xlyEntry]
XAPI[xlyApi]
XIF[xlyInterface]
XFLOW[xlyFlow]
XPLC[xlyPlc]
XMSG[/"xlyMsg<br/>library"/]
end
DB[("MySQL<br/>xlyweberp_*")]
REDIS[(Redis)]
AMQ([ActiveMQ])
XEJMSC[xlyErpJmsConsumer]
PLAT[("xlyPlat* modules<br/>+ MongoDB")]:::oos
BACK --> XENTRY
FROUNT --> XENTRY
FROUNT --> XAPI
EXT --> XAPI
HOOKS --> XIF
XENTRY --> DB
XAPI --> DB
XIF --> DB
XFLOW --> DB
XPLC --> DB
XENTRY -- "@CacheEvict on save<br/>(synchronous)" --> REDIS
XENTRY <-- "cache reads<br/>+ Shiro session" --> REDIS
XAPI <--> REDIS
XENTRY -- "domain events<br/>(NOT cache invalidation)" --> AMQ
AMQ --> XEJMSC
XEJMSC -- "PRO_ERPMERGEBASE*<br/>base-data merge" --> DB
XENTRY -. uses .-> XMSG
XIF -. uses .-> XMSG
PLAT -.-> DB
The dashed cluster (xlyPlat* + MongoDB) is the B2B printing-platform
tier — present in the build, but out of scope
for this wiki.
Note the two distinct paths between the runtime and Redis/ActiveMQ:
@CacheEvict is synchronous in the saving process and clears the
shared Redis store directly (cross-node coherence works through the
shared store). The JMS path is a separate base-data merge channel,
not cache invalidation — ConsumerChangeGdsModuleThread runs
PRO_ERPMERGEBASEGDSMODULE and similar procs. Both are documented in
cache invalidation on metadata change.
For the library inventory behind each box, see the Tech stack page.
Concept pages
These pages are intentionally short — each one explains one concept, with links to the vertical slices that exercise it. Concepts pages should stay short; if one grows past a screenful, that's a sign the content wants to be a slice instead.
- The data-driven thesis — why the framework looks the way it does.
- Modules, forms, virtual tables — the three core nouns.
- Master / slave document pattern — header/lines, everywhere.
- No-FK, semantic-FK reality — how relations actually work.
- Two customization channels — metadata edits vs. SQL scripts.
- Customization layers — within Channel 1, how base / per-tenant / per-user overlays merge.
-
Multi-tenancy and product editions — row scoping (
sBrandsId,sSubsidiaryId) plus licence-gated module discovery. - The metadata-driven request lifecycle — the diagram you'll come back to.
-
The three API tiers — internal (
xlyEntry), external (xlyApi), inbound webhooks (xlyInterface).