import { objectSchema } from '../../kernel/input-schema.mjs'; import { getModuleManagerService } from './index.mjs'; const toggleSchema = objectSchema({ cascade: { type: 'boolean' }, }); export function registerModuleManagerRoutes({ app, routes, upload, deps }) { routes.register(app, { id: 'modules.catalog.read', method: 'GET', path: '/api/admin/modules', owner: 'vendoo.module-manager', policy: 'modules.manage', audit: 'modules.catalog.read', rateLimit: 'administration', csrf: false, stability: 'stable', handler: async (_req, res) => res.json(getModuleManagerService().catalog()), }); routes.register(app, { id: 'modules.enable', method: 'POST', path: '/api/admin/modules/:id/enable', owner: 'vendoo.module-manager', policy: 'modules.manage', audit: 'modules.enabled', rateLimit: 'administration', csrf: true, stability: 'stable', handler: async (req, res) => { const module = await getModuleManagerService().enable(req.params.id); deps.auditLog(req.user.id, req.user.email, 'module.enabled', 'module', req.params.id, null, deps.getClientIp(req)); res.json({ module }); }, }); routes.register(app, { id: 'modules.disable', method: 'POST', path: '/api/admin/modules/:id/disable', owner: 'vendoo.module-manager', policy: 'modules.manage', audit: 'modules.disabled', rateLimit: 'administration', csrf: true, stability: 'stable', input: toggleSchema, handler: async (req, res) => { const result = await getModuleManagerService().disable(req.params.id, req.validatedBody || {}); deps.auditLog(req.user.id, req.user.email, 'module.disabled', 'module', req.params.id, JSON.stringify(result.disabled), deps.getClientIp(req)); res.json(result); }, }); routes.register(app, { id: 'modules.install', method: 'POST', path: '/api/admin/modules/install', owner: 'vendoo.module-manager', policy: 'modules.manage', audit: 'modules.installed', rateLimit: 'administration', csrf: true, stability: 'stable', middleware: [upload.single('module')], handler: async (req, res) => { const module = getModuleManagerService().install(req.file?.buffer); deps.auditLog(req.user.id, req.user.email, 'module.installed', 'module', module.id, module.version, deps.getClientIp(req)); res.status(201).json({ module }); }, }); routes.register(app, { id: 'modules.remove', method: 'DELETE', path: '/api/admin/modules/:id', owner: 'vendoo.module-manager', policy: 'modules.manage', audit: 'modules.removed', rateLimit: 'administration', csrf: true, stability: 'stable', handler: async (req, res) => { const result = await getModuleManagerService().remove(req.params.id); deps.auditLog(req.user.id, req.user.email, 'module.removed', 'module', req.params.id, null, deps.getClientIp(req)); res.json(result); }, }); routes.register(app, { id: 'modules.export', method: 'GET', path: '/api/admin/modules/:id/export', owner: 'vendoo.module-manager', policy: 'modules.manage', audit: 'modules.exported', rateLimit: 'administration', csrf: false, stability: 'stable', handler: async (req, res) => { const payload = getModuleManagerService().export(req.params.id); deps.auditLog(req.user.id, req.user.email, 'module.exported', 'module', req.params.id, null, deps.getClientIp(req)); res.setHeader('Content-Type', 'application/vnd.vendoo.module+json; charset=utf-8'); res.setHeader('Content-Disposition', `attachment; filename="${String(req.params.id).replace(/[^a-z0-9.-]/gi, '_')}.vmod"`); res.send(payload); }, }); }