diff --git a/Dockerfile b/Dockerfile index b46ebd3..d17164e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -37,6 +37,6 @@ RUN mv /opt/database/suiviLootWow.db /opt/schema/suiviLootWow.db COPY ./docker-entrypoint.sh /docker-entrypoint.sh RUN chmod +x /docker-entrypoint.sh -EXPOSE 3021 +EXPOSE 3201 ENTRYPOINT "/docker-entrypoint.sh" diff --git a/configuration/server.config.js b/configuration/server.config.js index 3967fed..608d6df 100644 --- a/configuration/server.config.js +++ b/configuration/server.config.js @@ -3,7 +3,7 @@ export default { secret: 'e8p$2!76QKq%Wi3q8sU#qwvXqX2o2%mz', database: { development: { - path: 'D:/ProjetWeb/suivi-loot-wow-api/suiviLootWow.db' + path: './suiviLootWow.db' }, production: { path: '/opt/database/suiviLootWow.db' diff --git a/controllers/config.controller.js b/controllers/config.controller.js new file mode 100644 index 0000000..1d44db8 --- /dev/null +++ b/controllers/config.controller.js @@ -0,0 +1,27 @@ +import configService from '../services/config.service.js'; +import typesError from '../error/types.error.js'; + +const getConfig = async (request, reply) => { + try { + const config = await configService.getConfig() + return reply.code(200).send({ config: config.toJson() }) + } catch (e) { + return reply.code(500).send({ message: e.message }) + } +} + +const updateConfig = async (request, reply) => { + const newConfig = request.body + try { + await configService.updateConfig(newConfig) + return reply.code(200).send({ success: true }) + } catch (e) { + return reply.code(500).send({ message: typesError.TECHNICAL_UNKNOWN }) + } +} + + +export default { + getConfig, + updateConfig +} diff --git a/controllers/suivi.controller.js b/controllers/suivi.controller.js index 8015cb4..30fc8fc 100644 --- a/controllers/suivi.controller.js +++ b/controllers/suivi.controller.js @@ -1,4 +1,5 @@ import suiviService from '../services/suivi.service.js'; +import configService from '../services/config.service.js'; import typesError from '../error/types.error.js'; import { DateTime } from 'luxon' @@ -108,7 +109,10 @@ const deleteHistories = async (request, reply) => { const getBisList = async (request, reply) => { try { - const bisList = await suiviService.getBisList() + const config = await configService.getConfig() + const config_ = config.toJson() + const raidDate = config_.startingDateRaid + const bisList = await suiviService.getBisList(raidDate) return reply.code(200).send({ bis: bisList }) } catch (e) { return reply.code(500).send({ message: e.message }) diff --git a/dao/config.dao.js b/dao/config.dao.js new file mode 100644 index 0000000..29ce43d --- /dev/null +++ b/dao/config.dao.js @@ -0,0 +1,76 @@ +import sqlite3 from 'sqlite3' +import bcrypt from 'bcryptjs' +import ErrorType from '../error/types.error.js' +import serverConfig from '../configuration/server.config.js' + +sqlite3.verbose() + +const tableName = 'Config' + +class Config { + constructor(options = {}) { + this.id = options.id + this.startingDateRaid = options.startingDateRaid + } + + static find() { + return new Promise((resolve, reject) => { + const db = openDB() + db.serialize(() => { + db.all(`SELECT * FROM ${tableName}`, (err, configs) => { + if (err) reject(new Error(ErrorType.TECHNICAL_UNKNOWN)) + else { + if (configs.length) { + const config = createConfigFromDB(configs[0]) + resolve(config); + } else reject(new Error(ErrorType.TECHNICAL_UNKNOWN)) + } + }) + closeDB(db) + }) + }) + } + + async update() { + return new Promise((resolve, reject) => { + const db = openDB(); + db.serialize(() => { + db.run(`UPDATE ${tableName} SET startingDateRaid = ${this.startingDateRaid} WHERE id = ${this.id}`, err => { + if (err) reject(new Error(ErrorType.TECHNICAL_UNKNOWN)) + else resolve() + }) + }) + closeDB(db) + }) + } + + toJson() { + return { + id: this.id, + startingDateRaid: this.startingDateRaid + } + } +} + +export default Config + +function openDB() { + const env = process.env.NODE_ENV || 'development' + return new sqlite3.Database(serverConfig.database[env].path, err => { + if (err) throw new Error(err) + }) +} + +function closeDB(db) { + db.close(err => { + if (err) throw new Error(err) + }) +} + +function createConfigFromDB(dbUser) { + return new Config({ + id: dbUser.id, + startingDateRaid: dbUser.startingDateRaid + }) +} + diff --git a/dao/roster.dao.js b/dao/roster.dao.js index 06d3ab1..398ea47 100644 --- a/dao/roster.dao.js +++ b/dao/roster.dao.js @@ -36,7 +36,7 @@ class Roster { }) } - static getBisData() { + static getBisData(raidDate) { return new Promise((resolve, reject) => { const db = openDB() db.serialize(() => { @@ -56,7 +56,7 @@ FROM ${tableName} LEFT JOIN ${historyTableName} ON ${tableName}.name = ${historyTableName}.name -WHERE ${historyTableName}.response = 'Bis' +WHERE ${historyTableName}.response = 'Bis' and ${historyTableName}.fullDate >= ${raidDate} GROUP BY ${tableName}.name, ${tableName}.classe; ` @@ -146,10 +146,8 @@ function createBisFromDB(res) { taille: 0, jambes: 0, pied: 0, - doigt1: 0, - doigt2: 0, - bijou1: 0, - bijou2: 0, + doigt: 0, + bijou: 0, arme: 0, mainGauche: 0, relique: 0 @@ -201,13 +199,11 @@ function createBisFromDB(res) { totalBIS += 1 break case 'Doigt': - if (data.doigt1 === 0) data.doigt1 += 1 - else data.doigt2 += 1 + data.doigt += 1 totalBIS += 1 break case 'Bijou': - if (data.bijou1 === 0) data.bijou1 += 1 - else data.bijou2 += 1 + data.bijou += 1 totalBIS += 1 break case 'À une main': diff --git a/database/migrations/20241004120002-add-config.js b/database/migrations/20241004120002-add-config.js new file mode 100644 index 0000000..d53ca7d --- /dev/null +++ b/database/migrations/20241004120002-add-config.js @@ -0,0 +1,22 @@ +'use strict'; + +/** @type {import('sequelize-cli').Migration} */ +module.exports = { + async up (queryInterface, Sequelize) { + await queryInterface.createTable('Config', { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER + }, + startingDateRaid: { + type: Sequelize.INTEGER + } + }); + }, + + async down (queryInterface, Sequelize) { + await queryInterface.dropTable('Config'); + } +}; diff --git a/database/seeders/development/20241004120712-add_initial_config.js b/database/seeders/development/20241004120712-add_initial_config.js new file mode 100644 index 0000000..a1fefd8 --- /dev/null +++ b/database/seeders/development/20241004120712-add_initial_config.js @@ -0,0 +1,15 @@ +'use strict'; + +/** @type {import('sequelize-cli').Migration} */ +module.exports = { + async up (queryInterface, Sequelize) { + await queryInterface.bulkInsert('Config', [{ + id: 1, + startingDateRaid: 1717020000000, + }], {}) + }, + + async down (queryInterface, Sequelize) { + await queryInterface.bulkDelete('Config', null, {}) + } +}; diff --git a/database/seeders/production/20241004120712-add_initial_config.js b/database/seeders/production/20241004120712-add_initial_config.js new file mode 100644 index 0000000..603ad17 --- /dev/null +++ b/database/seeders/production/20241004120712-add_initial_config.js @@ -0,0 +1,15 @@ +'use strict'; + +/** @type {import('sequelize-cli').Migration} */ +module.exports = { + async up (queryInterface, Sequelize) { + await queryInterface.bulkInsert('Config', [{ + id: 1, + startingDateRaid: 1717020000, + }], {}) + }, + + async down (queryInterface, Sequelize) { + await queryInterface.bulkDelete('Config', null, {}) + } +}; diff --git a/package-lock.json b/package-lock.json index 79fef63..8898bf3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -310,30 +310,10 @@ "@types/ms": "*" } }, - "node_modules/@types/eslint": { - "version": "8.56.10", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", - "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", - "dev": true, - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/eslint-scope": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", - "dev": true, - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "dev": true }, "node_modules/@types/json-schema": { @@ -1402,9 +1382,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz", - "integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==", + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", "dev": true, "dependencies": { "graceful-fs": "^4.2.4", @@ -1759,9 +1739,9 @@ } }, "node_modules/find-my-way": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/find-my-way/-/find-my-way-8.2.0.tgz", - "integrity": "sha512-HdWXgFYc6b1BJcOBDBwjqWuHJj1WYiqrxSh25qtU4DabpMFdj/gSunNBQb83t+8Zt67D7CXEzJWTkxaShMTMOA==", + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/find-my-way/-/find-my-way-8.2.2.tgz", + "integrity": "sha512-Dobi7gcTEq8yszimcfp/R7+owiT4WncAJ7VTTgFH1jYJ5GaG1FbhjwDG820hptN0QDFvzVY3RfCzdInvGPGzjA==", "dependencies": { "fast-deep-equal": "^3.1.3", "fast-querystring": "^1.0.0", @@ -4429,12 +4409,11 @@ } }, "node_modules/webpack": { - "version": "5.93.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.93.0.tgz", - "integrity": "sha512-Y0m5oEY1LRuwly578VqluorkXbvXKh7U3rLoQCEO04M97ScRr44afGVkI0FQFsXzysk5OgFAxjZAb9rsGQVihA==", + "version": "5.95.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.95.0.tgz", + "integrity": "sha512-2t3XstrKULz41MNMBF+cJ97TyHdyQ8HCt//pqErqDvNjU9YQBnZxIHa11VXsi7F3mb5/aO2tuDxdeTPdU7xu9Q==", "dev": true, "dependencies": { - "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.5", "@webassemblyjs/ast": "^1.12.1", "@webassemblyjs/wasm-edit": "^1.12.1", @@ -4443,7 +4422,7 @@ "acorn-import-attributes": "^1.9.5", "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.0", + "enhanced-resolve": "^5.17.1", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", diff --git a/routes/suivi.routes.js b/routes/suivi.routes.js index b6046e9..e5bab07 100644 --- a/routes/suivi.routes.js +++ b/routes/suivi.routes.js @@ -1,5 +1,6 @@ import suiviController from '../controllers/suivi.controller.js'; import securityService from '../services/security.service.js'; +import configController from '../controllers/config.controller.js'; const suiviRoutes = async (app) => { app.route({ @@ -47,6 +48,20 @@ const suiviRoutes = async (app) => { url: '/bisList', handler: suiviController.getBisList }); + + app.route({ + method: 'GET', + url: '/config', + preHandler: securityService.checkJWT, + handler: configController.getConfig + }); + + app.route({ + method: 'POST', + url: '/config', + preHandler: securityService.checkJWT, + handler: configController.updateConfig + }) }; export default suiviRoutes; diff --git a/services/config.service.js b/services/config.service.js new file mode 100644 index 0000000..8e53c33 --- /dev/null +++ b/services/config.service.js @@ -0,0 +1,18 @@ +import Config from '../dao/config.dao.js' + +async function getConfig() { + return Config.find() +} + +async function updateConfig(options) { + const config = new Config({ + id: options.id, + startingDateRaid: options.startingDateRaid + }) + await config.update() +} + +export default { + getConfig, + updateConfig +} \ No newline at end of file diff --git a/services/suivi.service.js b/services/suivi.service.js index 44ed900..b731afd 100644 --- a/services/suivi.service.js +++ b/services/suivi.service.js @@ -49,8 +49,8 @@ async function removeHistory(id) { return history } -async function getBisList() { - return Roster.getBisData() +async function getBisList(raidDate) { + return Roster.getBisData(raidDate) } export default {