feat: Migrate legacy Slack settings to group-specific plugin settings…#40
Open
SerVitasik wants to merge 4 commits intomainfrom
Open
feat: Migrate legacy Slack settings to group-specific plugin settings…#40SerVitasik wants to merge 4 commits intomainfrom
SerVitasik wants to merge 4 commits intomainfrom
Conversation
… and enhance plugin management
There was a problem hiding this comment.
Pull request overview
This PR migrates legacy per-group Slack configuration into a generalized group-specific plugin settings model, then updates backend dispatch + API + UI to support installing/configuring plugins per host group.
Changes:
- Introduces
groupPluginSettingspersistence + migration from legacyhostGroups[*].slackSettings/slackWebhook. - Updates PluginManager to merge per-group overrides into per-plugin settings at runtime and initialize plugins referenced by groups.
- Updates API + frontend Plugins UI to manage group-installed plugins (list/configure/remove) and removes Slack-specific fields from host groups.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 12 comments.
Show a summary per file
| File | Description |
|---|---|
| server/src/database.js | Adds groupPluginSettings defaulting and migrates legacy Slack group fields into the new structure. |
| server/src/utils.js | Changes HOST_GROUP payload to expose pluginSettings keyed by pluginId. |
| server/src/pluginManager.js | Merges global + group plugin settings during dispatch and adjusts plugin initialization logic. |
| server/src/plugins/slack.js | Removes bespoke group override logic and relies on PluginManager-merged settings. |
| server/src/apinext.js | Adds group plugin settings read/write, group plugin removal endpoint, and updates group payloads. |
| server/frontend/src/Components/Plugins/Plugins.jsx | Enhances UI to display group-installed plugins and allow per-group settings/removal/add. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+44
to
+49
| db.data.groupPluginSettings.push({ | ||
| groupId: group.id, | ||
| pluginId: 'slack-notifications', | ||
| params: group.slackSettings?.params || (group.slackWebhook ? { webhook: group.slackWebhook } : {}), | ||
| enabledEvents: group.slackSettings?.enabledEvents || [], | ||
| }); |
Comment on lines
+776
to
+782
| if (isNew) { | ||
| database.data.groupPluginSettings.push(entry); | ||
| // init plugin if not globally enabled | ||
| const globallyEnabled = database.data.pluginSettings.find((ps) => ps.id === plugin.id)?.enabled; | ||
| if (!globallyEnabled) await plugin.onPluginEnabled?.(); | ||
| } else { | ||
| database.data.groupPluginSettings[idx] = entry; |
Comment on lines
+220
to
+222
| return { plugin: p, settings }; | ||
| }) | ||
| .filter((p) => p.settings.enabled && enabledPluginsArr.includes(p.plugin.id)); |
Comment on lines
143
to
147
| const pass = | ||
| p.settings.enabled && | ||
| effectiveEnabled && | ||
| effectiveEnabledEvents?.includes(eventType) && | ||
| !hostEvents.includes(eventType) && | ||
| enabledPlugins.includes(p.plugin.id); |
Comment on lines
700
to
705
| const pluginSettings = group | ||
| ? { | ||
| ...globalPluginSettings, | ||
| params: group.slackSettings?.params || {}, | ||
| enabledEvents: group.slackSettings?.enabledEvents || globalPluginSettings?.enabledEvents || [], | ||
| params: groupPluginEntry?.params || {}, | ||
| enabledEvents: groupPluginEntry?.enabledEvents || globalPluginSettings?.enabledEvents || [], | ||
| enabled: globalPluginSettings?.enabled, | ||
| } |
Comment on lines
+769
to
774
| const entry = { | ||
| groupId, | ||
| pluginId: plugin.id, | ||
| params: input.params || {}, | ||
| enabledEvents: input.events ? Object.keys(input.events) : [], | ||
| }; |
Comment on lines
+37
to
+55
| // Migrate legacy slackSettings/slackWebhook from group objects to groupPluginSettings | ||
| for (const group of db.data.hostGroups) { | ||
| if (group.slackSettings || group.slackWebhook) { | ||
| const alreadyMigrated = db.data.groupPluginSettings.some( | ||
| (s) => s.groupId === group.id && s.pluginId === 'slack-notifications' | ||
| ); | ||
| if (!alreadyMigrated) { | ||
| db.data.groupPluginSettings.push({ | ||
| groupId: group.id, | ||
| pluginId: 'slack-notifications', | ||
| params: group.slackSettings?.params || (group.slackWebhook ? { webhook: group.slackWebhook } : {}), | ||
| enabledEvents: group.slackSettings?.enabledEvents || [], | ||
| }); | ||
| } | ||
| delete group.slackSettings; | ||
| delete group.slackWebhook; | ||
| delete group.channelName; | ||
| } | ||
| } |
Comment on lines
703
to
706
| enabledEvents: groupPluginEntry?.enabledEvents || globalPluginSettings?.enabledEvents || [], | ||
| enabled: globalPluginSettings?.enabled, | ||
| } | ||
| : globalPluginSettings; |
…d improving initialization logic
| const pluginSettings = {}; | ||
| (database.data.groupPluginSettings || []) | ||
| .filter((s) => s.groupId === g.id) | ||
| .forEach((s) => { pluginSettings[s.pluginId] = { params: s.params, enabledEvents: s.enabledEvents }; }); |
| await p.plugin.sendMessage(p.settings, rssFormatedMessage, webhookOverride); | ||
| await p.plugin.sendMessage(p.settings, rssFormatedMessage); | ||
| } catch (e) { | ||
| console.error("Error in plugin", p.id, e, "stack:", e.stack); |
| pluginId: 'slack-notifications', | ||
| params: group.slackSettings?.params || (group.slackWebhook ? { webhook: group.slackWebhook } : {}), | ||
| }; | ||
| // Only set enabledEvents if explicitly configured; null means inherit global |
Comment on lines
+773
to
+778
| const entry = { | ||
| groupId, | ||
| pluginId: plugin.id, | ||
| params: input.params || {}, | ||
| // undefined = inherit global enabledEvents; explicit array = group override | ||
| ...(input.events ? { enabledEvents: Object.keys(input.events) } : {}), |
Comment on lines
699
to
705
| // For group-specific settings, use group's own params (not the global ones) | ||
| const pluginSettings = group | ||
| ? { | ||
| ...globalPluginSettings, | ||
| params: group.slackSettings?.params || {}, | ||
| enabledEvents: group.slackSettings?.enabledEvents || globalPluginSettings?.enabledEvents || [], | ||
| params: groupPluginEntry?.params || {}, | ||
| enabledEvents: groupPluginEntry?.enabledEvents ?? globalPluginSettings?.enabledEvents ?? [], | ||
| enabled: globalPluginSettings?.enabled, | ||
| } |
…iguration and enhancing error logging
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
… and enhance plugin management