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
+21
View File
@@ -0,0 +1,21 @@
module.exports = (sequelize) => {
const { User, Group, FriendRequest, Friendship } = sequelize.models;
// User <-> Group: Many-to-Many
// A User can be in many Groups, and a Group can have many Users (members).
const UserGroup = sequelize.define('UserGroup', {}, { timestamps: false });
User.belongsToMany(Group, { through: UserGroup, foreignKey: 'userId' });
Group.belongsToMany(User, { through: UserGroup, as: 'members', foreignKey: 'groupId' });
// Friendship is a direct link between two users.
// user1Id will always be less than user2Id to ensure uniqueness.
Friendship.belongsTo(User, { as: 'user1', foreignKey: 'user1Id' });
Friendship.belongsTo(User, { as: 'user2', foreignKey: 'user2Id' });
// User <-> FriendRequest: One-to-Many
// A User can send many friend requests and receive many friend requests.
User.hasMany(FriendRequest, { as: 'sentRequests', foreignKey: 'fromUserId', onDelete: 'CASCADE' });
User.hasMany(FriendRequest, { as: 'receivedRequests', foreignKey: 'toUserId', onDelete: 'CASCADE' });
FriendRequest.belongsTo(User, { as: 'fromUser', foreignKey: 'fromUserId' });
FriendRequest.belongsTo(User, { as: 'toUser', foreignKey: 'toUserId' });
};
+30
View File
@@ -0,0 +1,30 @@
const mongoose = require('mongoose');
const { Schema } = mongoose;
const BetParticipantSchema = new Schema({
user: { type: Number, required: true }, // Stores the PostgreSQL User ID
role: { type: String, enum: ['PARTICIPANT', 'OBSERVER'], required: true },
}, { _id: false });
const BetSchema = new mongoose.Schema({
title: { type: String, required: true },
description: { type: String },
stake: { type: String, required: true },
participants: [BetParticipantSchema],
status: { type: String, enum: ['ACTIVE', 'AWAITING_VALIDATION', 'COMPLETED', 'EXPIRED'], required: true },
startDate: { type: Date, default: Date.now },
endDate: { type: Date, default: null },
isPublic: { type: Boolean, default: false },
groupId: { type: String, default: null }, // Stores the PostgreSQL Group ID
winner: { type: Number, default: null }, // Stores the PostgreSQL User ID
});
BetSchema.set('toJSON', {
virtuals: true,
versionKey: false,
transform: function (doc, ret) {
delete ret._id;
}
});
module.exports = mongoose.model('Bet', BetSchema);
@@ -0,0 +1,21 @@
const { DataTypes } = require('sequelize');
module.exports = (sequelize) => {
const FriendRequest = sequelize.define('FriendRequest', {
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true
},
status: {
type: DataTypes.STRING,
defaultValue: 'PENDING',
allowNull: false
}
// Foreign keys 'fromUserId' and 'toUserId' are added via associations
}, {
// Uses default `createdAt` and `updatedAt` timestamps from Sequelize
tableName: 'friend_requests'
});
return FriendRequest;
};
+25
View File
@@ -0,0 +1,25 @@
const { DataTypes } = require('sequelize');
module.exports = (sequelize) => {
const Friendship = sequelize.define('Friendship', {
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true
}
// Foreign keys 'user1Id' and 'user2Id' are added via associations
}, {
timestamps: false,
tableName: 'friendships',
hooks: {
// Ensure user1Id is always less than user2Id to guarantee
// a unique friendship pair regardless of creation order.
beforeValidate: (friendship) => {
if (friendship.user1Id > friendship.user2Id) {
[friendship.user1Id, friendship.user2Id] = [friendship.user2Id, friendship.user1Id];
}
}
}
});
return Friendship;
};
+19
View File
@@ -0,0 +1,19 @@
const { DataTypes } = require('sequelize');
module.exports = (sequelize) => {
const Group = sequelize.define('Group', {
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true
},
name: {
type: DataTypes.STRING,
allowNull: false
}
}, {
timestamps: false,
tableName: 'groups'
});
return Group;
};
+35
View File
@@ -0,0 +1,35 @@
const { DataTypes } = require('sequelize');
module.exports = (sequelize) => {
const User = sequelize.define('User', {
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true
},
name: {
type: DataTypes.STRING,
allowNull: false
},
email: {
type: DataTypes.STRING,
allowNull: false,
unique: true,
validate: {
isEmail: true
}
},
avatarUrl: {
type: DataTypes.STRING,
allowNull: false
},
score: {
type: DataTypes.INTEGER,
defaultValue: 0
},
}, {
timestamps: false,
tableName: 'users'
});
return User;
};