Settings Editor
The Settings Editor edits the backend and frontend configuration stored on one layer of the configuration cascade. Each project, tenant and application owns a settings row; each (tenant, application) enablement can own one too. The Manager merges these layers when it serves configuration to a running frontend or backend. Use the editor to set shared defaults high up and narrow overrides low down.
The layers
| Layer | Where you edit it |
|---|---|
| Project | /<project>/settings, sidebar Project settings |
| Tenant | /<project>/<tenant>/settings, sidebar Tenant settings |
| Application | /<project>/applications/<app>/settings, sidebar Application settings |
| (Tenant, Application) | The Configure button on the tenant page or the application page's Tenant access card opens Per-tenant configuration: Frontend and Backend key-value pairs only |
How the layers combine when the Manager resolves the frontend configuration for a tenant using an application:
Project → Application (module fields only) → Tenant → (Tenant, Application)Later layers win. Merge rules per field:
AvailableModules,AvailableThemes,AvailableLocales: union of all layers.EnabledModules,EnabledThemes,EnabledLocales: a non-empty list replaces the inherited list; an empty list inherits.DefaultTheme,DefaultLocale: a non-empty value replaces; empty inherits.KeyValuePairs: merged by key; the later layer's value wins.
The application layer contributes only its module fields to the tenant-scoped frontend config. Backend communications settings cascade project → tenant → (tenant, application). Built-in defaults before any layer: DefaultTheme: "light", AvailableLocales: ["en"], EnabledLocales: ["en"], DefaultLocale: "en". See Configuration Layers.
The page
The header has a toggle: GUI Editor (default) or JSON Editor. On the left, Configuration Layers lists the layers that apply to the page you are on (Project Settings, Tenant Settings, Application Settings) with an Override badge on layers that set values, and Inheritance Chain shows their order. The main area has two tabs, Backend and Frontend.
Reading a layer needs a membership that reaches it: Project settings and Application settings need membership of the project; Tenant settings and the tenant2application selector need membership of the tenant or of its project. A system administrator reads every layer without a membership. Writing (updateBackendModuleConfig / updateFrontendModuleConfig) is a higher bar: project maintainer or owner, the system administrator role, or, for the tenant-owned layers, the tenant.apps.configure permission in that tenant. Backend key-value pairs and module lists are readable only at the write bar; see Configuration Layers.
GUI Editor
Every change in GUI mode is saved immediately and confirmed with a notification (Backend settings updated successfully / Frontend settings updated successfully).
Backend tab, Backend configuration
- Modules: Select modules to enable (multi-select over the available modules) and Add Module (asks for a Module Name; the module is added to
AvailableModules). Each module row has a remove action. - Key-Value pairs: Add Key-Value Pair opens a dialog with Key and Value; Save stores it. Rows have edit and delete actions. The key of an existing pair cannot be changed; delete and re-add it.
- Communications: the notification channel for this layer: Communications enabled, Email channel (Sender address, Subject prefix, Layout template), Delivery timing (Grace window (minutes)), and Send test notification. Fields left empty inherit from the layer above.
Frontend tab, Frontend configuration
- Modules: the same module selector. A frontend module can carry a version as
name@version(for exampledashboard@1.2.0); the version is shown as a badge. - Themes: a table with Theme, Enabled?, Default? and Actions; Add Theme asks for a Theme Name. Only an enabled theme can be the default.
- Locales: a table with Locale, Enabled?, Default? and Actions; Add Locale asks for a Locale Code (e.g., en, es).
- Key-Value pairs: as on the backend tab.
JSON Editor
Switch the header toggle to JSON Editor. Each tab shows one document, Backend configuration (JSON) or Frontend configuration (JSON), with Reset to original and Save changes buttons. Invalid JSON is flagged (Invalid JSON, JSON cannot be empty) and cannot be saved.
Backend document:
{
"AvailableModules": ["auth", "api", "analytics"],
"EnabledModules": ["auth", "api"],
"KeyValuePairs": [
{ "Key": "api_version", "Value": "v2" },
{ "Key": "rate_limit", "Value": "1000" }
]
}The backend JSON view edits these three fields; the Communications block is edited only through the GUI section.
Frontend document:
{
"AvailableModules": ["dashboard@1.2.0", "reports@2.0.1"],
"EnabledModules": ["dashboard", "reports"],
"AvailableThemes": ["light", "dark"],
"EnabledThemes": ["light", "dark"],
"DefaultTheme": "light",
"AvailableLocales": ["en", "es"],
"EnabledLocales": ["en", "es"],
"DefaultLocale": "en",
"KeyValuePairs": [
{ "Key": "app_title", "Value": "My Dashboard" }
]
}API
Read a layer with the settings query, passing exactly one selector:
query {
settings(application: "app-uuid") {
id
backendSetting {
id
moduleConfig { AvailableModules EnabledModules KeyValuePairs { Key Value } }
}
frontendSetting {
id
moduleConfig {
AvailableModules EnabledModules
AvailableThemes EnabledThemes DefaultTheme
AvailableLocales EnabledLocales DefaultLocale
KeyValuePairs { Key Value }
}
}
}
}Selectors: project, tenant, application, tenant2application (the join row id from tenant2Applications). Pass exactly one; the selectors are combined with AND, and a settings row has a single owner, so two selectors never match.
Write with the two module-config mutations, using the backendSetting.id / frontendSetting.id from the query:
mutation {
updateFrontendModuleConfig(
id: "frontend-settings-uuid"
input: { DefaultTheme: "dark", EnabledThemes: ["light", "dark"] }
) {
id
moduleConfig { DefaultTheme EnabledThemes }
}
}mutation {
updateBackendModuleConfig(
id: "backend-settings-uuid"
input: { KeyValuePairs: [{ Key: "rate_limit", Value: "1000" }] }
) {
id
moduleConfig { KeyValuePairs { Key Value } }
}
}ModuleConfigInput also accepts a Communications block; omit it to leave the stored block untouched.
Common tasks
Copy settings between layers
- Open the source layer, switch to JSON Editor, copy the Backend and Frontend documents.
- Open the target layer, switch to JSON Editor, paste, adjust, Save changes.
Reset a layer so it inherits everything
Save empty lists and empty strings; the merge treats them as "no opinion":
{ "AvailableModules": [], "EnabledModules": [], "KeyValuePairs": [] }Add many key-value pairs at once
Use the JSON Editor and add them to KeyValuePairs in one save. In GUI mode you add them one at a time.
Troubleshooting
A change does not show up in the application
- Look at Configuration Layers on the page: a more specific layer (tenant or the (tenant, application) leaf) may override yours.
Enabled*lists replace rather than merge: an enabled list on a lower layer hides the project's list completely.- The running frontend fetches its configuration on load; reload it.
The frontend config request returns 404
The application is not enabled for that tenant. Enable it on the tenant page. See Managing Tenants.
JSON validation error
Look for a trailing comma, an unquoted key, or unmatched brackets. Switch back to GUI Editor if in doubt.