Ajout de la base de données MySQL
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
APP_ENV="development"
|
APP_ENV="development"
|
||||||
NODE_ENV="development"
|
NODE_ENV="development"
|
||||||
DEBUG=false
|
DEBUG=false
|
||||||
SERVER_PORT="3200"
|
SERVER_PORT="3201"
|
||||||
SECRET="$2b$10$2.JkQCRUa3fXESy/WyKVWO"
|
SECRET="$2b$10$2.JkQCRUa3fXESy/WyKVWO"
|
||||||
SESSION_LIFETIME="3600"
|
SESSION_LIFETIME="3600"
|
||||||
MONGODB_URI="mongodb://localhost:27017/adastradb"
|
MONGODB_URI="mongodb://localhost:27017/adastradb"
|
||||||
@@ -14,4 +14,10 @@ COUCHDB_DATABASE="adastradb"
|
|||||||
COUCHDB_DESIGN="adastra_app"
|
COUCHDB_DESIGN="adastra_app"
|
||||||
COUCHDB_CREDENTIAL="cmFtcGV1cjpES3hwMjRQUw=="
|
COUCHDB_CREDENTIAL="cmFtcGV1cjpES3hwMjRQUw=="
|
||||||
SKYDIVERID_API_URL="https://skydiver.id/api"
|
SKYDIVERID_API_URL="https://skydiver.id/api"
|
||||||
SKYDIVERID_API_TOKEN="xmqzgnGYMD.OJgFw1pCXCpJFGmZfSjmWK8lrpqAQNnu"
|
SKYDIVERID_API_TOKEN="xmqzgnGYMD.OJgFw1pCXCpJFGmZfSjmWK8lrpqAQNnu"
|
||||||
|
MYSQL_DBNAME="c4adastracomdb2"
|
||||||
|
MYSQL_DBUSER="c4adastracomu2"
|
||||||
|
MYSQL_DBPASS="kbrnrt5jPK12"
|
||||||
|
MYSQL_DBHOST="ns388640.ip-176-31-255.eu"
|
||||||
|
MYSQL_DBPORT="3306"
|
||||||
|
MYSQL_DBTYPE="mysql"
|
||||||
+7
-1
@@ -1,7 +1,7 @@
|
|||||||
APP_ENV="development"
|
APP_ENV="development"
|
||||||
NODE_ENV="development"
|
NODE_ENV="development"
|
||||||
DEBUG=false
|
DEBUG=false
|
||||||
SERVER_PORT="3200"
|
SERVER_PORT="3201"
|
||||||
SECRET="$2b$10$2.JkQCRUa3fXESy/WyKVWO"
|
SECRET="$2b$10$2.JkQCRUa3fXESy/WyKVWO"
|
||||||
SESSION_LIFETIME=3600
|
SESSION_LIFETIME=3600
|
||||||
MONGODB_URI="mongodb://localhost:27017/adastradb"
|
MONGODB_URI="mongodb://localhost:27017/adastradb"
|
||||||
@@ -15,3 +15,9 @@ COUCHDB_DESIGN="adastra_app"
|
|||||||
COUCHDB_CREDENTIAL="cmFtcGV1cjpES3hwMjRQUw=="
|
COUCHDB_CREDENTIAL="cmFtcGV1cjpES3hwMjRQUw=="
|
||||||
SKYDIVERID_API_URL="https://skydiver.id/api"
|
SKYDIVERID_API_URL="https://skydiver.id/api"
|
||||||
SKYDIVERID_API_TOKEN="xmqzgnGYMD.OJgFw1pCXCpJFGmZfSjmWK8lrpqAQNnu"
|
SKYDIVERID_API_TOKEN="xmqzgnGYMD.OJgFw1pCXCpJFGmZfSjmWK8lrpqAQNnu"
|
||||||
|
MYSQL_DBNAME="c4adastracomdb2"
|
||||||
|
MYSQL_DBUSER="c4adastracomu2"
|
||||||
|
MYSQL_DBPASS="kbrnrt5jPK12"
|
||||||
|
MYSQL_DBHOST="ns388640.ip-176-31-255.eu"
|
||||||
|
MYSQL_DBPORT="3306"
|
||||||
|
MYSQL_DBTYPE="mysql"
|
||||||
|
|||||||
+7
-1
@@ -1,7 +1,7 @@
|
|||||||
APP_ENV="local"
|
APP_ENV="local"
|
||||||
NODE_ENV="development"
|
NODE_ENV="development"
|
||||||
DEBUG=false
|
DEBUG=false
|
||||||
SERVER_PORT="3200"
|
SERVER_PORT="3201"
|
||||||
SECRET="$2b$10$2.JkQCRUa3fXESy/WyKVWO"
|
SECRET="$2b$10$2.JkQCRUa3fXESy/WyKVWO"
|
||||||
SESSION_LIFETIME=3600
|
SESSION_LIFETIME=3600
|
||||||
MONGODB_URI="mongodb://localhost:27017/adastradb"
|
MONGODB_URI="mongodb://localhost:27017/adastradb"
|
||||||
@@ -15,3 +15,9 @@ COUCHDB_DESIGN="adastra_app"
|
|||||||
COUCHDB_CREDENTIAL="cmFtcGV1cjpES3hwMjRQUw=="
|
COUCHDB_CREDENTIAL="cmFtcGV1cjpES3hwMjRQUw=="
|
||||||
SKYDIVERID_API_URL="https://skydiver.id/api"
|
SKYDIVERID_API_URL="https://skydiver.id/api"
|
||||||
SKYDIVERID_API_TOKEN="xmqzgnGYMD.OJgFw1pCXCpJFGmZfSjmWK8lrpqAQNnu"
|
SKYDIVERID_API_TOKEN="xmqzgnGYMD.OJgFw1pCXCpJFGmZfSjmWK8lrpqAQNnu"
|
||||||
|
MYSQL_DBNAME="c4adastracomdb2"
|
||||||
|
MYSQL_DBUSER="c4adastracomu2"
|
||||||
|
MYSQL_DBPASS="kbrnrt5jPK12"
|
||||||
|
MYSQL_DBHOST="ns388640.ip-176-31-255.eu"
|
||||||
|
MYSQL_DBPORT="3306"
|
||||||
|
MYSQL_DBTYPE="mysql"
|
||||||
|
|||||||
+7
-1
@@ -1,7 +1,7 @@
|
|||||||
APP_ENV="production"
|
APP_ENV="production"
|
||||||
NODE_ENV="production"
|
NODE_ENV="production"
|
||||||
DEBUG=false
|
DEBUG=false
|
||||||
SERVER_PORT="3200"
|
SERVER_PORT="3201"
|
||||||
SECRET="$2b$10$2.JkQCRUa3fXESy/WyKVWO"
|
SECRET="$2b$10$2.JkQCRUa3fXESy/WyKVWO"
|
||||||
SESSION_LIFETIME=3600
|
SESSION_LIFETIME=3600
|
||||||
MONGODB_URI="mongodb://localhost:27017/adastradb"
|
MONGODB_URI="mongodb://localhost:27017/adastradb"
|
||||||
@@ -15,3 +15,9 @@ COUCHDB_DESIGN="adastra_app"
|
|||||||
COUCHDB_CREDENTIAL="cmFtcGV1cjpES3hwMjRQUw=="
|
COUCHDB_CREDENTIAL="cmFtcGV1cjpES3hwMjRQUw=="
|
||||||
SKYDIVERID_API_URL="https://skydiver.id/api"
|
SKYDIVERID_API_URL="https://skydiver.id/api"
|
||||||
SKYDIVERID_API_TOKEN="xmqzgnGYMD.OJgFw1pCXCpJFGmZfSjmWK8lrpqAQNnu"
|
SKYDIVERID_API_TOKEN="xmqzgnGYMD.OJgFw1pCXCpJFGmZfSjmWK8lrpqAQNnu"
|
||||||
|
MYSQL_DBNAME="c4adastracomdb2"
|
||||||
|
MYSQL_DBUSER="c4adastracomu2"
|
||||||
|
MYSQL_DBPASS="kbrnrt5jPK12"
|
||||||
|
MYSQL_DBHOST="ns388640.ip-176-31-255.eu"
|
||||||
|
MYSQL_DBPORT="3306"
|
||||||
|
MYSQL_DBTYPE="mysql"
|
||||||
|
|||||||
@@ -62,5 +62,3 @@ sonar.properties
|
|||||||
**/*.copy.ts
|
**/*.copy.ts
|
||||||
**/*.copy.scss
|
**/*.copy.scss
|
||||||
**/*.copy.html
|
**/*.copy.html
|
||||||
|
|
||||||
middlewares
|
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ const { promisify } = require('util'),
|
|||||||
bodyParser = require('body-parser'),
|
bodyParser = require('body-parser'),
|
||||||
chalk = require('chalk'),
|
chalk = require('chalk'),
|
||||||
utils = require('./routes/utils'),
|
utils = require('./routes/utils'),
|
||||||
exceptionHandler = require('./middlewares/exceptions.handler.js');
|
exceptionHandler = require('./middlewares/exceptions.handler.js'),
|
||||||
|
connectDB = require('./src/services/connectDB');
|
||||||
var express = require('express'),
|
var express = require('express'),
|
||||||
session = require('express-session'),
|
session = require('express-session'),
|
||||||
cors = require('cors'),
|
cors = require('cors'),
|
||||||
@@ -65,6 +66,8 @@ if(isProduction){
|
|||||||
require('./models/mongo');
|
require('./models/mongo');
|
||||||
require('./config/passport');
|
require('./config/passport');
|
||||||
|
|
||||||
|
|
||||||
|
connectDB();
|
||||||
app.use(require('./routes'));
|
app.use(require('./routes'));
|
||||||
|
|
||||||
app.use(exceptionHandler.notFoundErrorHandler);
|
app.use(exceptionHandler.notFoundErrorHandler);
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
var appEnv = process.env.APP_ENV;
|
||||||
|
if (appEnv == undefined) {
|
||||||
|
appEnv = 'development';
|
||||||
|
}
|
||||||
|
const isProduction = appEnv === 'production',
|
||||||
|
chalk = require('chalk'),
|
||||||
|
utils = require('../routes/utils');
|
||||||
|
|
||||||
|
const exceptionHandler = {
|
||||||
|
notFoundErrorHandler: (req, res, next) => {
|
||||||
|
let err = new Error('Not Found');
|
||||||
|
err.status = 404;
|
||||||
|
console.log(`${utils.getDateTimeISOString()}`, chalk.yellow(`${err.status} ${err.message}`));
|
||||||
|
next(err);
|
||||||
|
},
|
||||||
|
logErrorHandler: (err, req, res, next) => {
|
||||||
|
console.log(`${utils.getDateTimeISOString()}`, chalk.red(`error handler : ${err.message} ${err.err}`));
|
||||||
|
console.error(err.stack);
|
||||||
|
next(err);
|
||||||
|
},
|
||||||
|
clientErrorHandler: (err, req, res, next) => {
|
||||||
|
if (req.xhr) {
|
||||||
|
res.status(err.status || 500);
|
||||||
|
} else {
|
||||||
|
next(err);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
fianlErrorHandler: (err, req, res, next) => {
|
||||||
|
res.status(err.status || 500);
|
||||||
|
if (!isProduction) {
|
||||||
|
/* development error handler will print stacktrace */
|
||||||
|
res.json({errors: {
|
||||||
|
message: err.message,
|
||||||
|
error: err.err,
|
||||||
|
stack: err.stack
|
||||||
|
}});
|
||||||
|
} else {
|
||||||
|
/* production error handler no stacktraces leaked to user */
|
||||||
|
res.json({errors: {
|
||||||
|
message: err.message,
|
||||||
|
error: {},
|
||||||
|
stack: {}
|
||||||
|
}});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = exceptionHandler;
|
||||||
+8
-2
@@ -3,7 +3,7 @@
|
|||||||
"APP_ENV": "local",
|
"APP_ENV": "local",
|
||||||
"NODE_ENV" : "development",
|
"NODE_ENV" : "development",
|
||||||
"DEBUG": false,
|
"DEBUG": false,
|
||||||
"SERVER_PORT": "3200",
|
"SERVER_PORT": "3201",
|
||||||
"SECRET": "$2b$10$aEsAUG7Dy8dcTORi1vaQle",
|
"SECRET": "$2b$10$aEsAUG7Dy8dcTORi1vaQle",
|
||||||
"SESSION_LIFETIME": "3600",
|
"SESSION_LIFETIME": "3600",
|
||||||
"MONGODB_URI": "mongodb://localhost:27017/adastradb",
|
"MONGODB_URI": "mongodb://localhost:27017/adastradb",
|
||||||
@@ -16,6 +16,12 @@
|
|||||||
"COUCHDB_DESIGN": "adastra_app",
|
"COUCHDB_DESIGN": "adastra_app",
|
||||||
"COUCHDB_CREDENTIAL": "cmFtcGV1cjpES3hwMjRQUw==",
|
"COUCHDB_CREDENTIAL": "cmFtcGV1cjpES3hwMjRQUw==",
|
||||||
"SKYDIVERID_API_URL": "https://skydiver.id/api",
|
"SKYDIVERID_API_URL": "https://skydiver.id/api",
|
||||||
"SKYDIVERID_API_TOKEN": "xmqzgnGYMD.OJgFw1pCXCpJFGmZfSjmWK8lrpqAQNnu"
|
"SKYDIVERID_API_TOKEN": "xmqzgnGYMD.OJgFw1pCXCpJFGmZfSjmWK8lrpqAQNnu",
|
||||||
|
"MYSQL_DBNAME": "c4adastracomdb2",
|
||||||
|
"MYSQL_DBUSER": "c4adastracomu2",
|
||||||
|
"MYSQL_DBPASS": "kbrnrt5jPK12",
|
||||||
|
"MYSQL_DBHOST": "ns388640.ip-176-31-255.eu",
|
||||||
|
"MYSQL_DBPORT": "3306",
|
||||||
|
"MYSQL_DBTYPE": "mysql"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+955
-7
File diff suppressed because it is too large
Load Diff
+5
-2
@@ -45,13 +45,16 @@
|
|||||||
"request": "^2.88.2",
|
"request": "^2.88.2",
|
||||||
"slug": "^8.2.3",
|
"slug": "^8.2.3",
|
||||||
"underscore": "^1.13.6",
|
"underscore": "^1.13.6",
|
||||||
"uuid": "^9.0.1"
|
"uuid": "^9.0.1",
|
||||||
|
"sequelize": "^6.37.3",
|
||||||
|
"mysql2": "^3.14.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "^9.0.0",
|
"@eslint/js": "^9.0.0",
|
||||||
"eslint": "^9.0.0",
|
"eslint": "^9.0.0",
|
||||||
"globals": "^15.0.0",
|
"globals": "^15.0.0",
|
||||||
"newman": "^5.3.2",
|
"newman": "^5.3.2",
|
||||||
"nodemon": "^2.0.22"
|
"nodemon": "^2.0.22",
|
||||||
|
"sequelize-cli": "^6.6.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-15
@@ -1,19 +1,19 @@
|
|||||||
var router = require('express').Router();
|
var routes = require('express').Router();
|
||||||
|
|
||||||
router.use('/', require('./users'));
|
routes.use('/', require('./users'));
|
||||||
router.use('/articles', require('./articles'));
|
routes.use('/articles', require('./articles'));
|
||||||
router.use('/comments', require('./comments'));
|
routes.use('/comments', require('./comments'));
|
||||||
router.use('/tags', require('./tags'));
|
routes.use('/tags', require('./tags'));
|
||||||
router.use('/profiles', require('./profiles'));
|
routes.use('/profiles', require('./profiles'));
|
||||||
router.use('/applications', require('./applications'));
|
routes.use('/applications', require('./applications'));
|
||||||
router.use('/aeronefs', require('./aeronefs'));
|
routes.use('/aeronefs', require('./aeronefs'));
|
||||||
router.use('/canopies', require('./canopies'));
|
routes.use('/canopies', require('./canopies'));
|
||||||
router.use('/dropzones', require('./dropzones'));
|
routes.use('/dropzones', require('./dropzones'));
|
||||||
router.use('/jumps', require('./jumps'));
|
routes.use('/jumps', require('./jumps'));
|
||||||
router.use('/pages', require('./pages'));
|
routes.use('/pages', require('./pages'));
|
||||||
router.use('/qcm', require('./qcm'));
|
routes.use('/qcm', require('./qcm'));
|
||||||
|
|
||||||
router.use(function (err, req, res, next) {
|
routes.use(function (err, req, res, next) {
|
||||||
if (err.name === 'ValidationError') {
|
if (err.name === 'ValidationError') {
|
||||||
return res.status(422).json({
|
return res.status(422).json({
|
||||||
errors: Object.keys(err.errors).reduce(function (errors, key) {
|
errors: Object.keys(err.errors).reduce(function (errors, key) {
|
||||||
@@ -25,4 +25,4 @@ router.use(function (err, req, res, next) {
|
|||||||
return next(err);
|
return next(err);
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = routes;
|
||||||
+3
-3
@@ -1,4 +1,4 @@
|
|||||||
var router = require('express').Router();
|
var routes = require('express').Router();
|
||||||
router.use('/api', require('./api'));
|
routes.use('/api', require('./api'));
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = routes;
|
||||||
|
|||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
//import express to use express methods and properties
|
||||||
|
const express = require('express');
|
||||||
|
const routes = require('./routes');
|
||||||
|
|
||||||
|
//create an instance of express
|
||||||
|
const app = express();
|
||||||
|
|
||||||
|
//use express.json() to parse incoming requests with JSON payloads
|
||||||
|
app.use(express.json());
|
||||||
|
app.use(express.urlencoded({ extended: true })); //parse incoming requests with urlencoded payloads
|
||||||
|
|
||||||
|
app.use('/api/v1', routes);
|
||||||
|
|
||||||
|
//catch all routes that are not defined to avoid running into errors when a route is not defined
|
||||||
|
app.use('*', (req, res) => {
|
||||||
|
res.status(404).json({ error: 'Path does not found, try again' });
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = app; //export app to be used in other files
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
const { ArticleService } = require('../services/article.service');
|
||||||
|
|
||||||
|
const createArticle = async (req, res) => {
|
||||||
|
try {
|
||||||
|
const { name, description, userId } = req.body;
|
||||||
|
|
||||||
|
const article = await ArticleService.createArticle({
|
||||||
|
name,
|
||||||
|
description,
|
||||||
|
userId,
|
||||||
|
});
|
||||||
|
|
||||||
|
res.status(201).json({
|
||||||
|
message: 'Article created successfully',
|
||||||
|
data: article,
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
res.status(500).json({
|
||||||
|
message: 'something went wrong while creating article',
|
||||||
|
error: err.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getArticlesByUserId = async (req, res) => {
|
||||||
|
try {
|
||||||
|
const { userId } = req.params;
|
||||||
|
|
||||||
|
const articles = await ArticleService.getArticlesByUserId(userId);
|
||||||
|
|
||||||
|
res.status(200).json({
|
||||||
|
data: articles,
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
res.status(500).json({
|
||||||
|
message: 'something went wrong while fetching articles',
|
||||||
|
error: err.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = { createArticle, getArticlesByUserId };
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
const { UserService } = require('../services/user.service');
|
||||||
|
|
||||||
|
const createUser = async (req, res) => {
|
||||||
|
try {
|
||||||
|
const { name, email } = req.body;
|
||||||
|
|
||||||
|
const user = await UserService.createUser({ name, email });
|
||||||
|
|
||||||
|
res.status(201).json({
|
||||||
|
message: 'User created successfully',
|
||||||
|
data: user,
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
res.status(500).json({
|
||||||
|
message: 'something went wrong while creating user',
|
||||||
|
error: err.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getAllUsers = async (req, res) => {
|
||||||
|
try {
|
||||||
|
const users = await UserService.getAllUsers();
|
||||||
|
|
||||||
|
res.status(200).json({
|
||||||
|
data: users,
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
res.status(500).json({
|
||||||
|
message: 'something went wrong while fetching users',
|
||||||
|
error: err.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = { createUser, getAllUsers };
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
module.exports = {
|
||||||
|
"development": {
|
||||||
|
"username": process.env.MYSQL_DBUSER,
|
||||||
|
"password": process.env.MYSQL_DBPASS,
|
||||||
|
"database": process.env.MYSQL_DBNAME,
|
||||||
|
"host": process.env.MYSQL_DBHOST,
|
||||||
|
"port": process.env.MYSQL_DBPORT,
|
||||||
|
"dialect": process.env.MYSQL_DBTYPE
|
||||||
|
},
|
||||||
|
"test": {
|
||||||
|
"username": process.env.MYSQL_DBUSER,
|
||||||
|
"password": process.env.MYSQL_DBPASS,
|
||||||
|
"database": process.env.MYSQL_DBNAME,
|
||||||
|
"host": process.env.MYSQL_DBHOST,
|
||||||
|
"port": process.env.MYSQL_DBPORT,
|
||||||
|
"dialect": process.env.MYSQL_DBTYPE
|
||||||
|
},
|
||||||
|
"production": {
|
||||||
|
"username": process.env.MYSQL_DBUSER,
|
||||||
|
"password": process.env.MYSQL_DBPASS,
|
||||||
|
"database": process.env.MYSQL_DBNAME,
|
||||||
|
"host": process.env.MYSQL_DBHOST,
|
||||||
|
"port": process.env.MYSQL_DBPORT,
|
||||||
|
"dialect": process.env.MYSQL_DBTYPE,
|
||||||
|
"dialectOptions": {
|
||||||
|
"ssl": {
|
||||||
|
// enable this for production environment only if using a secure connection
|
||||||
|
"require": true,
|
||||||
|
"rejectUnauthorized": false
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
const { Sequelize } = require('sequelize');
|
||||||
|
|
||||||
|
const Op = Sequelize.Op;
|
||||||
|
const sequelize = new Sequelize(
|
||||||
|
process.env.MYSQL_DBNAME,
|
||||||
|
process.env.MYSQL_DBUSER,
|
||||||
|
process.env.MYSQL_DBPASS,
|
||||||
|
{
|
||||||
|
host: process.env.MYSQL_DBHOST,
|
||||||
|
port: process.env.MYSQL_DBPORT,
|
||||||
|
dialect: process.env.MYSQL_DBTYPE,
|
||||||
|
$like: Op.like,
|
||||||
|
$not: Op.not,
|
||||||
|
timezone: '+02:00',
|
||||||
|
define: {
|
||||||
|
charset: 'utf8mb4',
|
||||||
|
collate: 'utf8mb4_general_ci',
|
||||||
|
underscored: false,
|
||||||
|
freezeTableName: true,
|
||||||
|
},
|
||||||
|
pool: {
|
||||||
|
//explain this line of code? this means that the connection pool will have a minimum of 0 connections and a maximum of 5 connections
|
||||||
|
min: 0,
|
||||||
|
max: 5,
|
||||||
|
},
|
||||||
|
logQueryParameters: process.env.APP_ENV === 'development', // this line of code will log the query parameters if the environment is development
|
||||||
|
benchmark: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
const checkConnection = async () => {
|
||||||
|
try {
|
||||||
|
await sequelize.authenticate();
|
||||||
|
console.log(`DB Connected`.cyan.underline.bold);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Unable to connect to the database:".red.bold, error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
checkConnection();
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = sequelize;
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
const sequelize = require('./config/sequelize');
|
||||||
|
const ArticleModel = require('./models/article');
|
||||||
|
const UserModel = require('./models/user');
|
||||||
|
|
||||||
|
const DB = {
|
||||||
|
sequelize,
|
||||||
|
User: UserModel(sequelize),
|
||||||
|
Article: ArticleModel(sequelize),
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = DB;
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
'use strict';
|
||||||
|
/** @type {import('sequelize-cli').Migration} */
|
||||||
|
module.exports = {
|
||||||
|
async up(queryInterface, Sequelize) {
|
||||||
|
await queryInterface.createTable('Users', {
|
||||||
|
id: {
|
||||||
|
allowNull: false,
|
||||||
|
autoIncrement: true,
|
||||||
|
primaryKey: true,
|
||||||
|
type: Sequelize.INTEGER,
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
type: Sequelize.STRING,
|
||||||
|
},
|
||||||
|
email: {
|
||||||
|
type: Sequelize.STRING,
|
||||||
|
},
|
||||||
|
createdAt: {
|
||||||
|
allowNull: false,
|
||||||
|
type: Sequelize.DATE,
|
||||||
|
defaultValue: Sequelize.NOW,
|
||||||
|
},
|
||||||
|
updatedAt: {
|
||||||
|
allowNull: false,
|
||||||
|
type: Sequelize.DATE,
|
||||||
|
defaultValue: Sequelize.NOW,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
async down(queryInterface, Sequelize) {
|
||||||
|
await queryInterface.dropTable('Users');
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
'use strict';
|
||||||
|
/** @type {import('sequelize-cli').Migration} */
|
||||||
|
module.exports = {
|
||||||
|
async up(queryInterface, Sequelize) {
|
||||||
|
await queryInterface.createTable('article', {
|
||||||
|
id: {
|
||||||
|
allowNull: false,
|
||||||
|
autoIncrement: true,
|
||||||
|
primaryKey: true,
|
||||||
|
type: Sequelize.INTEGER,
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
type: Sequelize.STRING,
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
type: Sequelize.TEXT,
|
||||||
|
},
|
||||||
|
userId: {
|
||||||
|
type: Sequelize.INTEGER,
|
||||||
|
allowNull: false,
|
||||||
|
references: {
|
||||||
|
model: 'User',
|
||||||
|
key: 'id',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
createdAt: {
|
||||||
|
allowNull: false,
|
||||||
|
type: Sequelize.DATE,
|
||||||
|
defaultValue: Sequelize.NOW,
|
||||||
|
},
|
||||||
|
updatedAt: {
|
||||||
|
allowNull: false,
|
||||||
|
type: Sequelize.DATE,
|
||||||
|
defaultValue: Sequelize.NOW,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
async down(queryInterface, Sequelize) {
|
||||||
|
await queryInterface.dropTable('article');
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
const { DataTypes, Model } = require("sequelize");
|
||||||
|
const sequelize = require("../config/sequelize");
|
||||||
|
const slug = require("slug");
|
||||||
|
|
||||||
|
class Article extends Model { }
|
||||||
|
|
||||||
|
const ArticleModel = () => {
|
||||||
|
Article.init(
|
||||||
|
{
|
||||||
|
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true, allowNull: false },
|
||||||
|
slug: { type: DataTypes.STRING, allowNull: false },
|
||||||
|
title: { type: DataTypes.STRING, allowNull: false },
|
||||||
|
description: { type: DataTypes.TEXT },
|
||||||
|
body: { type: DataTypes.TEXT, allowNull: false }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sequelize,
|
||||||
|
modelName: 'Article',
|
||||||
|
tableName: 'article',
|
||||||
|
timestamps: true,
|
||||||
|
createdAt: true,
|
||||||
|
updatedAt: true
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
Article.beforeValidate((article) => {
|
||||||
|
article.slug =slug(`${article.title}`) + '-' + (Math.random() * Math.pow(36, 6) | 0).toString(36);
|
||||||
|
});
|
||||||
|
|
||||||
|
Article.prototype.toJSONFor = function () {
|
||||||
|
return {
|
||||||
|
id: this.id,
|
||||||
|
slug: this.slug,
|
||||||
|
title: this.title,
|
||||||
|
description: this.description,
|
||||||
|
body: this.body
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
return Article;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = ArticleModel;
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
const { DataTypes, Model } = require("sequelize");
|
||||||
|
const sequelize = require("../config/sequelize");
|
||||||
|
const bcrypt = require("bcrypt");
|
||||||
|
|
||||||
|
class User extends Model { }
|
||||||
|
|
||||||
|
const UserModel = () => {
|
||||||
|
User.init(
|
||||||
|
{
|
||||||
|
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true, allowNull: false },
|
||||||
|
email: { type: DataTypes.STRING, allowNull: false, unique: true },
|
||||||
|
username: { type: DataTypes.STRING, allowNull: false, unique: true },
|
||||||
|
firstname: { type: DataTypes.STRING },
|
||||||
|
lastname: { type: DataTypes.STRING },
|
||||||
|
bio: { type: DataTypes.TEXT, allowNull: true },
|
||||||
|
image: { type: DataTypes.TEXT, allowNull: true },
|
||||||
|
role: { type: DataTypes.STRING },
|
||||||
|
password: { type: DataTypes.STRING, allowNull: false }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sequelize,
|
||||||
|
modelName: 'User',
|
||||||
|
tableName: 'user',
|
||||||
|
timestamps: false,
|
||||||
|
createdAt: true,
|
||||||
|
updatedAt: true
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
Model.prototype.matchPassword = async function (enteredPassword) {
|
||||||
|
return await bcrypt.compare(enteredPassword, this.password);
|
||||||
|
};
|
||||||
|
|
||||||
|
const DEFAULT_SALT_ROUNDS = 10;
|
||||||
|
|
||||||
|
User.addHook("beforeCreate", async (user) => {
|
||||||
|
const encryptedPassword = await bcrypt.hash(
|
||||||
|
user.password,
|
||||||
|
DEFAULT_SALT_ROUNDS
|
||||||
|
);
|
||||||
|
user.password = encryptedPassword;
|
||||||
|
});
|
||||||
|
|
||||||
|
User.prototype.toJSONFor = function () {
|
||||||
|
return {
|
||||||
|
id: this.id,
|
||||||
|
email: this.email,
|
||||||
|
username: this.username,
|
||||||
|
firstname: this.firstname,
|
||||||
|
lastname: this.lastname,
|
||||||
|
bio: this.bio,
|
||||||
|
image: this.image,
|
||||||
|
role: this.role
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
return User;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = UserModel;
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
const DB = require('../index');
|
||||||
|
|
||||||
|
const associate = () => {
|
||||||
|
DB.User.hasMany(DB.Article, {
|
||||||
|
foreignKey: 'userId',
|
||||||
|
as: 'projects',
|
||||||
|
});
|
||||||
|
|
||||||
|
DB.Article.belongsTo(DB.User, {
|
||||||
|
foreignKey: 'userId',
|
||||||
|
as: 'user',
|
||||||
|
});
|
||||||
|
/*
|
||||||
|
DB.User.belongsToMany(DB.User, { as: "followers", through: "Followers", foreignKey: "userId", timestamps: false });
|
||||||
|
DB.User.belongsToMany(DB.User, { as: "following", through: "Followers", foreignKey: "followerId", timestamps: false });
|
||||||
|
DB.User.hasMany(DB.Article, { foreignKey: "authorId", onDelete: "CASCADE" });
|
||||||
|
DB.Article.belongsTo(DB.User, { as: "author", foreignKey: "authorId" });
|
||||||
|
DB.User.hasMany(DB.Comment, { foreignKey: "authorId", onDelete: "CASCADE" });
|
||||||
|
DB.Comment.belongsTo(DB.User, { as: "author", foreignKey: "authorId" });
|
||||||
|
DB.Article.hasMany(DB.omment, { foreignKey: "articleId", onDelete: "CASCADE" });
|
||||||
|
DB.Comment.belongsTo(DB.Article, { foreignKey: "articleId" });
|
||||||
|
DB.User.belongsToMany(DB.Article, { as: "favorites", through: "Favorites", timestamps: false });
|
||||||
|
DB.Article.belongsToMany(DB.User, { through: "Favorites", foreignKey: "articleId", timestamps: false });
|
||||||
|
DB.Article.belongsToMany(DB.Tag, { through: "TagLists", as: "tagLists", foreignKey: "articleId", timestamps: false, onDelete: "CASCADE" });
|
||||||
|
DB.Tag.belongsToMany(DB.Article, { through: "ArticleTags", uniqueKey: false, timestamps: false });
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = associate;
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
console.log('this is placeholder for models');
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
const express = require('express');
|
||||||
|
const { createProject, getProjectsByUserId } = require('../../controllers/article.controller');
|
||||||
|
|
||||||
|
const projectRouter = express.Router();
|
||||||
|
|
||||||
|
projectRouter.post('/', createProject);
|
||||||
|
projectRouter.get('/:userId', getProjectsByUserId);
|
||||||
|
|
||||||
|
module.exports = projectRouter;
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
const express = require('express');
|
||||||
|
const { createUser, getAllUsers } = require('../../controllers/user.controller');
|
||||||
|
|
||||||
|
const userRouter = express.Router();
|
||||||
|
|
||||||
|
userRouter.post('/register', createUser);
|
||||||
|
userRouter.get('/', getAllUsers);
|
||||||
|
|
||||||
|
module.exports = userRouter;
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
const express = require('express');
|
||||||
|
const articleRouter = require('./api/article.routes');
|
||||||
|
const userRouter = require('./api/user.routes');
|
||||||
|
|
||||||
|
const routes = express.Router();
|
||||||
|
|
||||||
|
routes.use('/user', userRouter);
|
||||||
|
routes.use('/article', articleRouter);
|
||||||
|
|
||||||
|
module.exports = routes;
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
const http = require('http'); // import the http module from node.js core to create a server instance
|
||||||
|
const app = require('./app'); // import the express app from the app.js file
|
||||||
|
const connectDB = require('./services/connectDB');
|
||||||
|
|
||||||
|
const PORT = process.env.PORT || 3000; // set the port number to be used by the server instance
|
||||||
|
|
||||||
|
/* create a server instance using the http.createServer method
|
||||||
|
* there is no right or wrong way to create a server instance weather using the http.createServer method or the app.listen method
|
||||||
|
* I usualy use the http.createServer method because it gives me more control over the server instance like adding a socket.io instance to the server instance
|
||||||
|
*/
|
||||||
|
const server = http.createServer(app);
|
||||||
|
|
||||||
|
// Adding server instance inside a callback function also gives a flexibility to add more logic before starting the server
|
||||||
|
const startServer = () => {
|
||||||
|
// Listen to the server instance on the specified port number
|
||||||
|
connectDB(); // connect to the database before starting the server
|
||||||
|
server.listen(PORT, () => {
|
||||||
|
console.log(
|
||||||
|
`Server is running on port ${PORT} AND NODE_ENV is ${process.env.NODE_ENV}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
startServer(); // start the server instance
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
const DB = require('../database');
|
||||||
|
|
||||||
|
const { Projects } = DB;
|
||||||
|
|
||||||
|
module.exports = class ProjectService {
|
||||||
|
static async createProject(data) {
|
||||||
|
return Projects.create(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static async getProjectsByUserId(userId) {
|
||||||
|
return Projects.findAll({
|
||||||
|
where: { userId },
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: DB.Users,
|
||||||
|
as: 'user',
|
||||||
|
attributes: ['name', 'email'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
order: [['createdAt', 'DESC']],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
const DB = require('../database');
|
||||||
|
const sequelize = require('../database/config/sequelize');
|
||||||
|
const associate = require('../database/relationships');
|
||||||
|
|
||||||
|
// Connect to the database and log a message to the console
|
||||||
|
const connectDB = async () => {
|
||||||
|
try {
|
||||||
|
await sequelize.authenticate();
|
||||||
|
console.log('Connection has been established successfully🔥');
|
||||||
|
|
||||||
|
// Synchronize the database with the models without need of dropping the tables
|
||||||
|
await DB.sequelize.sync({
|
||||||
|
force: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
associate(); // Call the associate function to create the relationships between the models
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Unable to connect to the database:', error);
|
||||||
|
process.exit(1); // Exit the process if the connection is not successful
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = connectDB;
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
const DB = require('../database');
|
||||||
|
|
||||||
|
const { Users } = DB;
|
||||||
|
|
||||||
|
module.exports = class UserService {
|
||||||
|
static async createUser(data) {
|
||||||
|
return Users.create(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static async getAllUsers() {
|
||||||
|
return Users.findAll({
|
||||||
|
order: [['createdAt', 'DESC']],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static async getUserById(id) {
|
||||||
|
return Users.findByPk(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//module.exports = userService;
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
console.log('this is placeholder for routes');
|
||||||
Reference in New Issue
Block a user