Réorganisation des sources

This commit is contained in:
Rampeur
2025-08-15 17:29:23 +02:00
parent bd3d1ade49
commit ea2d177c4c
29 changed files with 199 additions and 190 deletions
+68
View File
@@ -0,0 +1,68 @@
const chalk = require('chalk');
const mongoose = require('mongoose');
const DB = require('.');
const sequelize = require('./config/sequelize');
const associate = require('./relationships');
const utils = require('../utils');
// Connect to the MongoDB database and log a message to the console
const connectMongoDb = async () => {
try {
if (process.env.APP_ENV === 'production') {
mongoose.connect(process.env.MONGODB_URI);
} else {
mongoose.set('strictQuery', true);
mongoose.connect(process.env.MONGODB_URI).then(() => {
console.log(`${utils.getDateTimeISOString()}`, chalk.green('MongoDB connection has been established successfully 🟢'));
}).catch(() => {
console.log(`${utils.getDateTimeISOString()}`, chalk.red('Unable to connect to the MongoDB database 🔴'));
});
mongoose.set('debug', process.env.DEBUG);
console.log(`${utils.getDateTimeISOString()}`, chalk.red('debug :'), chalk.yellow(process.env.DEBUG));
}
} catch (error) {
console.log(`${utils.getDateTimeISOString()}`, chalk.red('Unable to connect to the MongoDB database 🔴'));
console.error('MongoDB connection error:', error);
// Exit the process if the connection is not successful
process.exit(1);
}
};
// Connect to the MySQL database and log a message to the console
const connectMysqlDb = async () => {
try {
await sequelize.authenticate();
console.log('Connection has been established successfully 🔹');
console.log(`${utils.getDateTimeISOString()}`, chalk.green('MySQL connection has been established successfully 🟢'));
// Synchronize the database with the models without need of dropping the tables
await DB.sequelize.sync({
force: false,
});
// Call the associate function to create the relationships between the models
associate();
} catch (error) {
console.log(`${utils.getDateTimeISOString()}`, chalk.red('Unable to connect to the MySQL database 🔴'));
console.error('MySQL connection error:', error);
// Exit the process if the connection is not successful
process.exit(1);
}
};
// Connect to all database and log a message to the console
const connectAllDb = async () => {
connectMongoDb();
connectMysqlDb();
};
module.exports.connectAllDb = connectAllDb;
module.exports.connectMongoDb = connectMongoDb;
module.exports.connectMysqlDb = connectMysqlDb;
module.exports.default = connectAllDb;
+33
View File
@@ -0,0 +1,33 @@
var mongoose = require('mongoose');
var slug = require('slug');
var AeronefSchema = new mongoose.Schema({
slug: { type: String, lowercase: true, unique: true },
aeronef: String,
imat: String,
author: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }
}, {timestamps: true, toJSON: {virtuals: true}});
AeronefSchema.pre('validate', function (next) {
if (!this.slug) {
this.slugify();
}
next();
});
AeronefSchema.methods.slugify = function () {
this.slug = slug(`${this.aeronef} ${this.imat}`) + '-' + (Math.random() * Math.pow(36, 6) | 0).toString(36);
};
AeronefSchema.methods.toJSONFor = function(user){
return {
slug: this.slug,
aeronef: this.aeronef,
imat: this.imat,
createdAt: this.createdAt,
updatedAt: this.updatedAt,
author: this.author.toProfileJSONFor(user)
};
};
mongoose.model('Aeronef', AeronefSchema);
+51
View File
@@ -0,0 +1,51 @@
var mongoose = require('mongoose');
var uniqueValidator = require('mongoose-unique-validator');
var slug = require('slug');
var ApplicationSchema = new mongoose.Schema({
apikey: String,
maskedkey: String,
slug: { type: String, lowercase: true, unique: true },
title: String,
description: String,
author: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }
}, { timestamps: true, toJSON: { virtuals: true } });
ApplicationSchema.plugin(uniqueValidator, { message: 'is already taken' });
ApplicationSchema.pre('validate', function (next) {
if (!this.slug) {
this.slugify();
}
next();
});
ApplicationSchema.methods.slugify = function () {
this.slug = slug(this.title) + '-' + (Math.random() * Math.pow(36, 6) | 0).toString(36);
};
ApplicationSchema.methods.toJSONFor = function (user) {
return {
maskedkey: this.maskedkey,
slug: this.slug,
title: this.title,
description: this.description,
createdAt: this.createdAt,
updatedAt: this.updatedAt,
author: this.author.toProfileJSONFor(user)
};
};
ApplicationSchema.methods.toAuthJSON = function () {
return {
maskedkey: this.maskedkey,
slug: this.slug,
title: this.title,
description: this.description,
createdAt: this.createdAt,
updatedAt: this.updatedAt,
author: this.author.toJSONFor()
};
};
mongoose.model('Application', ApplicationSchema);
+60
View File
@@ -0,0 +1,60 @@
var mongoose = require('mongoose');
var uniqueValidator = require('mongoose-unique-validator');
var slug = require('slug');
var User = mongoose.model('User');
//var Membre = mongoose.model('Membre');
var ArticleSchema = new mongoose.Schema({
slug: { type: String, lowercase: true, unique: true },
title: String,
description: String,
body: String,
membre: String,
// membre: Membre.schema,
// membre: { type: mongoose.Schema.Types.ObjectId, ref: 'Membre' },
author: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
comments: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Comment' }],
favoritesCount: { type: Number, default: 0 },
tagList: [{ type: String }]
}, { timestamps: true, toJSON: { virtuals: true } });
ArticleSchema.plugin(uniqueValidator, { message: 'is already taken' });
ArticleSchema.pre('validate', function (next) {
if (!this.slug) {
this.slugify();
}
next();
});
ArticleSchema.methods.slugify = function () {
this.slug = slug(this.title) + '-' + (Math.random() * Math.pow(36, 6) | 0).toString(36);
};
ArticleSchema.methods.updateFavoriteCount = function () {
var article = this;
return User.count({ favorites: { $in: [article._id] } }).then(function (count) {
article.favoritesCount = count;
return article.save();
});
};
ArticleSchema.methods.toJSONFor = function (user) {
return {
slug: this.slug,
title: this.title,
description: this.description,
body: this.body,
createdAt: this.createdAt,
updatedAt: this.updatedAt,
tagList: this.tagList,
membre: this.membre,
favorited: user ? user.isFavorite(this._id) : false,
favoritesCount: this.favoritesCount,
author: this.author.toProfileJSONFor(user)
};
};
mongoose.model('Article', ArticleSchema);
+33
View File
@@ -0,0 +1,33 @@
var mongoose = require('mongoose');
var slug = require('slug');
var CanopySchema = new mongoose.Schema({
slug: { type: String, lowercase: true, unique: true },
voile: String,
taille: Number,
author: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }
}, {timestamps: true, toJSON: {virtuals: true}});
CanopySchema.pre('validate', function (next) {
if (!this.slug) {
this.slugify();
}
next();
});
CanopySchema.methods.slugify = function () {
this.slug = slug(`${this.voile} ${this.taille}`) + '-' + (Math.random() * Math.pow(36, 6) | 0).toString(36);
};
CanopySchema.methods.toJSONFor = function(user){
return {
slug: this.slug,
voile: this.voile,
taille: this.taille,
createdAt: this.createdAt,
updatedAt: this.updatedAt,
author: this.author.toProfileJSONFor(user)
};
};
mongoose.model('Canopy', CanopySchema);
+19
View File
@@ -0,0 +1,19 @@
var mongoose = require('mongoose');
var CommentSchema = new mongoose.Schema({
body: String,
author: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
article: { type: mongoose.Schema.Types.ObjectId, ref: 'Article' }
}, { timestamps: true, toJSON: { virtuals: true } });
// Requires population of author
CommentSchema.methods.toJSONFor = function (user) {
return {
id: this._id,
body: this.body,
createdAt: this.createdAt,
author: this.author.toProfileJSONFor(user)
};
};
mongoose.model('Comment', CommentSchema);
+33
View File
@@ -0,0 +1,33 @@
var mongoose = require('mongoose');
var slug = require('slug');
var DropzoneSchema = new mongoose.Schema({
slug: { type: String, lowercase: true, unique: true },
lieu: String,
oaci: String,
author: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }
}, {timestamps: true, toJSON: {virtuals: true}});
DropzoneSchema.pre('validate', function (next) {
if (!this.slug) {
this.slugify();
}
next();
});
DropzoneSchema.methods.slugify = function () {
this.slug = slug(`${this.lieu} ${this.oaci}`) + '-' + (Math.random() * Math.pow(36, 6) | 0).toString(36);
};
DropzoneSchema.methods.toJSONFor = function(user){
return {
slug: this.slug,
lieu: this.lieu,
oaci: this.oaci,
createdAt: this.createdAt,
updatedAt: this.updatedAt,
author: this.author.toProfileJSONFor(user)
};
};
mongoose.model('Dropzone', DropzoneSchema);
+86
View File
@@ -0,0 +1,86 @@
var mongoose = require('mongoose');
var uniqueValidator = require('mongoose-unique-validator');
var slug = require('slug');
var JumpSchema = new mongoose.Schema({
slug: { type: String, lowercase: true, unique: true },
date: { type: Date, default: Date.now },
numero: { type: Number, unique: true },
lieu: String,
oaci: String,
aeronef: String,
imat: String,
hauteur: Number,
deploiement: Number,
voile: String,
taille: Number,
categorie: String,
module: String,
participants: Number,
sautants: [String],
programme: String,
accessoires: String,
zone: String,
dossier: String,
video: String,
files: [{ type: mongoose.Schema.Types.ObjectId, ref: 'JumpFile' }],
x2data: { type: mongoose.Schema.Types.ObjectId, ref: 'X2DataLog' },
author: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }
}, {timestamps: true, toJSON: {virtuals: true}});
JumpSchema.plugin(uniqueValidator, { message: 'is already taken' });
JumpSchema.pre('validate', function (next) {
if (!this.slug) {
this.slugify();
}
next();
});
JumpSchema.methods.slugify = function () {
this.slug = slug(`${this.numero} ${this.lieu}`) + '-' + (Math.random() * Math.pow(36, 6) | 0).toString(36);
};
JumpSchema.methods.addFile = function (id) {
if (this.files.indexOf(id) === -1) {
this.files.push(id);
}
return this.save();
};
JumpSchema.methods.removeFile = function (id) {
this.files.remove(id);
return this.save();
};
JumpSchema.methods.toJSONFor = function(user) {
return {
slug: this.slug,
date: this.date,
numero: this.numero,
lieu: this.lieu,
oaci: this.oaci,
aeronef: this.aeronef,
imat: this.imat,
hauteur: this.hauteur,
deploiement: this.deploiement,
voile: this.voile,
taille: this.taille,
categorie: this.categorie,
module: this.module,
participants: this.participants,
sautants: this.sautants,
programme: this.programme,
accessoires: this.accessoires,
zone: this.zone,
dossier: this.dossier,
video: this.video,
files: this.files.map(file => file ? file.toJSONForJump() : null),
x2data: this.x2data ? this.x2data.toJSONFor() : null,
createdAt: this.createdAt,
updatedAt: this.updatedAt,
author: this.author.toProfileJSONFor(user)
};
};
mongoose.model('Jump', JumpSchema);
+51
View File
@@ -0,0 +1,51 @@
var mongoose = require('mongoose');
var uniqueValidator = require('mongoose-unique-validator');
var slug = require('slug');
var JumpFileSchema = new mongoose.Schema({
slug: { type: String, lowercase: true, unique: true },
name: String,
path: String,
type: {
type: String,
enum : ['csv', 'image', 'kml', 'video'],
default: 'video'
},
author: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }
}, {timestamps: true, toJSON: {virtuals: true}});
JumpFileSchema.plugin(uniqueValidator, { message: 'is already taken' });
JumpFileSchema.pre('validate', function (next) {
if (!this.slug) {
this.slugify();
}
next();
});
JumpFileSchema.methods.slugify = function () {
this.slug = slug(`${this.type}`) + '-' + (Math.random() * Math.pow(36, 6) | 0).toString(36) + (Math.random() * Math.pow(36, 6) | 0).toString(36);
};
JumpFileSchema.methods.toJSONFor = function(user){
return {
slug: this.slug,
name: this.name,
path: this.path,
type: this.type,
createdAt: this.createdAt,
updatedAt: this.updatedAt,
author: this.author.toProfileJSONFor(user)
};
};
JumpFileSchema.methods.toJSONForJump = function(){
return {
slug: this.slug,
name: this.name,
path: this.path,
type: this.type
};
};
mongoose.model('JumpFile', JumpFileSchema);
+46
View File
@@ -0,0 +1,46 @@
var mongoose = require('mongoose');
var uniqueValidator = require('mongoose-unique-validator');
var slug = require('slug');
var QcmSchema = new mongoose.Schema({
name: { type: String, lowercase: true, unique: true },
slug: { type: String, lowercase: true, unique: true },
categories: [
{ type: mongoose.Schema.Types.ObjectId, ref: 'QcmCategory' }
]
}, {timestamps: true, toJSON: {virtuals: true}});
QcmSchema.plugin(uniqueValidator, { message: 'is already taken' });
QcmSchema.pre('validate', function (next) {
if (!this.slug) {
this.slugify();
}
next();
});
QcmSchema.methods.slugify = function () {
this.slug = slug(`${this.name}-`) + (Math.random() * Math.pow(36, 6) | 0).toString(36);
};
QcmSchema.methods.addCategory = function (id) {
if (this.categories.indexOf(id) === -1) {
this.categories.push(id);
}
return this.save();
};
QcmSchema.methods.removeCategory = function (id) {
this.categories.remove(id);
return this.save();
};
QcmSchema.methods.toJSONFor = function() {
return {
name: this.name,
slug: this.slug,
categories: this.categories.map(category => category.toJSONFor())
};
};
mongoose.model('Qcm', QcmSchema);
+48
View File
@@ -0,0 +1,48 @@
var mongoose = require('mongoose');
var uniqueValidator = require('mongoose-unique-validator');
var slug = require('slug');
var QcmCategorySchema = new mongoose.Schema({
num: Number,
name: { type: String, unique: true },
slug: { type: String, lowercase: true, unique: true },
questions: [
{ type: mongoose.Schema.Types.ObjectId, ref: 'QcmQuestion' }
]
}, {timestamps: true, toJSON: {virtuals: true}});
QcmCategorySchema.plugin(uniqueValidator, { message: 'is already taken' });
QcmCategorySchema.pre('validate', function (next) {
if (!this.slug) {
this.slugify();
}
next();
});
QcmCategorySchema.methods.slugify = function () {
this.slug = slug(`${this.name}-${this.num}-`) + (Math.random() * Math.pow(36, 6) | 0).toString(36);
};
QcmCategorySchema.methods.addQuestion = function (id) {
if (this.questions.indexOf(id) === -1) {
this.questions.push(id);
}
return this.save();
};
QcmCategorySchema.methods.removeQuestion = function (id) {
this.questions.remove(id);
return this.save();
};
QcmCategorySchema.methods.toJSONFor = function() {
return {
num: this.num,
name: this.name,
slug: this.slug,
questions: this.questions.map(question => question.toJSONFor())
};
};
mongoose.model('QcmCategory', QcmCategorySchema);
+17
View File
@@ -0,0 +1,17 @@
var mongoose = require('mongoose');
var QcmChoiceSchema = new mongoose.Schema({
index: String,
libelle: String,
correct: Boolean
}, {timestamps: true, toJSON: {virtuals: true}});
QcmChoiceSchema.methods.toJSONFor = function() {
return {
index: this.index,
libelle: this.libelle,
correct: this.correct
};
};
mongoose.model('QcmChoice', QcmChoiceSchema);
+31
View File
@@ -0,0 +1,31 @@
var mongoose = require('mongoose');
var QcmQuestionSchema = new mongoose.Schema({
num: Number,
libelle: String,
choices: [
{ type: mongoose.Schema.Types.ObjectId, ref: 'QcmChoice' }
]
}, {timestamps: true, toJSON: {virtuals: true}});
QcmQuestionSchema.methods.addChoice = function (id) {
if (this.choices.indexOf(id) === -1) {
this.choices.push(id);
}
return this.save();
};
QcmQuestionSchema.methods.removeChoice = function (id) {
this.choices.remove(id);
return this.save();
};
QcmQuestionSchema.methods.toJSONFor = function() {
return {
num: this.num,
libelle: this.libelle,
choices: this.choices.map(choice => choice.toJSONFor())
};
};
mongoose.model('QcmQuestion', QcmQuestionSchema);
+18
View File
@@ -0,0 +1,18 @@
const mongoose = require('mongoose');
const uniqueValidator = require('mongoose-unique-validator');
const TagSchema = new mongoose.Schema({
tagName: {
type: String,
required: true,
unique: true
},
articles: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Article'
}]
})
TagSchema.plugin(uniqueValidator);
module.exports = mongoose.model('Tag', TagSchema);
+133
View File
@@ -0,0 +1,133 @@
var mongoose = require('mongoose');
var uniqueValidator = require('mongoose-unique-validator');
var crypto = require('crypto');
var jwt = require('jsonwebtoken'),
secret = require('../../../config').secret,
session_lifetime = require('../../../config').session_lifetime;
var UserSchema = new mongoose.Schema({
email: { type: String, lowercase: true, unique: true, required: [true, "email can't be blank"], match: [/\S+@\S+\.\S+/, 'is invalid'], index: true },
username: { type: String, lowercase: true, unique: true, required: [true, "username can't be blank"], match: [/^[a-zA-Z0-9_]+$/, 'is invalid'], index: true },
role: String,
firstname: { type: String, required: [true, "firstname can't be blank"] },
lastname: { type: String, required: [true, "lastname can't be blank"] },
phone: String,
licence: Number,
poids: Number,
image: String,
bg_image: String,
favorites: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Product' }],
following: [{ type: mongoose.Schema.Types.ObjectId, ref: 'User' }],
hash: String,
salt: String
}, { timestamps: true, toJSON: { virtuals: true } });
UserSchema.plugin(uniqueValidator, { message: 'is already taken.' });
UserSchema.methods.validPassword = function (password) {
let hash = crypto.pbkdf2Sync(password, this.salt, 10000, 512, 'sha512').toString('hex');
return this.hash === hash;
};
UserSchema.methods.setPassword = function (password) {
this.salt = crypto.randomBytes(16).toString('hex');
this.hash = crypto.pbkdf2Sync(password, this.salt, 10000, 512, 'sha512').toString('hex');
};
UserSchema.methods.generateJWT = function () {
var today = new Date();
var exp = new Date(today.getTime() + (session_lifetime * 1000));
return jwt.sign({
id: this._id,
username: this.username,
exp: parseInt(exp.getTime() / 1000)
}, secret, { algorithm: 'HS256' });
};
UserSchema.methods.toAuthJSON = function () {
return {
id: this._id,
email: this.email,
role: this.role,
token: this.generateJWT(),
firstname: this.firstname,
lastname: this.lastname,
phone: this.phone,
licence: this.licence,
poids: this.poids,
username: this.username,
image: this.image || '/assets/images/users/user.jpg',
bg_image: this.bg_image || '/assets/images/users/bg_user.jpg'
};
};
UserSchema.methods.toJSONFor = function () {
return {
email: this.email,
role: this.role,
firstname: this.firstname,
lastname: this.lastname,
phone: this.phone,
licence: this.licence,
poids: this.poids,
username: this.username,
image: this.image || '/assets/images/users/user.jpg',
bg_image: this.bg_image || '/assets/images/users/bg_user.jpg'
};
};
UserSchema.methods.toProfileJSONFor = function (user) {
return {
email: this.email,
firstname: this.firstname,
lastname: this.lastname,
phone: this.phone,
licence: this.licence,
poids: this.poids,
username: this.username,
image: this.image || '/assets/images/users/user.jpg',
bg_image: this.bg_image || '/assets/images/users/bg_user.jpg',
following: user ? user.isFollowing(this._id) : false
};
};
UserSchema.methods.favorite = function (id) {
if (this.favorites.indexOf(id) === -1) {
this.favorites.push(id);
}
return this.save();
};
UserSchema.methods.unfavorite = function (id) {
this.favorites.remove(id);
return this.save();
};
UserSchema.methods.isFavorite = function (id) {
return this.favorites.some(function (favoriteId) {
return favoriteId.toString() === id.toString();
});
};
UserSchema.methods.follow = function (id) {
if (this.following.indexOf(id) === -1) {
this.following.push(id);
}
return this.save();
};
UserSchema.methods.unfollow = function (id) {
this.following.remove(id);
return this.save();
};
UserSchema.methods.isFollowing = function (id) {
return this.following.some(function (followId) {
return followId.toString() === id.toString();
});
};
mongoose.model('User', UserSchema);
+107
View File
@@ -0,0 +1,107 @@
var mongoose = require('mongoose');
var X2DataLogSchema = new mongoose.Schema({
id: String,
name: String,
type: String,
description: String,
landingZone: String,
speed: {
freeFall: {
vertical: {
max: Number,
avg: Number
},
horizontal: {
max: Number,
avg: Number
}
},
underCanopy: {
vertical: {
max: Number,
avg: Number
},
horizontal: {
max: Number,
avg: Number
}
}
},
glideRatio: {
freeFall: {
max: Number,
avg: Number
},
underCanopy: {
max: Number,
avg: Number
}
},
duration: {
freeFall: Number,
underCanopy: Number
},
distance: {
exitFromLandingZone: Number,
totalFlying: Number,
totalHorizontal: Number
},
altitude: {
exit: Number,
deployment: Number
},
cutaway: String,
malfunctions: [
{
name: String,
type: String
}
],
date: String,
createdOn: String,
author: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }
}, {timestamps: true, toJSON: {virtuals: true}});
X2DataLogSchema.methods.toJSONFor = function() {
return {
id: this.id,
name: this.name,
type: this.type,
description: this.description,
landingZone: this.landingZone,
speed: this.speed,
glideRatio: this.glideRatio,
duration: this.duration,
distance: this.distance,
altitude: this.altitude,
cutaway: this.cutaway,
malfunctions: this.malfunctions,
date: this.date,
createdOn: this.createdOn
};
};
X2DataLogSchema.methods.toJSONForUser = function(user) {
return {
id: this.id,
name: this.name,
type: this.type,
description: this.description,
landingZone: this.landingZone,
speed: this.speed,
glideRatio: this.glideRatio,
duration: this.duration,
distance: this.distance,
altitude: this.altitude,
cutaway: this.cutaway,
malfunctions: this.malfunctions,
date: this.date,
createdOn: this.createdOn,
createdAt: this.createdAt,
updatedAt: this.updatedAt,
author: this.author.toProfileJSONFor(user)
};
};
mongoose.model('X2DataLog', X2DataLogSchema);
+16
View File
@@ -0,0 +1,16 @@
exports.User = require('./User');
exports.Application = require('./Application');
exports.Aeronef = require('./Aeronef');
exports.Canopy = require('./Canopy');
exports.Dropzone = require('./Dropzone');
exports.JumpFile = require('./JumpFile');
exports.Jump = require('./Jump');
exports.Qcm = require('./Qcm');
exports.QcmCategory = require('./QcmCategory');
exports.QcmQuestion = require('./QcmQuestion');
exports.QcmChoice = require('./QcmChoice');
exports.X2DataLog = require('./X2DataLog');
exports.Article = require('./Article');
exports.Comment = require('./Comment');
exports.Tag = require('./Tag');
+2 -2
View File
@@ -1,8 +1,8 @@
const { DataTypes, Model } = require("sequelize");
var crypto = require('crypto');
var jwt = require('jsonwebtoken'),
secret = require('../../../../config').secret,
session_lifetime = require('../../../../config').session_lifetime;
secret = require('../../../config').secret,
session_lifetime = require('../../../config').session_lifetime;
const sequelize = require("../../config/sequelize");