diff --git a/controller/dev/DevManagementController.js b/controller/dev/DevManagementController.js new file mode 100644 index 0000000..e3b7914 --- /dev/null +++ b/controller/dev/DevManagementController.js @@ -0,0 +1,34 @@ +const DevManagementService = require('../../services/dev/DevManagementService'); +const { logger } = require('../../middleware/logger'); + +function previewSql(sql, max = 180) { + if (!sql) return ''; + const s = String(sql).replace(/\s+/g, ' ').trim(); + return s.length > max ? `${s.slice(0, max)}…` : s; +} + +exports.importSqlDump = async (req, res) => { + try { + if (!req.file || !req.file.buffer) { + return res.status(400).json({ success: false, error: 'SQL dump file is required' }); + } + const sql = req.file.buffer.toString('utf8'); + if (!sql.trim()) { + return res.status(400).json({ success: false, error: 'SQL dump file is empty' }); + } + const start = Date.now(); + const { rows, fields } = await DevManagementService.executeDump(sql); + const durationMs = Date.now() - start; + + const isMulti = Array.isArray(fields) && fields.length > 0 && Array.isArray(fields[0]); + + return res.json({ + success: true, + data: { result: rows, isMulti: !!isMulti }, + meta: { durationMs } + }); + } catch (e) { + logger.error('[DevManagementController.importSqlDump] error', { msg: e?.message, sql: previewSql(req.file?.buffer?.toString('utf8')) }); + return res.status(500).json({ success: false, error: e?.message || 'SQL execution failed' }); + } +}; diff --git a/database/database.js b/database/database.js index dd5284c..9f628d5 100644 --- a/database/database.js +++ b/database/database.js @@ -99,5 +99,12 @@ module.exports = { // Get a connection from the pool async getConnection() { return await pool.getConnection(); + }, + // Get a dedicated connection that allows multiple statements (for SQL dumps) + async getMultiStatementConnection() { + return await mysql.createConnection({ + ...dbConfig, + multipleStatements: true + }); } }; \ No newline at end of file diff --git a/routes/postRoutes.js b/routes/postRoutes.js index c4b214d..c37290b 100644 --- a/routes/postRoutes.js +++ b/routes/postRoutes.js @@ -28,6 +28,7 @@ const AffiliateController = require('../controller/affiliate/AffiliateController const AbonemmentController = require('../controller/abonemments/AbonemmentController'); const NewsController = require('../controller/news/NewsController'); const InvoiceController = require('../controller/invoice/InvoiceController'); // NEW +const DevManagementController = require('../controller/dev/DevManagementController'); const multer = require('multer'); const upload = multer({ storage: multer.memoryStorage() }); @@ -113,6 +114,7 @@ function adminOnly(req, res, next) { next(); } + // NEW: ensure service sees a "company" user_type for admin users function forceCompanyForAdmin(req, res, next) { if (req.user && ['admin','super_admin'].includes(req.user.role) && req.user.user_type !== 'company') { @@ -161,6 +163,9 @@ router.post('/admin/affiliates', authMiddleware, adminOnly, upload.single('logo' // NEW: Admin create news with image upload router.post('/admin/news', authMiddleware, adminOnly, upload.single('image'), NewsController.create); +// NEW: Dev Management SQL dump import (admin + super_admin) +router.post('/admin/dev/sql', authMiddleware, adminOnly, upload.single('file'), DevManagementController.importSqlDump); + // Abonement POSTs router.post('/abonements/subscribe', authMiddleware, AbonemmentController.subscribe); router.post('/abonements/:id/pause', authMiddleware, AbonemmentController.pause); diff --git a/services/dev/DevManagementService.js b/services/dev/DevManagementService.js new file mode 100644 index 0000000..f80598b --- /dev/null +++ b/services/dev/DevManagementService.js @@ -0,0 +1,15 @@ +const db = require('../../database/database'); + +async function executeDump(sql) { + const conn = await db.getMultiStatementConnection(); + try { + const [rows, fields] = await conn.query(sql); + return { rows, fields }; + } finally { + try { await conn.end(); } catch (_) {} + } +} + +module.exports = { + executeDump +};