Initial commit

This commit is contained in:
Lorenzo Sanesi
2026-03-26 22:46:03 +01:00
commit 18e0e04700
80 changed files with 13114 additions and 0 deletions
@@ -0,0 +1,99 @@
const { NotFoundError, DatabaseError } = require('../../shared/errors');
const { Op } = require('sequelize');
class FriendRequestsRepository {
constructor({ sequelize }) {
this.sequelize = sequelize;
this.FriendRequest = sequelize.models.FriendRequest;
this.User = sequelize.models.User;
}
async findById(id) {
try {
const request = await this.FriendRequest.findByPk(id, {
include: [
{ model: this.User, as: 'fromUser' },
{ model: this.User, as: 'toUser' },
],
});
if (!request) {
throw new NotFoundError('Friend request not found');
}
return request;
} catch (error) {
if (error instanceof NotFoundError) throw error;
throw new DatabaseError(`Failed to fetch friend request with id ${id}`, error);
}
}
async findPendingByUserId(userId) {
try {
return await this.FriendRequest.findAll({
where: {
toUserId: userId,
status: 'PENDING',
},
include: [
{ model: this.User, as: 'fromUser' },
{ model: this.User, as: 'toUser' },
],
});
} catch (error) {
throw new DatabaseError(
`Failed to fetch pending requests for user ${userId}`,
error
);
}
}
async findExisting(fromUserId, toUserId) {
try {
return await this.FriendRequest.findOne({
where: {
[Op.or]: [
{ fromUserId, toUserId },
{ fromUserId: toUserId, toUserId: fromUserId },
],
status: 'PENDING',
},
});
} catch (error) {
throw new DatabaseError('Failed to check existing friend request', error);
}
}
async create(fromUserId, toUserId) {
try {
return await this.FriendRequest.create({
fromUserId,
toUserId,
status: 'PENDING',
});
} catch (error) {
throw new DatabaseError('Failed to create friend request', error);
}
}
async updateStatus(id, status) {
try {
const request = await this.findById(id);
return await request.update({ status });
} catch (error) {
if (error instanceof NotFoundError) throw error;
throw new DatabaseError('Failed to update friend request status', error);
}
}
async delete(id) {
try {
const request = await this.findById(id);
await request.destroy();
return true;
} catch (error) {
if (error instanceof NotFoundError) throw error;
throw new DatabaseError('Failed to delete friend request', error);
}
}
}
module.exports = FriendRequestsRepository;
@@ -0,0 +1,78 @@
const { NotFoundError, DatabaseError } = require('../../shared/errors');
const { Op } = require('sequelize');
class FriendshipsRepository {
constructor({ sequelize }) {
this.sequelize = sequelize;
this.Friendship = sequelize.models.Friendship;
this.User = sequelize.models.User;
}
async findByUserId(userId) {
try {
const friendships = await this.Friendship.findAll({
where: {
[Op.or]: [{ user1Id: userId }, { user2Id: userId }],
},
include: [
{ model: this.User, as: 'user1' },
{ model: this.User, as: 'user2' },
],
});
return friendships.map((friendship) => {
const friend =
friendship.user1.id === userId ? friendship.user2 : friendship.user1;
return friend;
});
} catch (error) {
throw new DatabaseError(`Failed to fetch friendships for user ${userId}`, error);
}
}
async exists(user1Id, user2Id) {
try {
const minId = Math.min(user1Id, user2Id);
const maxId = Math.max(user1Id, user2Id);
const friendship = await this.Friendship.findOne({
where: { user1Id: minId, user2Id: maxId },
});
return !!friendship;
} catch (error) {
throw new DatabaseError('Failed to check friendship existence', error);
}
}
async create(user1Id, user2Id) {
try {
const minId = Math.min(user1Id, user2Id);
const maxId = Math.max(user1Id, user2Id);
return await this.Friendship.create({
user1Id: minId,
user2Id: maxId,
});
} catch (error) {
throw new DatabaseError('Failed to create friendship', error);
}
}
async delete(user1Id, user2Id) {
try {
const minId = Math.min(user1Id, user2Id);
const maxId = Math.max(user1Id, user2Id);
const result = await this.Friendship.destroy({
where: { user1Id: minId, user2Id: maxId },
});
return result > 0;
} catch (error) {
throw new DatabaseError('Failed to delete friendship', error);
}
}
}
module.exports = FriendshipsRepository;
@@ -0,0 +1,93 @@
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 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;
@@ -0,0 +1,68 @@
const { NotFoundError, DatabaseError } = require('../../shared/errors');
class UsersRepository {
constructor({ sequelize }) {
this.sequelize = sequelize;
this.User = sequelize.models.User;
}
async findAll(options = {}) {
try {
return await this.User.findAll(options);
} catch (error) {
throw new DatabaseError('Failed to fetch users', error);
}
}
async findById(id, options = {}) {
try {
const user = await this.User.findByPk(id, options);
if (!user) {
throw new NotFoundError('User not found');
}
return user;
} catch (error) {
if (error instanceof NotFoundError) throw error;
throw new DatabaseError(`Failed to fetch user with id ${id}`, error);
}
}
async findOne(where, options = {}) {
try {
return await this.User.findOne({ where, ...options });
} catch (error) {
throw new DatabaseError('Failed to find user', error);
}
}
async create(userData) {
try {
return await this.User.create(userData);
} catch (error) {
throw new DatabaseError('Failed to create user', error);
}
}
async update(id, updateData) {
try {
const user = await this.findById(id);
return await user.update(updateData);
} catch (error) {
if (error instanceof NotFoundError) throw error;
throw new DatabaseError(`Failed to update user with id ${id}`, error);
}
}
async delete(id) {
try {
const user = await this.findById(id);
await user.destroy();
return true;
} catch (error) {
if (error instanceof NotFoundError) throw error;
throw new DatabaseError(`Failed to delete user with id ${id}`, error);
}
}
}
module.exports = UsersRepository;