Skip to main content

Module & Quota Settings per Organization (Platform Admin)

Overview

This module is the platform admin (onemoby) console for governing each customer organization. It does two things:

  1. Enable or disable modules for an organization by writing to organization_module, which overrides the baseline permissions inherited from the role.
  2. Set plan limits for an organization by writing to the organization.plan_limits JSONB column.

Disabling a module does more than hide a menu in cms-web: the server-side ModuleGate also returns 403 for direct API calls to that module, so the governance decision is genuinely enforced. Every endpoint here requires SuperAdminGuard.

Business Flow

  1. GET /api/org-module-setting/organizations lists all organizations for the platform admin to choose from.
  2. GET /api/org-module-setting/:orgId shows which modules the organization currently has enabled. The service merges two layers: the baseline from system_role_module and the overrides from organization_module.
  3. PUT /api/org-module-setting/:orgId accepts a {moduleIds, reset?} payload.
    • Sending moduleIds as the list of modules to enable overwrites organization_module.
    • Sending reset: true clears all overrides and reverts to the role baseline.
  4. From that point on, every request from a customer user in that organization is re-filtered:
    • GET /api/user/:id/permission returns the overridden set instead of the baseline, so the cms-web menu changes accordingly.
    • ModuleGate on a disabled module's routes responds with 403 ModuleDisabled.
  5. GET /api/org-module-setting/:orgId/limits and PUT /api/org-module-setting/:orgId/limits read and write quotas. Any value left unspecified falls back to DefaultPlanLimits.
  6. An unknown :orgId produces an organization-not-found error.

Key Files & Functions

The code lives in internal/modules/orgmodulesetting/, consisting of controller.go, service.go, and js.go.

MethodRouteHandler
GET/api/org-module-setting/organizationslistOrganizations
GET/api/org-module-setting/:orgIdgetOrgModules
PUT/api/org-module-setting/:orgIdsetOrgModules
GET/api/org-module-setting/:orgId/limitsgetOrgLimits
PUT/api/org-module-setting/:orgId/limitssetOrgLimits

All routes are registered on authed.Group("/org-module-setting", auth.SuperAdmin()).

Notable service functions:

  • ListOrganizations, GetOrgModules, SetOrgModules, GetOrgLimits, SetOrgLimits
  • IsModuleEnabledForOrg(ctx, orgID, moduleName) at service.go:291 is the shared resolver used by both modulegate.ModuleGate and user.FindPermissionByUserID, which guarantees the menu the user sees and the access the API enforces never diverge.

Connections to Other Services

  • Permissionsauth.SuperAdmin() (roleId == 1) on every route
  • Tablesorganization, organization_module, system_module, system_role_module
  • Cross-module — uses planlimits.Service to compute effective limits
  • Consumers of this resolver — the permission and module gate mechanism, and CMS user management
  • Original design specdocs/superpowers/specs/2026-07-26-platform-admin-design.md