diff --git a/controller/pool/PoolController.js b/controller/pool/PoolController.js index bf01839..360f53d 100644 --- a/controller/pool/PoolController.js +++ b/controller/pool/PoolController.js @@ -84,5 +84,22 @@ module.exports = { console.error('[PoolController.addMembers]', e); return res.status(500).json({ success: false, message: 'Internal server error' }); } + }, + + async removeMembers(req, res) { + try { + const { id } = req.params || {}; + const { userIds } = req.body || {}; + const actorUserId = req.user && req.user.userId; + if (!id) return res.status(400).json({ success: false, message: 'id is required' }); + if (!Array.isArray(userIds) || userIds.length === 0) { + return res.status(400).json({ success: false, message: 'userIds must be a non-empty array' }); + } + const removed = await PoolMemberService.removeMembers(id, userIds, actorUserId); + return res.status(200).json({ success: true, removed }); + } catch (e) { + console.error('[PoolController.removeMembers]', e); + return res.status(500).json({ success: false, message: 'Internal server error' }); + } } }; \ No newline at end of file diff --git a/repositories/pool/poolMemberRepository.js b/repositories/pool/poolMemberRepository.js index daa8339..de9cbbd 100644 --- a/repositories/pool/poolMemberRepository.js +++ b/repositories/pool/poolMemberRepository.js @@ -61,6 +61,27 @@ class PoolMemberRepository { throw error; } } + + async removeMembers(poolId, userIds, actorUserId = null) { + const conn = this.uow.connection; + if (!Array.isArray(userIds) || userIds.length === 0) return 0; + + try { + logger.info('PoolMemberRepository.removeMembers:start', { poolId, count: userIds.length, actorUserId }); + const placeholders = userIds.map(() => '?').join(', '); + const params = [poolId, ...userIds]; + const [result] = await conn.execute( + `DELETE FROM pool_members + WHERE pool_id = ? AND user_id IN (${placeholders})`, + params + ); + logger.info('PoolMemberRepository.removeMembers:success', { poolId, removed: result?.affectedRows || 0 }); + return result?.affectedRows || 0; + } catch (error) { + logger.error('PoolMemberRepository.removeMembers:error', { poolId, error: error.message }); + throw error; + } + } } module.exports = PoolMemberRepository; diff --git a/routes/deleteRoutes.js b/routes/deleteRoutes.js index dca35e9..79ff077 100644 --- a/routes/deleteRoutes.js +++ b/routes/deleteRoutes.js @@ -9,6 +9,7 @@ const CompanyStampController = require('../controller/companyStamp/CompanyStampC const CoffeeController = require('../controller/admin/CoffeeController'); const AffiliateController = require('../controller/affiliate/AffiliateController'); const NewsController = require('../controller/news/NewsController'); +const PoolController = require('../controller/pool/PoolController'); // Helper middlewares for company-stamp function forceCompanyForAdmin(req, res, next) { @@ -34,4 +35,7 @@ router.delete('/admin/affiliates/:id', authMiddleware, adminOnly, AffiliateContr // Admin: delete news router.delete('/admin/news/:id', authMiddleware, adminOnly, NewsController.delete); +// Admin: remove pool members +router.delete('/admin/pools/:id/members', authMiddleware, adminOnly, PoolController.removeMembers); + module.exports = router; diff --git a/services/pool/PoolMemberService.js b/services/pool/PoolMemberService.js index e7908e9..9d3fa7d 100644 --- a/services/pool/PoolMemberService.js +++ b/services/pool/PoolMemberService.js @@ -29,4 +29,18 @@ async function addMembers(poolId, userIds, actorUserId) { } } -module.exports = { listMembers, addMembers }; +async function removeMembers(poolId, userIds, actorUserId) { + const uow = new UnitOfWork(); + try { + await uow.start(); + const repo = new PoolMemberRepository(uow); + const removed = await repo.removeMembers(poolId, userIds, actorUserId); + await uow.commit(); + return removed; + } catch (err) { + try { await uow.rollback(err); } catch (_) {} + throw err; + } +} + +module.exports = { listMembers, addMembers, removeMembers };