feat: implement removeMembers functionality for pool management + enhance usability

This commit is contained in:
seaznCode 2026-01-28 20:14:04 +01:00
parent fb3d3c410c
commit 1491f0fc0e
4 changed files with 57 additions and 1 deletions

View File

@ -84,5 +84,22 @@ module.exports = {
console.error('[PoolController.addMembers]', e); console.error('[PoolController.addMembers]', e);
return res.status(500).json({ success: false, message: 'Internal server error' }); 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' });
}
} }
}; };

View File

@ -61,6 +61,27 @@ class PoolMemberRepository {
throw error; 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; module.exports = PoolMemberRepository;

View File

@ -9,6 +9,7 @@ const CompanyStampController = require('../controller/companyStamp/CompanyStampC
const CoffeeController = require('../controller/admin/CoffeeController'); const CoffeeController = require('../controller/admin/CoffeeController');
const AffiliateController = require('../controller/affiliate/AffiliateController'); const AffiliateController = require('../controller/affiliate/AffiliateController');
const NewsController = require('../controller/news/NewsController'); const NewsController = require('../controller/news/NewsController');
const PoolController = require('../controller/pool/PoolController');
// Helper middlewares for company-stamp // Helper middlewares for company-stamp
function forceCompanyForAdmin(req, res, next) { function forceCompanyForAdmin(req, res, next) {
@ -34,4 +35,7 @@ router.delete('/admin/affiliates/:id', authMiddleware, adminOnly, AffiliateContr
// Admin: delete news // Admin: delete news
router.delete('/admin/news/:id', authMiddleware, adminOnly, NewsController.delete); 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; module.exports = router;

View File

@ -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 };