const { Op } = require('sequelize'); const { NotFoundError, DatabaseError } = require('../../shared/errors'); class GroupsRepository { constructor({ sequelize }) { this.sequelize = sequelize; this.Group = sequelize.models.Group; this.User = sequelize.models.User; } async findAll(options = {}) { try { return await this.Group.findAll(options); } catch (error) { throw new DatabaseError('Failed to fetch groups', error); } } async findByUserId(userId) { try { return await this.Group.findAll({ include: [ { model: this.User, as: 'members', through: { attributes: [] }, }, ], where: { id: { [Op.in]: this.sequelize.literal( `(SELECT "groupId" FROM "UserGroups" WHERE "userId" = ${parseInt(userId, 10)})` ), }, }, }); } catch (error) { throw new DatabaseError('Failed to fetch groups for user', error); } } async findById(id, includeMembers = false) { try { const options = {}; if (includeMembers) { options.include = [ { model: this.User, as: 'members', through: { attributes: [] }, }, ]; } const group = await this.Group.findByPk(id, options); if (!group) { throw new NotFoundError('Group not found'); } return group; } catch (error) { if (error instanceof NotFoundError) throw error; throw new DatabaseError(`Failed to fetch group with id ${id}`, error); } } async create(groupData) { try { return await this.Group.create(groupData); } catch (error) { throw new DatabaseError('Failed to create group', error); } } async addMembers(groupId, userIds) { try { const group = await this.findById(groupId); await group.addMembers(userIds); return this.findById(groupId, true); } catch (error) { if (error instanceof NotFoundError) throw error; throw new DatabaseError('Failed to add members to group', error); } } async removeMember(groupId, userId) { try { const group = await this.findById(groupId); await group.removeMember(userId); return this.findById(groupId, true); } catch (error) { if (error instanceof NotFoundError) throw error; throw new DatabaseError('Failed to remove member from group', error); } } async update(id, updateData) { try { const group = await this.findById(id); return await group.update(updateData); } catch (error) { if (error instanceof NotFoundError) throw error; throw new DatabaseError(`Failed to update group with id ${id}`, error); } } async delete(id) { try { const group = await this.findById(id); await group.destroy(); return true; } catch (error) { if (error instanceof NotFoundError) throw error; throw new DatabaseError(`Failed to delete group with id ${id}`, error); } } } module.exports = GroupsRepository;