You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
To add a new core setting group (managed directly by the application):
507
507
508
508
1.**Create Setting File**: Add a new `.ts` file in `src/global-settings/`
509
509
@@ -691,6 +691,17 @@ The new group-based system replaces the old category-based approach. The migrati
691
691
2.**Auto-Initialization**: Groups are created automatically from setting definitions
692
692
3.**Setting Linking**: Existing settings are linked to appropriate groups
693
693
694
+
## Plugin-Contributed Global Settings
695
+
696
+
In addition to core global settings, plugins can also define and register their own global settings and setting groups. These are managed through the same system and are subject to the same access controls (i.e., editable by `global_admin`).
697
+
698
+
Key points for plugin-contributed settings:
699
+
700
+
-**Declaration**: Plugins declare global settings via a `globalSettingsExtension` property in their main class.
701
+
-**Initialization**: The `PluginManager` processes these definitions at startup, creating new groups and settings if they don't already exist.
702
+
-**Precedence**: Core global settings always take precedence. If a plugin tries to define a setting with a key that already exists (either from core or another plugin), the plugin's definition for that specific key is ignored.
703
+
-**Documentation**: For details on how plugins can define global settings, refer to the [PLUGINS.MD](PLUGINS.MD) document.
Copy file name to clipboardExpand all lines: services/backend/PLUGINS.md
+107Lines changed: 107 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -210,6 +210,7 @@ Plugins receive access to:
210
210
-**Fastify instance** (`app`) - For registering routes, hooks, and decorations
211
211
-**Database instance** (`db`) - For database operations
212
212
-**Configuration** - Through the plugin manager (if provided)
213
+
-**Global Settings** - Plugins can define their own global settings
213
214
214
215
## Plugin Lifecycle
215
216
@@ -308,6 +309,112 @@ See the `plugins/example-plugin` directory for a working example.
308
309
309
310
The complete Plugin interface is defined in `src/plugin-system/types.ts`.
310
311
312
+
## Defining Global Settings via Plugins
313
+
314
+
Plugins can contribute their own global settings to the DeployStack system. These settings will be managed alongside core global settings and will be editable by users with the `global_admin` role.
315
+
316
+
### How it Works
317
+
318
+
1.**Define `globalSettingsExtension`**: In your plugin class, add an optional property `globalSettingsExtension`.
319
+
2.**Structure**: This property should be an object implementing the `GlobalSettingsExtension` interface (defined in `src/plugin-system/types.ts`). It can contain:
320
+
321
+
-`groups`: An optional array of `GlobalSettingGroupForPlugin` objects to define new setting groups.
322
+
-`settings`: A mandatory array of `GlobalSettingDefinitionForPlugin` objects to define individual settings.
323
+
324
+
3.**Initialization**: During server startup, the `PluginManager` will:
325
+
326
+
- Collect all group and setting definitions from active plugins.
327
+
- Create any new groups defined by plugins if they don't already exist. If a group ID already exists, the plugin's group definition is ignored for that specific group, and the existing group is used.
328
+
- Initialize the plugin's global settings with their default values, but only if a setting with the same key doesn't already exist (either from core settings or another plugin). Core settings always take precedence.
329
+
330
+
4.**Access Control**: All plugin-defined global settings are subject to the same access control as core settings (i.e., manageable by `global_admin`).
331
+
332
+
5.**Security**:
333
+
334
+
-**Core Precedence**: Core global settings (defined in `services/backend/src/global-settings/`) cannot be overridden by plugins.
335
+
-**Duplicate Keys**: If a plugin attempts to register a setting with a key that already exists (from core or another plugin), the plugin's setting will be ignored, and a warning will be logged.
// You can try to access your plugin's settings here if needed during init,
402
+
// using GlobalSettingsService.get('myAwesomePlugin.features.enableSuperFeature')
403
+
// Note: Ensure GlobalSettingsService is available or handle potential errors.
404
+
}
405
+
}
406
+
407
+
exportdefaultMyAwesomePlugin;
408
+
```
409
+
410
+
### Important Considerations
411
+
412
+
-**Key Uniqueness**: Ensure your setting keys are unique, preferably prefixed with your plugin ID (e.g., `yourPluginId.category.settingName`) to avoid conflicts.
413
+
-**Group IDs**: If defining new groups, ensure their IDs are unique.
414
+
-**Default Values**: Provide sensible default values.
415
+
-**Encryption**: Mark sensitive settings (API keys, passwords) with `encrypted: true`.
416
+
-**Documentation**: Document any global settings your plugin introduces in its own README or documentation.
417
+
311
418
---
312
419
313
420
For additional questions or support, please contact the DeployStack team or open an issue on GitHub.
// Attempt to create the group if it doesn't exist.
325
+
awaitGlobalSettingsService.createGroup(group);
326
+
console.log(`[PluginManager] Created global setting group ID '${group.id}' (Name: "${group.name}") as defined by a plugin.`);
327
+
}else{
328
+
// Group ID already exists. Log that the plugin's definition for this group ID (name, description, etc.) is ignored.
329
+
console.warn(`[PluginManager] Global setting group ID '${group.id}' already exists (Existing Name: "${existingGroup.name}"). Plugin's attempt to define a group with this ID (Plugin's proposed Name: "${group.name}") will use the existing group. Plugin-specific metadata for this group ID (name, description, icon, sort_order) is ignored.`);
330
+
}
331
+
}catch(error){
332
+
console.error(`[PluginManager] Error processing plugin-defined group '${group.id}' (Plugin's proposed Name: "${group.name}"):`,error);
333
+
}
334
+
}
335
+
336
+
// Initialize settings
337
+
constinitializedKeys=newSet<string>();
338
+
// First, get all existing core setting keys to ensure precedence
0 commit comments