Skip to main content

System Module Registry

Overview

system_module is the master table that declares which modules the platform is made of — campaign, rich-menu, form-builder, audiences, and so on. Every mechanism related to permissions or feature toggling refers back to this table:

  • system_role_module references module_id to express role-based permissions
  • organization_module references module_id to override permissions per organization
  • ModuleGate uses system_module.name as the key for checking whether a module is enabled

Because this is platform-level data, every endpoint in the module enforces SuperAdminGuard.

Business Flow

  1. A platform operator (roleId = 1) opens the module management screen in cms-web.
  2. GET /api/system-module lists all modules, with the soft-delete filter deleted_date IS NULL applied automatically.
  3. GET /api/system-module/list-all-object returns an {id: name} shape. The user module calls this FindAllObject function directly to translate module_id values into module names in the permission response.
  4. New modules are added with POST /api/system-module. The name must match exactly what ModuleGate(d, "module-name") uses, otherwise the gate will not find it.
  5. Updates and removals go through PUT /api/system-module/:id and DELETE /api/system-module/:id (soft delete).
  6. Additions and edits surface in the dropdown on the per-organization module settings screen, where platform admins enable or disable modules for each customer.

Parity note: the SystemModule entity genuinely has a @DeleteDateColumn, so GORM appends deleted_date IS NULL automatically via gorm.DeletedAt. However, update() and softDelete() must use Unscoped(), because TypeORM did not apply the filter in those two cases.

Key Files & Functions

The code lives in internal/modules/systemmodule/, consisting of controller.go, service.go, and dto.go.

MethodRouteHandlerPolicy (metadata)
GET/api/system-moduleh.findAllreadAll system_module
GET/api/system-module/list-all-objecth.findAllObjectreadAll system_module
GET/api/system-module/:idh.findOneread system_module
POST/api/system-moduleh.createcreate system_module
PUT/api/system-module/:idh.updateupdate system_module
DELETE/api/system-module/:idh.deletedelete system_module

Every route carries auth.SuperAdmin() as middleware, registered on authed.Group("/system-module").

The function other modules call is systemmodule.Service.FindAllObject(ctx), which returns a map from id to name.

Connections to Other Services

  • Permissionsauth.SuperAdmin() on every route: roleId must equal 1, otherwise the request is rejected with 403 Forbidden resource.
  • Tablessystem_module, referenced from system_role_module and organization_module
  • Consumers — CMS user management (through FindPermissionByUserID), per-organization module settings, and ModuleGate, which keys off name.
  • Note — the menu-builder module also uses PolicyModuleSystemModule as its policy metadata, carried over from the original TypeScript implementation.