const express = require('express'); const { ok } = require('../src/utils/responses'); const { ValidationError } = require('../src/utilities/errors'); /** * Validate a workflow ID. * @param {string} workflowId - Workflow ID from route param * @throws {ValidationError} if the ID contains unsafe characters */ function validateWorkflowId(workflowId) { if (!workflowId || typeof workflowId !== 'string') { throw new ValidationError('Workflow ID is required'); } if (!/^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$/.test(workflowId)) { throw new ValidationError('Invalid workflow ID format'); } } /** * Workflows routes factory * @param {Object} deps - Explicit dependencies * @param {Object} deps.workflowEngine - WorkflowEngine instance * @param {Object} deps.licenseManager - License manager for premium gating * @param {Function} deps.asyncHandler - Async route handler wrapper * @param {Function} deps.ok - Success response helper * @returns {express.Router} */ module.exports = function({ workflowEngine, licenseManager, asyncHandler, ok }) { const router = express.Router(); // Apply premium gating to all workflows routes router.use(licenseManager.requirePremium('workflows')); // ===== WORKFLOW MANAGEMENT ENDPOINTS ===== // List all bundled workflows router.get('/workflows', asyncHandler(async (req, res) => { const workflows = workflowEngine.listWorkflows(); ok(res, { workflows }); }, 'workflows-list')); // Enable a workflow router.post('/workflows/:workflowId/enable', asyncHandler(async (req, res) => { const { workflowId } = req.params; validateWorkflowId(workflowId); const result = workflowEngine.setWorkflowEnabled(workflowId, true); ok(res, result); }, 'workflows-enable')); // Disable a workflow router.post('/workflows/:workflowId/disable', asyncHandler(async (req, res) => { const { workflowId } = req.params; validateWorkflowId(workflowId); const result = workflowEngine.setWorkflowEnabled(workflowId, false); ok(res, result); }, 'workflows-disable')); // Manually trigger a workflow router.post('/workflows/:workflowId/run', asyncHandler(async (req, res) => { const { workflowId } = req.params; validateWorkflowId(workflowId); const triggerData = req.body || {}; triggerData.trigger = 'manual'; const result = await workflowEngine.executeWorkflow(workflowId, triggerData); ok(res, { result }); }, 'workflows-run')); // Get execution history for a workflow router.get('/workflows/:workflowId/history', asyncHandler(async (req, res) => { const { workflowId } = req.params; const limit = parseInt(req.query.limit) || 50; const history = workflowEngine.getHistory(workflowId, limit); ok(res, { history }); }, 'workflows-history')); // Get all workflow execution history router.get('/workflows/history', asyncHandler(async (req, res) => { const limit = parseInt(req.query.limit) || 100; const history = workflowEngine.getHistory(null, limit); ok(res, { history }); }, 'workflows-all-history')); return router; };