const express = require('express'); const { body, param, query, validationResult } = require('express-validator'); const { authorize } = require('../middleware/auth'); const { uploadMarketing } = require('../middleware/upload'); const marketingController = require('../controllers/marketingController'); 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(); }; // Asset validation const assetValidation = [ body('title') .trim() .isLength({ min: 2, max: 200 }) .withMessage('Title must be 2-200 characters'), body('type') .isIn(['logo', 'brochure', 'presentation', 'video', 'image', 'document', 'template', 'other']) .withMessage('Invalid asset type'), body('category') .isIn(['sales_collateral', 'pitch_deck', 'email_template', 'brand_assets', 'product_sheets', 'case_studies', 'other']) .withMessage('Invalid asset category'), body('description') .optional() .trim() .isLength({ max: 1000 }) .withMessage('Description must be less than 1000 characters'), body('accessLevel') .optional() .isIn(['public', 'reseller_only', 'tier_specific', 'admin_only']) .withMessage('Invalid access level'), body('tierAccess') .optional() .isArray() .withMessage('Tier access must be an array'), body('isEditable') .optional() .isBoolean() .withMessage('Is editable must be boolean'), body('tags') .optional() .isArray() .withMessage('Tags must be an array'), body('expiryDate') .optional() .isISO8601() .withMessage('Expiry date must be valid ISO 8601 date') ]; // Download validation const downloadValidation = [ body('purpose') .optional() .trim() .isLength({ max: 255 }) .withMessage('Purpose must be less than 255 characters') ]; // UUID parameter validation const uuidValidation = [ param('assetId') .isUUID() .withMessage('Asset 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('type') .optional() .isIn(['logo', 'brochure', 'presentation', 'video', 'image', 'document', 'template', 'other']) .withMessage('Invalid asset type'), query('category') .optional() .isIn(['sales_collateral', 'pitch_deck', 'email_template', 'brand_assets', 'product_sheets', 'case_studies', 'other']) .withMessage('Invalid asset category'), query('search') .optional() .trim() .isLength({ min: 2 }) .withMessage('Search query must be at least 2 characters') ]; // Public routes (no authentication required for some assets) router.get('/', queryValidation, handleValidationErrors, marketingController.getMarketingAssets); router.get('/categories', marketingController.getAssetCategories); // Protected routes (authentication required) router.use(authorize('reseller')); // Asset management router.get('/:assetId', uuidValidation, handleValidationErrors, marketingController.getAssetDetails); router.post('/:assetId/download', [ ...uuidValidation, ...downloadValidation ], handleValidationErrors, marketingController.downloadAsset); // Download history router.get('/user/downloads', marketingController.getDownloadHistory); // Admin routes (admin only) router.post('/admin/assets', [ authorize('reseller_admin'), uploadMarketing.single('assetFile'), ...assetValidation ], handleValidationErrors, marketingController.createMarketingAsset); module.exports = router;