const { logger } = require('../../middleware/logger'); class PoolMemberRepository { constructor(uow) { this.uow = uow; } async listMembers(poolId) { const conn = this.uow.connection; try { logger.info('PoolMemberRepository.listMembers:start', { poolId }); // 1) Get the pool info (is_core flag, member count, total inflows) const [poolMeta] = await conn.execute( `SELECT p.pool_name, (SELECT COUNT(*) FROM pool_members WHERE pool_id = p.id) AS member_count, COALESCE((SELECT SUM(pi.amount_net) FROM pool_inflows pi WHERE pi.pool_id = p.id), 0) AS total_pool_amount FROM pools p WHERE p.id = ?`, [poolId] ); const meta = poolMeta[0] || { pool_name: '', member_count: 0, total_pool_amount: 0 }; const isCore = meta.pool_name === 'Core'; const memberCount = Number(meta.member_count) || 1; const totalPoolAmount = Number(meta.total_pool_amount) || 0; // For Core: every member gets the full total. Others: equal share. const perMemberShare = isCore ? totalPoolAmount : totalPoolAmount / memberCount; // 2) Fetch member rows const [rows] = await conn.execute( `SELECT u.id, u.email, u.user_type, u.role, pp.first_name, pp.last_name, cp.company_name, pm.joined_at FROM pool_members pm JOIN users u ON u.id = pm.user_id LEFT JOIN personal_profiles pp ON u.id = pp.user_id LEFT JOIN company_profiles cp ON u.id = cp.user_id WHERE pm.pool_id = ? ORDER BY pm.joined_at DESC`, [poolId] ); // 3) Attach per-member share const enriched = rows.map(r => ({ ...r, share: Number(perMemberShare.toFixed(2)) })); logger.info('PoolMemberRepository.listMembers:success', { poolId, count: rows.length }); return enriched; } catch (error) { logger.error('PoolMemberRepository.listMembers:error', { poolId, error: error.message }); throw error; } } async addMembers(poolId, userIds, actorUserId = null) { const conn = this.uow.connection; if (!Array.isArray(userIds) || userIds.length === 0) return []; try { logger.info('PoolMemberRepository.addMembers:start', { poolId, count: userIds.length, actorUserId }); const placeholders = userIds.map(() => '(?, ?, ?)').join(', '); const params = []; for (const userId of userIds) { params.push(poolId, userId, actorUserId); } await conn.execute( `INSERT INTO pool_members (pool_id, user_id, created_by) VALUES ${placeholders} ON DUPLICATE KEY UPDATE updated_at = CURRENT_TIMESTAMP`, params ); logger.info('PoolMemberRepository.addMembers:success', { poolId, count: userIds.length }); return true; } catch (error) { logger.error('PoolMemberRepository.addMembers:error', { poolId, error: error.message }); 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;