const express = require('express'); const { body, param, query, validationResult } = require('express-validator'); const { authorize } = require('../middleware/auth'); const provisioningController = require('../controllers/provisioningController'); const router = express.Router(); // Validation middleware const handleValidationErrors = (req, res, next) => { const errors = validationResult(req); if (!errors.isEmpty()) { return res.status(400).json({ success: false, message: 'Validation failed', errors: errors.array() }); } next(); }; // Instance creation validation const instanceValidation = [ body('customerId') .isUUID() .withMessage('Customer ID must be a valid UUID'), body('name') .trim() .isLength({ min: 2, max: 50 }) .withMessage('Instance name must be 2-50 characters'), body('template') .trim() .notEmpty() .withMessage('Template is required'), body('size') .trim() .notEmpty() .withMessage('Instance size is required'), body('region') .trim() .notEmpty() .withMessage('Region is required'), body('specifications') .optional() .isObject() .withMessage('Specifications must be an object'), body('configuration') .optional() .isObject() .withMessage('Configuration must be an object'), body('tags') .optional() .isArray() .withMessage('Tags must be an array') ]; // Snapshot validation const snapshotValidation = [ body('name') .trim() .isLength({ min: 2, max: 50 }) .withMessage('Snapshot name must be 2-50 characters'), body('description') .optional() .trim() .isLength({ max: 255 }) .withMessage('Description must be less than 255 characters'), body('type') .optional() .isIn(['manual', 'automatic', 'backup']) .withMessage('Invalid snapshot type') ]; // UUID parameter validation const uuidValidation = [ param('instanceId') .isUUID() .withMessage('Instance ID must be a valid UUID') ]; // Query validation const queryValidation = [ query('page') .optional() .isInt({ min: 1 }) .withMessage('Page must be a positive integer'), query('limit') .optional() .isInt({ min: 1, max: 100 }) .withMessage('Limit must be between 1 and 100'), query('status') .optional() .isIn(['pending', 'creating', 'running', 'stopped', 'stopping', 'starting', 'failed', 'terminated']) .withMessage('Invalid status'), query('type') .optional() .isIn(['compute', 'storage', 'network', 'database']) .withMessage('Invalid instance type'), query('customerId') .optional() .isUUID() .withMessage('Customer ID must be a valid UUID'), query('region') .optional() .trim() .notEmpty() .withMessage('Region cannot be empty') ]; // All routes require authentication router.use(authorize('reseller')); // Instance management routes router.get('/', queryValidation, handleValidationErrors, provisioningController.getInstances); router.post('/', instanceValidation, handleValidationErrors, provisioningController.createInstance); // Instance control routes router.post('/:instanceId/start', uuidValidation, handleValidationErrors, provisioningController.startInstance); router.post('/:instanceId/stop', uuidValidation, handleValidationErrors, provisioningController.stopInstance); // Snapshot management router.post('/:instanceId/snapshots', [ ...uuidValidation, ...snapshotValidation ], handleValidationErrors, provisioningController.createSnapshot); // Instance events router.get('/:instanceId/events', [ ...uuidValidation, query('page') .optional() .isInt({ min: 1 }) .withMessage('Page must be a positive integer'), query('limit') .optional() .isInt({ min: 1, max: 100 }) .withMessage('Limit must be between 1 and 100') ], handleValidationErrors, provisioningController.getInstanceEvents); module.exports = router;