# Metadata-management services (`xlyManage`) The `xlyManage` module is the **service tier behind the BACK builder**. When a PM clicks 修改 / 新增 / 删除 in any of the 系统模块配置 / 界面显示内容配置 / 数据表内容配置 / 系统权限配置 / 系统常量配置 / 用户信息配置 / Mysql脚本配置 screens, the call lands on a `Gds*Controller` in `xlyEntry/.../web/systemweb/`, which then delegates to a `Gds*ServiceImpl` in `xlyManage/src/main/java/com/xly/service/systeminfo/impl/`. These services are the framework's **metadata-CRUD spine** — they own the read/write logic for every `gds*` table. The runtime ([Slice 1](../../slices/01-hello-world.md), [runtime.md](runtime.md)) *reads* metadata; `xlyManage` *writes* it. ## Services at a glance | Service | Lines | Owns | BACK page | |---|---:|---|---| | `GdsmoduleServiceImpl` | 729 | `gdsmodule` (modules), `gdsroute` (URL whitelist), module-tree CRUD, edition gating | 系统模块配置 | | `GdsconfigformServiceImpl` | 878 | `gdsconfigformmaster`, `gdsconfigformslave`, `gdsconfigformcustomslave`, `gdsconfigformpersonalize` (form definitions + per-tenant overlays) | 界面显示内容配置 | | `GdsconfigtbServiceImpl` | 555 | `gdsconfigtbmaster`, `gdsconfigtbslave` (virtual-table definitions) | 数据表内容配置 | | `SqlScriptsServiceImpl` | 489 | DDL / proc / view scripts authored in BACK; uses templates from [`templesql/`](sql-templates.md) | Mysql脚本配置 | | `GdsjurisdictionServiceImpl` | 362 | `gdsjurisdiction` (the action *catalogue* per module — see [permissions](../builder/permissions.md)) | (part of 系统权限配置 + builder flows) | | `GdsparameterServiceImpl` | 319 | `gdsparameter` (system-wide parameters) | (parameter screens) | | `GdsformconstServiceImpl` | 243 | `gdsformconst` (per-form constants — labels, default text). Slice 1 anchor table. | 系统常量配置 | | `GdslogininfoServiceImpl` | 221 | `sftlogininfo*` family (user / login / group catalogue) | 用户信息配置 | | `SysbrandsServiceImpl` | 125 | `sysbrands` (manufacturer / tenant master) | (tenant admin) | | `CommonServiceImpl` | 56 | shared helpers used across the rest | n/a | Total: ~4,000 lines of metadata-CRUD logic — a meaningful share of the framework runtime that this wiki had previously left undocumented. ## Method-shape convention Every `Gds*Service` follows the same five-method shape: ```java Feedback> getXxx(Map params); // list / paged read Feedback> getXxxBysId(Map params); // single-row read Feedback> addXxx(Map params); // insert Feedback> updateXxx(Map params); // update Feedback> deleteXxx(Map params); // delete (often soft, via bInvalid) ``` — mirrored exactly by the corresponding `Gds*Controller`'s endpoint methods. So the BACK admin surface is essentially a thin pass-through: controllers in `xlyEntry/.../systemweb/`, services in `xlyManage/.../systeminfo/impl/`. This is the inverse of the runtime side ([runtime.md](runtime.md)), where one universal `BusinessBaseController` handles every business-data CRUD against any table the metadata names — here, every framework-metadata CRUD has its own dedicated controller+service pair. ## Notable specifics - **`GdsconfigformServiceImpl` is the largest** because it owns four closely-coupled tables (form-master, form-slave, customslave, personalize) plus the **DDL-script generation** flow. Methods like `getFormslaveScriptSqlPro` and `getMasterSlaveScriptSqlPro` produce SQL that an engineer can apply against the underlying physical tables when adding fields. This is what makes the customization-overlay model ([Slice 4](../../slices/04-custom-field.md)) end-to-end usable: the BACK builder can also generate the schema-migration SQL the overlay implies. - **`GdsmoduleServiceImpl` includes `getModuleTreePro`** — the per-edition / per-tenant module-tree resolution called by the SPA at login (the first `/gdsmodule/getModuleTreePro` request you see in the live trace). Edition gating ([Slice 2](../../slices/02-multi-tenancy.md)) happens here, as a filter on `gdsmodule.sVersionFlowId` against the user's `sisversionflow` row. - **`SqlScriptsServiceImpl`** glues the [`templesql/`](sql-templates.md) scaffolds into the BACK script authoring screen. Engineers fill in the placeholder spec; the service materialises a compilable proc/view body and runs it against the connected schema. - **`GdsjurisdictionServiceImpl` writes the action *catalogue***; `sysjurisdiction` (the per-user grant table) is written elsewhere (in `xlyBusinessService`'s permission-admin flow). See [How to set permissions](../builder/permissions.md) for the catalogue-vs-grant distinction. - **`SysbrandsServiceImpl`** writes the tenant master (`sysbrands` + `sBrandsId` rows); a fresh tenant onboarding flow is essentially a row insert here plus seed metadata. ## Cache-invalidation hookpoints Every write through these services synchronously calls `BusinessCleanRedisData.delCleanRedisData*` on commit. This is why metadata edits in BACK take effect immediately on every node — the shared Redis cache (RedisCacheManager, see [cache-invalidation.md](cache-invalidation.md)) gets the relevant regions evicted in the same transaction the write commits. There is **no JMS fan-out here for cache-bust** — that's a common misconception, addressed in detail on the cache-invalidation page. ## What's *not* in `xlyManage` - **Business-data CRUD.** That's the universal `BusinessBaseController` + `BusinessBaseServiceImpl` path ([runtime.md](runtime.md), [Slice 1](../../slices/01-hello-world.md)). - **API metadata** (`sysapi`). That's `xlyApi`'s own admin surface — see [external API](../../api-reference/external.md). - **Workflow metadata** (`gdsmoduleflow`, `act_*`, `biz_flow`). That's in `xlyFlow` — see [activiti.md](activiti.md). ## Where to look first when something breaks | Symptom | First place to look | |---|---| | BACK 修改/新增 against `gdsconfigform*` returns "操作失败" | `GdsconfigformServiceImpl` — check field validation + the matching DDL-script generation path | | Edition gating shows wrong modules | `GdsmoduleServiceImpl.getModuleTreePro` — verify the user's `sVersionFlowId` resolution | | BACK script-authoring screen produces broken SQL | `SqlScriptsServiceImpl` + the [templesql scaffolds](sql-templates.md) | | Permission catalogue (BtnAdd / BtnUpd / …) missing for a module | `GdsjurisdictionServiceImpl` — check the rows under that `sParentId` | | User can log in to BACK but FROUNT is empty | `GdslogininfoServiceImpl` — check the `sftlogininfo*` link tables |