feat: premium tier features — auto-backup scheduling, resource alerting, bundled workflows, one-click revert, notification manager
This commit is contained in:
@@ -39,6 +39,13 @@ let dockerMaintenance, logDigest;
|
||||
try { dockerMaintenance = require('../docker-maintenance'); } catch (_) { /* optional module */ }
|
||||
try { logDigest = require('../log-digest'); } catch (_) { /* optional module */ }
|
||||
|
||||
// Workflow engine (bundled workflows)
|
||||
let bundledWorkflowsModule;
|
||||
let workflowEngine = null;
|
||||
try {
|
||||
bundledWorkflowsModule = require('../bundled-workflows');
|
||||
} catch (_) { /* optional module */ }
|
||||
|
||||
// Templates
|
||||
const { APP_TEMPLATES, TEMPLATE_CATEGORIES, DIFFICULTY_LEVELS } = require('../app-templates');
|
||||
const { RECIPE_TEMPLATES, RECIPE_CATEGORIES } = require('../recipe-templates');
|
||||
@@ -69,6 +76,7 @@ const recipesRoutes = require('../routes/recipes');
|
||||
const themesRoutes = require('../routes/themes');
|
||||
const dockerResourcesRoutes = require('../routes/docker-resources');
|
||||
const eventsRoutes = require('../routes/events');
|
||||
const workflowsRoutes = require('../routes/workflows');
|
||||
|
||||
// Constants
|
||||
const { APP } = require('../constants');
|
||||
@@ -308,9 +316,55 @@ async function createApp() {
|
||||
app,
|
||||
});
|
||||
|
||||
// Initialize workflow engine if bundled-workflows is available
|
||||
if (bundledWorkflowsModule && ctx.docker) {
|
||||
try {
|
||||
const { WorkflowEngine } = bundledWorkflowsModule;
|
||||
const workflowCtx = {
|
||||
docker: ctx.docker,
|
||||
notification: ctx.notification,
|
||||
backupManager: ctx.backupManager,
|
||||
resourceMonitor: ctx.resourceMonitor,
|
||||
servicesStateManager: ctx.servicesStateManager
|
||||
};
|
||||
workflowEngine = new WorkflowEngine(workflowCtx);
|
||||
ctx.workflowEngine = workflowEngine;
|
||||
log.info('app', 'Workflow engine initialized');
|
||||
} catch (err) {
|
||||
log.error('app', 'Failed to initialize workflow engine', { error: err.message });
|
||||
}
|
||||
}
|
||||
|
||||
// Build versioned API router
|
||||
const apiRouter = express.Router();
|
||||
|
||||
|
||||
// Wire up notification listeners for resourceMonitor and backupManager
|
||||
if (ctx.notification && ctx.resourceMonitor) {
|
||||
ctx.resourceMonitor.on('alert', (alertData) => {
|
||||
ctx.notification.sendAlert(alertData).catch(err => {
|
||||
log.error('notification', 'Failed to send alert', { error: err.message });
|
||||
});
|
||||
});
|
||||
ctx.resourceMonitor.on('auto-restart', (data) => {
|
||||
ctx.notification.sendServiceEvent('auto-restart', data).catch(err => {
|
||||
log.error('notification', 'Failed to send auto-restart notification', { error: err.message });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (ctx.notification && ctx.backupManager) {
|
||||
ctx.backupManager.on('backup-complete', (data) => {
|
||||
ctx.notification.send('backup-complete', data).catch(err => {
|
||||
log.error('notification', 'Failed to send backup-complete', { error: err.message });
|
||||
});
|
||||
});
|
||||
ctx.backupManager.on('backup-failed', (data) => {
|
||||
ctx.notification.send('backup-failed', data).catch(err => {
|
||||
log.error('notification', 'Failed to send backup-failed', { error: err.message });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Mount route modules
|
||||
apiRouter.use(authRoutes(ctx));
|
||||
apiRouter.use(configRoutes(ctx));
|
||||
@@ -361,7 +415,8 @@ async function createApp() {
|
||||
resourceMonitor: ctx.resourceMonitor,
|
||||
docker: ctx.docker,
|
||||
asyncHandler: ctx.asyncHandler,
|
||||
log: ctx.log
|
||||
log: ctx.log,
|
||||
notificationManager: ctx.notification
|
||||
}));
|
||||
apiRouter.use(updatesRoutes({
|
||||
updateManager: ctx.updateManager,
|
||||
@@ -404,6 +459,7 @@ async function createApp() {
|
||||
}));
|
||||
apiRouter.use(backupsRoutes({
|
||||
backupManager: ctx.backupManager,
|
||||
licenseManager: ctx.licenseManager,
|
||||
asyncHandler: ctx.asyncHandler
|
||||
}));
|
||||
apiRouter.use('/ca', caRoutes(ctx));
|
||||
@@ -434,6 +490,11 @@ async function createApp() {
|
||||
updateManager: ctx.updateManager,
|
||||
logError: ctx.logError
|
||||
}));
|
||||
apiRouter.use(workflowsRoutes({
|
||||
workflowEngine: ctx.workflowEngine,
|
||||
licenseManager: ctx.licenseManager,
|
||||
asyncHandler: ctx.asyncHandler
|
||||
}));
|
||||
|
||||
// Inline API routes
|
||||
apiRouter.get('/health', (req, res) => {
|
||||
|
||||
Reference in New Issue
Block a user