diff --git a/.env b/.env
index 8666014..4cc1526 100644
--- a/.env
+++ b/.env
@@ -1 +1 @@
-teamname="wiq_es04c"
\ No newline at end of file
+teamname="wiq_es04c"
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index b281041..47b4f44 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -3,6 +3,7 @@ on:
push:
branches:
- master
+ - releases
pull_request:
types: [opened, synchronize, reopened]
jobs:
@@ -18,8 +19,8 @@ jobs:
- run: npm --prefix users/authservice ci
- run: npm --prefix users/userservice ci
- run: npm --prefix gatewayservice ci
- - run: npm --prefix questionsservice ci # Agrega la tarea para questionsservice
- run: npm --prefix webapp ci
+ - run: npm --prefix questionservice ci
- run: npm --prefix users/authservice test -- --coverage
- run: npm --prefix users/userservice test -- --coverage
- run: npm --prefix gatewayservice test -- --coverage
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 9ddf038..515c6da 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -1,10 +1,8 @@
name: Deploy on release
on:
- push:
- branches:
- -master
- -releases
+ release:
+ types: [published]
jobs:
unit-tests:
@@ -53,9 +51,7 @@ jobs:
- name: Publish to Registry
uses: elgohr/Publish-Docker-Github-Action@v5
env:
- API_URI: http://${{ secrets.DEPLOY_HOST || 'localhost' }}:8000
-
-
+ API_URI: http://${{ secrets.DEPLOY_HOST }}:8000
with:
name: arquisoft/wiq_es04c/webapp
username: ${{ github.actor }}
@@ -63,6 +59,26 @@ jobs:
registry: ghcr.io
workdir: webapp
buildargs: API_URI
+ docker-push-questionservice:
+ name: Push question service Docker Image to GitHub Packages
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ packages: write
+ needs: [e2e-tests]
+ steps:
+ - uses: actions/checkout@v4
+ - name: Publish to Registry
+ uses: elgohr/Publish-Docker-Github-Action@v5
+ with:
+ name: arquisoft/wiq_es04c/questionservice
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+ registry: ghcr.io
+ workdir: ./questionservice
+
+
+
docker-push-authservice:
name: Push auth service Docker Image to GitHub Packages
runs-on: ubuntu-latest
@@ -113,29 +129,11 @@ jobs:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
registry: ghcr.io
- workdir: ./gatewayservice
- docker-push-questionservice:
- name: Push question service Docker Image to GitHub Packages
- runs-on: ubuntu-latest
- permissions:
- contents: read
- packages: write
- needs: [e2e-tests]
- steps:
- - uses: actions/checkout@v4
- - name: Publish to Registry
- uses: elgohr/Publish-Docker-Github-Action@v5
- with:
- name: arquisoft/wiq_es04c/questionservice
- username: ${{ github.actor }}
- password: ${{ secrets.GITHUB_TOKEN }}
- registry: ghcr.io
- workdir: ./questionservice
-
+ workdir: gatewayservice
deploy:
name: Deploy over SSH
runs-on: ubuntu-latest
- needs: [docker-push-userservice,docker-push-authservice,docker-push-gatewayservice,docker-push-webapp,docker-push-questionservice]
+ needs: [docker-push-userservice,docker-push-authservice,docker-push-gatewayservice,docker-push-webapp]
steps:
- name: Deploy over SSH
uses: fifsky/ssh-action@master
@@ -144,8 +142,7 @@ jobs:
user: ${{ secrets.DEPLOY_USER }}
key: ${{ secrets.DEPLOY_KEY }}
command: |
- wget https://raw.githubusercontent.com/arquisoft/wiq_es04c/releases/docker-compose.yml -O docker-compose.yml
- wget https://raw.githubusercontent.com/arquisoft/wiq_es04c/releases/.env -O .env
- git clone -b releases https://github.com/Arquisoft/wiq_es04c.git
+ wget https://raw.githubusercontent.com/arquisoft/wiq_es04c/master/docker-compose.yml -O docker-compose.yml
+ wget https://raw.githubusercontent.com/arquisoft/wiq_es04c/master/.env -O .env
docker compose --profile prod down
- docker compose --profile prod up -d
+ docker compose --profile prod up -d
\ No newline at end of file
diff --git a/api_interfaces/api_questionservice.txt b/api_interfaces/api_questionservice.txt
index ad891f2..4809401 100644
--- a/api_interfaces/api_questionservice.txt
+++ b/api_interfaces/api_questionservice.txt
@@ -5,9 +5,10 @@ devuelve json -> {question: string, answers: answer[]}
answer: {answer: string, correct: boolean}
EJEMPLO
-const example_data = {question: 'pregunta ejemplo', answers: [
+const example_data = {question: 'pregunta ejemplo', respuesta: [
{answer: 'respuesta correcta', correct: true},
{answer: 'respuesta incorrecta1', correct: false},
{answer: 'respuesta incorrecta2', correct: false},
- {answer: 'respuesta incorrecta3', correct: false}
-]};
\ No newline at end of file
+ {answer: 'respuesta incorrecta3', correct: false}],
+ questionCategory: 'geografia'
+ };
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
index 8ea4e22..bad1840 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,7 +1,7 @@
version: '3'
services:
mongodb:
- container_name: mongodb-${teamname:-defaultASW}
+ container_name: mongodb-${teamname:-wiq_es04c}
image: mongo
profiles: ["dev", "prod"]
volumes:
@@ -10,10 +10,34 @@ services:
- "27017:27017"
networks:
- mynetwork
+ # Servicio de MySQL no se mete en el release te bajas la ultima imagen
+ questionservice-mysql:
+ image: mysql:latest
+ container_name: questionservice-mysql-${teamname:-wiq_es04c}
+ environment:
+ MYSQL_USER: bidof
+ MYSQL_PASSWORD: admin
+ MYSQL_ROOT_PASSWORD: admin
+ MYSQL_DATABASE: questions_db
+ MYSQL_CHARSET: utf8mb4
+ MYSQL_COLLATION: utf8mb4_unicode_ci
+ DB_PORT: 3306
+
+ ports:
+ - "3306:3306"
+ volumes:
+ - mysql-data:/var/lib/mysql
+ #montar en el directorio de mysql el archivo schema que esta en questionservice/database para que lo tenga el contendor y lo pueda ejecutar
+ #create_db es true
+ - ./questionservice/database/:/docker-entrypoint-initdb.d
+ networks:
+ - mynetwork
+ expose:
+ - "3306"
authservice:
- container_name: authservice-${teamname:-defaultASW}
- image: ghcr.io/arquisoft/wiq_0/authservice:latest
+ container_name: authservice-${teamname:-wiq_es04c}
+ image: ghcr.io/arquisoft/${teamname:-wiq_es04c}/authservice:latest
profiles: ["dev", "prod"]
build: ./users/authservice
depends_on:
@@ -26,8 +50,8 @@ services:
MONGODB_URI: mongodb://mongodb:27017/userdb
userservice:
- container_name: userservice-${teamname:-defaultASW}
- image: ghcr.io/arquisoft/wiq_0/userservice:latest
+ container_name: userservice-${teamname:-wiq_es04c}
+ image: ghcr.io/arquisoft/${teamname:-wiq_es04c}/userservice:latest
profiles: ["dev", "prod"]
build: ./users/userservice
depends_on:
@@ -40,8 +64,8 @@ services:
MONGODB_URI: mongodb://mongodb:27017/userdb
gatewayservice:
- container_name: gatewayservice-${teamname:-defaultASW}
- image: ghcr.io/arquisoft/wiq_0/gatewayservice:latest
+ container_name: gatewayservice-${teamname:-wiq_es04c}
+ image: ghcr.io/arquisoft/${teamname:-wiq_es04c}/gatewayservice:latest
profiles: ["dev", "prod"]
build: ./gatewayservice
depends_on:
@@ -59,26 +83,33 @@ services:
questionservice:
- container_name: questionservice-${teamname:-defaultASW}
- build: ./questionservice
+ container_name: questionservice-${teamname:-wiq_es04c}
+ build: questionservice
+ depends_on:
+ - questionservice-mysql
ports:
- "8003:8003"
networks:
- mynetwork
+ environment:
+ DB_HOST: questionservice-mysql
+
webapp:
- container_name: webapp-${teamname:-defaultASW}
- image: ghcr.io/arquisoft/wiq_0/webapp:latest
+ container_name: webapp-${teamname:-wiq_es04c}
+ image: ghcr.io/arquisoft/${teamname:-wiq_es04c}/webapp:latest
profiles: ["dev", "prod"]
build: ./webapp
depends_on:
- gatewayservice
ports:
- "3000:3000"
+ environment:
+ - API_URI=${API_URI}
prometheus:
image: prom/prometheus
- container_name: prometheus-${teamname:-defaultASW}
+ container_name: prometheus-${teamname:-wiq_es04c}
profiles: ["dev"]
networks:
- mynetwork
@@ -92,7 +123,7 @@ services:
grafana:
image: grafana/grafana
- container_name: grafana-${teamname:-defaultASW}
+ container_name: grafana-${teamname:-wiq_es04c}
profiles: ["dev"]
networks:
- mynetwork
@@ -114,6 +145,8 @@ volumes:
mongodb_data:
prometheus_data:
grafana_data:
+ mysql-data:
+
networks:
mynetwork:
diff --git a/gatewayservice/gateway-service.js b/gatewayservice/gateway-service.js
index e781a2a..a85c43d 100644
--- a/gatewayservice/gateway-service.js
+++ b/gatewayservice/gateway-service.js
@@ -2,7 +2,6 @@ const express = require('express');
const axios = require('axios');
const cors = require('cors');
const promBundle = require('express-prom-bundle');
-
const app = express();
const port = 8000;
@@ -51,11 +50,22 @@ app.get('/getquestion', async(req,res)=> {
res.json(response.data);
} catch(error) {
- res.status(error.response.status).json({ error: error.response.data.error });
+ if (error.response) {
+ res.status(error.response.status).json({ error: error.response.data.error });
+ } else {
+ res.status(500).json({ error: 'An unexpected error occurred' });
+ }
}
});
-
+app.get('/generateQuestions', async(req,res)=> {
+ try{
+
+ } catch(error) {
+ res.status(error.response.status).json({ error: error.response.data.error });
+ }
+
+});
// Start the gateway service
const server = app.listen(port, () => {
console.log(`Gateway Service listening at http://localhost:${port}`);
diff --git a/gatewayservice/package.json b/gatewayservice/package.json
index fd16c42..03b5cc2 100644
--- a/gatewayservice/package.json
+++ b/gatewayservice/package.json
@@ -9,14 +9,14 @@
},
"repository": {
"type": "git",
- "url": "git+https://github.com/arquisoft/wiq_0.git"
+ "url": "git+https://github.com/arquisoft/wiq_es04c.git"
},
"author": "",
"license": "ISC",
"bugs": {
- "url": "https://github.com/arquisoft/wiq_0/issues"
+ "url": "https://github.com/arquisoft/wiq_es04c/issues"
},
- "homepage": "https://github.com/arquisoft/wiq_0#readme",
+ "homepage": "https://github.com/arquisoft/wiq_es04c#readme",
"dependencies": {
"axios": "^1.6.5",
"cors": "^2.8.5",
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..2668a58
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,585 @@
+{
+ "name": "wiq_es04c",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "dependencies": {
+ "bootstrap": "^5.3.3",
+ "cron": "^3.1.6",
+ "dotenv": "^16.4.5",
+ "mysql": "^2.18.1",
+ "mysql2": "^3.9.2",
+ "node-cron": "^3.0.3",
+ "react-bootstrap": "^2.10.1"
+ }
+ },
+ "node_modules/@babel/runtime": {
+ "version": "7.23.9",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.9.tgz",
+ "integrity": "sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==",
+ "dependencies": {
+ "regenerator-runtime": "^0.14.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@popperjs/core": {
+ "version": "2.11.8",
+ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
+ "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/popperjs"
+ }
+ },
+ "node_modules/@react-aria/ssr": {
+ "version": "3.9.2",
+ "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.2.tgz",
+ "integrity": "sha512-0gKkgDYdnq1w+ey8KzG9l+H5Z821qh9vVjztk55rUg71vTk/Eaebeir+WtzcLLwTjw3m/asIjx8Y59y1lJZhBw==",
+ "dependencies": {
+ "@swc/helpers": "^0.5.0"
+ },
+ "engines": {
+ "node": ">= 12"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ }
+ },
+ "node_modules/@restart/hooks": {
+ "version": "0.4.16",
+ "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.16.tgz",
+ "integrity": "sha512-f7aCv7c+nU/3mF7NWLtVVr0Ra80RqsO89hO72r+Y/nvQr5+q0UFGkocElTH6MJApvReVh6JHUFYn2cw1WdHF3w==",
+ "dependencies": {
+ "dequal": "^2.0.3"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0"
+ }
+ },
+ "node_modules/@restart/ui": {
+ "version": "1.6.6",
+ "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.6.6.tgz",
+ "integrity": "sha512-eC3puKuWE1SRYbojWHXnvCNHGgf3uzHCb6JOhnF4OXPibOIPEkR1sqDSkL643ydigxwh+ruCa1CmYHlzk7ikKA==",
+ "dependencies": {
+ "@babel/runtime": "^7.21.0",
+ "@popperjs/core": "^2.11.6",
+ "@react-aria/ssr": "^3.5.0",
+ "@restart/hooks": "^0.4.9",
+ "@types/warning": "^3.0.0",
+ "dequal": "^2.0.3",
+ "dom-helpers": "^5.2.0",
+ "uncontrollable": "^8.0.1",
+ "warning": "^4.0.3"
+ },
+ "peerDependencies": {
+ "react": ">=16.14.0",
+ "react-dom": ">=16.14.0"
+ }
+ },
+ "node_modules/@restart/ui/node_modules/uncontrollable": {
+ "version": "8.0.4",
+ "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-8.0.4.tgz",
+ "integrity": "sha512-ulRWYWHvscPFc0QQXvyJjY6LIXU56f0h8pQFvhxiKk5V1fcI8gp9Ht9leVAhrVjzqMw0BgjspBINx9r6oyJUvQ==",
+ "peerDependencies": {
+ "react": ">=16.14.0"
+ }
+ },
+ "node_modules/@swc/helpers": {
+ "version": "0.5.6",
+ "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.6.tgz",
+ "integrity": "sha512-aYX01Ke9hunpoCexYAgQucEpARGQ5w/cqHFrIR+e9gdKb1QWTsVJuTJ2ozQzIAxLyRQe/m+2RqzkyOOGiMKRQA==",
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@types/luxon": {
+ "version": "3.3.8",
+ "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.3.8.tgz",
+ "integrity": "sha512-jYvz8UMLDgy3a5SkGJne8H7VA7zPV2Lwohjx0V8V31+SqAjNmurWMkk9cQhfvlcnXWudBpK9xPM1n4rljOcHYQ=="
+ },
+ "node_modules/@types/prop-types": {
+ "version": "15.7.11",
+ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz",
+ "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng=="
+ },
+ "node_modules/@types/react": {
+ "version": "18.2.59",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.59.tgz",
+ "integrity": "sha512-DE+F6BYEC8VtajY85Qr7mmhTd/79rJKIHCg99MU9SWPB4xvLb6D1za2vYflgZfmPqQVEr6UqJTnLXEwzpVPuOg==",
+ "dependencies": {
+ "@types/prop-types": "*",
+ "@types/scheduler": "*",
+ "csstype": "^3.0.2"
+ }
+ },
+ "node_modules/@types/react-transition-group": {
+ "version": "4.4.10",
+ "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz",
+ "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==",
+ "dependencies": {
+ "@types/react": "*"
+ }
+ },
+ "node_modules/@types/scheduler": {
+ "version": "0.16.8",
+ "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz",
+ "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A=="
+ },
+ "node_modules/@types/warning": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.3.tgz",
+ "integrity": "sha512-D1XC7WK8K+zZEveUPY+cf4+kgauk8N4eHr/XIHXGlGYkHLud6hK9lYfZk1ry1TNh798cZUCgb6MqGEG8DkJt6Q=="
+ },
+ "node_modules/bignumber.js": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz",
+ "integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/bootstrap": {
+ "version": "5.3.3",
+ "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.3.tgz",
+ "integrity": "sha512-8HLCdWgyoMguSO9o+aH+iuZ+aht+mzW0u3HIMzVu7Srrpv7EBBxTnrFlSCskwdY1+EOFQSm7uMJhNQHkdPcmjg==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/twbs"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/bootstrap"
+ }
+ ],
+ "peerDependencies": {
+ "@popperjs/core": "^2.11.8"
+ }
+ },
+ "node_modules/classnames": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz",
+ "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow=="
+ },
+ "node_modules/core-util-is": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
+ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
+ },
+ "node_modules/cron": {
+ "version": "3.1.6",
+ "resolved": "https://registry.npmjs.org/cron/-/cron-3.1.6.tgz",
+ "integrity": "sha512-cvFiQCeVzsA+QPM6fhjBtlKGij7tLLISnTSvFxVdnFGLdz+ZdXN37kNe0i2gefmdD17XuZA6n2uPVwzl4FxW/w==",
+ "dependencies": {
+ "@types/luxon": "~3.3.0",
+ "luxon": "~3.4.0"
+ }
+ },
+ "node_modules/csstype": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
+ },
+ "node_modules/denque": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz",
+ "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==",
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/dequal": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
+ "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/dom-helpers": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz",
+ "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==",
+ "dependencies": {
+ "@babel/runtime": "^7.8.7",
+ "csstype": "^3.0.2"
+ }
+ },
+ "node_modules/dotenv": {
+ "version": "16.4.5",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz",
+ "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://dotenvx.com"
+ }
+ },
+ "node_modules/generate-function": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz",
+ "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==",
+ "dependencies": {
+ "is-property": "^1.0.2"
+ }
+ },
+ "node_modules/iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+ },
+ "node_modules/invariant": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
+ "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
+ "dependencies": {
+ "loose-envify": "^1.0.0"
+ }
+ },
+ "node_modules/is-property": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
+ "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g=="
+ },
+ "node_modules/isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
+ },
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
+ },
+ "node_modules/long": {
+ "version": "5.2.3",
+ "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz",
+ "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q=="
+ },
+ "node_modules/loose-envify": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+ "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+ "dependencies": {
+ "js-tokens": "^3.0.0 || ^4.0.0"
+ },
+ "bin": {
+ "loose-envify": "cli.js"
+ }
+ },
+ "node_modules/lru-cache": {
+ "version": "8.0.5",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz",
+ "integrity": "sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==",
+ "engines": {
+ "node": ">=16.14"
+ }
+ },
+ "node_modules/luxon": {
+ "version": "3.4.4",
+ "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.4.4.tgz",
+ "integrity": "sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA==",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/mysql": {
+ "version": "2.18.1",
+ "resolved": "https://registry.npmjs.org/mysql/-/mysql-2.18.1.tgz",
+ "integrity": "sha512-Bca+gk2YWmqp2Uf6k5NFEurwY/0td0cpebAucFpY/3jhrwrVGuxU2uQFCHjU19SJfje0yQvi+rVWdq78hR5lig==",
+ "dependencies": {
+ "bignumber.js": "9.0.0",
+ "readable-stream": "2.3.7",
+ "safe-buffer": "5.1.2",
+ "sqlstring": "2.3.1"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mysql2": {
+ "version": "3.9.2",
+ "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.9.2.tgz",
+ "integrity": "sha512-3Cwg/UuRkAv/wm6RhtPE5L7JlPB877vwSF6gfLAS68H+zhH+u5oa3AieqEd0D0/kC3W7qIhYbH419f7O9i/5nw==",
+ "dependencies": {
+ "denque": "^2.1.0",
+ "generate-function": "^2.3.1",
+ "iconv-lite": "^0.6.3",
+ "long": "^5.2.1",
+ "lru-cache": "^8.0.0",
+ "named-placeholders": "^1.1.3",
+ "seq-queue": "^0.0.5",
+ "sqlstring": "^2.3.2"
+ },
+ "engines": {
+ "node": ">= 8.0"
+ }
+ },
+ "node_modules/mysql2/node_modules/sqlstring": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz",
+ "integrity": "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/named-placeholders": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.3.tgz",
+ "integrity": "sha512-eLoBxg6wE/rZkJPhU/xRX1WTpkFEwDJEN96oxFrTsqBdbT5ec295Q+CoHrL9IT0DipqKhmGcaZmwOt8OON5x1w==",
+ "dependencies": {
+ "lru-cache": "^7.14.1"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/named-placeholders/node_modules/lru-cache": {
+ "version": "7.18.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
+ "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/node-cron": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/node-cron/-/node-cron-3.0.3.tgz",
+ "integrity": "sha512-dOal67//nohNgYWb+nWmg5dkFdIwDm8EpeGYMekPMrngV3637lqnX0lbUcCtgibHTz6SEz7DAIjKvKDFYCnO1A==",
+ "dependencies": {
+ "uuid": "8.3.2"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/process-nextick-args": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
+ },
+ "node_modules/prop-types": {
+ "version": "15.8.1",
+ "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
+ "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
+ "dependencies": {
+ "loose-envify": "^1.4.0",
+ "object-assign": "^4.1.1",
+ "react-is": "^16.13.1"
+ }
+ },
+ "node_modules/prop-types-extra": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz",
+ "integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==",
+ "dependencies": {
+ "react-is": "^16.3.2",
+ "warning": "^4.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=0.14.0"
+ }
+ },
+ "node_modules/react": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
+ "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
+ "peer": true,
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-bootstrap": {
+ "version": "2.10.1",
+ "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.10.1.tgz",
+ "integrity": "sha512-J3OpRZIvCTQK+Tg/jOkRUvpYLHMdGeU9KqFUBQrV0d/Qr/3nsINpiOJyZMWnM5SJ3ctZdhPA6eCIKpEJR3Ellg==",
+ "dependencies": {
+ "@babel/runtime": "^7.22.5",
+ "@restart/hooks": "^0.4.9",
+ "@restart/ui": "^1.6.6",
+ "@types/react-transition-group": "^4.4.6",
+ "classnames": "^2.3.2",
+ "dom-helpers": "^5.2.1",
+ "invariant": "^2.2.4",
+ "prop-types": "^15.8.1",
+ "prop-types-extra": "^1.1.0",
+ "react-transition-group": "^4.4.5",
+ "uncontrollable": "^7.2.1",
+ "warning": "^4.0.3"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.8",
+ "react": ">=16.14.0",
+ "react-dom": ">=16.14.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/react-dom": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
+ "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==",
+ "peer": true,
+ "dependencies": {
+ "loose-envify": "^1.1.0",
+ "scheduler": "^0.23.0"
+ },
+ "peerDependencies": {
+ "react": "^18.2.0"
+ }
+ },
+ "node_modules/react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
+ },
+ "node_modules/react-lifecycles-compat": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
+ "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
+ },
+ "node_modules/react-transition-group": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
+ "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==",
+ "dependencies": {
+ "@babel/runtime": "^7.5.5",
+ "dom-helpers": "^5.0.1",
+ "loose-envify": "^1.4.0",
+ "prop-types": "^15.6.2"
+ },
+ "peerDependencies": {
+ "react": ">=16.6.0",
+ "react-dom": ">=16.6.0"
+ }
+ },
+ "node_modules/readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "node_modules/regenerator-runtime": {
+ "version": "0.14.1",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
+ "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+ },
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+ },
+ "node_modules/scheduler": {
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
+ "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
+ "peer": true,
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ }
+ },
+ "node_modules/seq-queue": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz",
+ "integrity": "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q=="
+ },
+ "node_modules/sqlstring": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz",
+ "integrity": "sha512-ooAzh/7dxIG5+uDik1z/Rd1vli0+38izZhGzSa34FwR7IbelPWCCKSNIl8jlL/F7ERvy8CB2jNeM1E9i9mXMAQ==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dependencies": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "node_modules/tslib": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
+ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
+ },
+ "node_modules/uncontrollable": {
+ "version": "7.2.1",
+ "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.2.1.tgz",
+ "integrity": "sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ==",
+ "dependencies": {
+ "@babel/runtime": "^7.6.3",
+ "@types/react": ">=16.9.11",
+ "invariant": "^2.2.4",
+ "react-lifecycles-compat": "^3.0.4"
+ },
+ "peerDependencies": {
+ "react": ">=15.0.0"
+ }
+ },
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
+ },
+ "node_modules/uuid": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
+ "node_modules/warning": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
+ "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
+ "dependencies": {
+ "loose-envify": "^1.0.0"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..c633e34
--- /dev/null
+++ b/package.json
@@ -0,0 +1,11 @@
+{
+ "dependencies": {
+ "bootstrap": "^5.3.3",
+ "cron": "^3.1.6",
+ "dotenv": "^16.4.5",
+ "mysql": "^2.18.1",
+ "mysql2": "^3.9.2",
+ "node-cron": "^3.0.3",
+ "react-bootstrap": "^2.10.1"
+ }
+}
diff --git a/questionservice/.env b/questionservice/.env
new file mode 100644
index 0000000..e69de29
diff --git a/questionservice/DataBaseManager.js b/questionservice/DataBaseManager.js
new file mode 100644
index 0000000..12e5b55
--- /dev/null
+++ b/questionservice/DataBaseManager.js
@@ -0,0 +1,163 @@
+const mysql = require('mysql2/promise');
+const express = require('express');
+const bodyParser = require('body-parser');
+const app = express();
+const port = 3306;
+
+
+// Middleware to parse JSON in request body
+app.use(bodyParser.json());
+
+
+const dbConfig = {
+ host: process.env.DB_HOST || 'questionservice-mysql-wiq_es04c',
+ user: process.env.DB_USER || 'root',
+ password: process.env.DB_PASSWORD || 'admin',
+ database: process.env.DB_NAME || 'questions_db',
+ port: process.env.DB_PORT || 3306,
+ charset : 'utf8mb4'
+};
+
+//clae encargada de agregar datos a la bd
+class DatabaseManager {
+ config = dbConfig
+ constructor() {
+ this.connection = null;
+
+ }
+
+
+
+
+async connect() {
+ try {
+ console.log(this.config)
+ this.connection = await mysql.createConnection(this.config);
+ console.log('Connected to the database');
+ } catch (error) {
+ console.error('Error connecting to the database:', error.message);
+ }
+ }
+ async disconnect() {
+ try {
+ await this.connection.end();
+ console.log('Disconnected from the database');
+ } catch (error) {
+ console.error('Error disconnecting from the database:', error.message);
+ }
+ }
+ async ensureCategoryExists(categoryName) {
+ // Comprobar si la categoría ya existe
+ const [rows] = await this.connection.execute(
+ 'SELECT id_categoria FROM Categoria WHERE nombre_categoria = ?',
+ [categoryName]
+ );
+
+ if (rows.length > 0) {
+ // Si la categoría ya existe, devolver su ID
+ return rows[0].id_categoria;
+ } else {
+ // Si la categoría no existe, crearla y devolver su ID
+ const [result] = await this.connection.execute(
+ 'INSERT INTO Categoria (nombre_categoria) VALUES (?)',
+ [categoryName]
+ );
+
+ return result.insertId;
+ }
+ }
+
+ async addQuestion(question) {
+ try {
+ await this.connect();
+
+ const { question: questionText, answers, questionCategory, questionType } = question;
+
+ // Comenzamos la transacción para que si da errores se vuelva atrás
+ await this.connection.beginTransaction();
+
+ //PRIMERO COMPRUEBAS SI ESTAS CREANDO UNA CATEGORIA O SI YA EXISTE
+ const categoryId = await this.ensureCategoryExists(questionCategory);
+
+ // Insertar la pregunta
+ const correctAnswer = answers.find(answer => answer.correct).answer;
+ const [questionResult] = await this.connection.execute(
+ 'INSERT INTO Pregunta (pregunta, respuesta_correcta, id_categoria) VALUES (?, ?, ?)',
+ [questionText, correctAnswer, categoryId]
+ );
+
+ // Insertar los distractores
+ for (const answer of answers) {
+ if (!answer.correct) {
+ const [distractorResult] = await this.connection.execute(
+ 'INSERT INTO Distractor (distractor,id_categoria,id_pregunta) VALUES (?,?,?)',
+ [answer.answer, categoryId,questionResult.insertId]
+ );
+
+
+ }
+ }
+
+ // Si todo ha ido bien, confirmar la transacción
+ await this.connection.commit();
+
+ } catch (error) {
+ // Si algo ha ido mal, revertir la transacción
+ await this.connection.rollback();
+
+ console.error('Error adding question:', error.message);
+ throw error;
+ } finally {
+ // Desconectar de la base de datos
+ await this.disconnect();
+ }
+ }
+ async getGameQuestions() {
+ try {
+ await this.connect();
+
+ // Obtén una pregunta aleatoria
+ const [question] = await this.connection.execute(
+ 'SELECT * FROM Pregunta ORDER BY RAND() LIMIT 1'
+ );
+
+ const questionId = question[0].id_pregunta;
+
+ // Obtén la respuesta correcta para esa pregunta
+ const correctAnswer = question[0].respuesta_correcta;
+
+ // Obtén los distractores para esa pregunta
+ const [distractors] = await this.connection.execute(
+ 'SELECT distractor FROM Distractor WHERE id_pregunta = ?',
+ [questionId]
+ );
+ const respuestaArray = [
+ { answer: correctAnswer, correct: true },
+ ...distractors.map(distractor => ({ answer: distractor.distractor, correct: false }))
+ ];
+ // Obtén la categoría de la pregunta
+ const [category] = await this.connection.execute(
+ 'SELECT nombre_categoria FROM Categoria WHERE id_categoria = ?',
+ [question[0].id_categoria]
+ );
+
+ return {
+ question: question[0].pregunta,
+ answers:respuestaArray,
+ questionCategory: category[0].nombre_categoria
+ };
+
+ } catch (error) {
+ console.error('Error getting game questions:', error.message);
+ throw error;
+ } finally {
+ // Desconectar de la base de datos
+ await this.disconnect();
+ }
+ }
+
+}
+
+
+module.exports = DatabaseManager;
+
diff --git a/questionservice/database/schema.sql b/questionservice/database/schema.sql
new file mode 100644
index 0000000..3f279ba
--- /dev/null
+++ b/questionservice/database/schema.sql
@@ -0,0 +1,32 @@
+-- schema.sql
+DROP TABLE IF EXISTS Distractor;
+DROP TABLE IF EXISTS Pregunta;
+DROP TABLE IF EXISTS Categoria;
+CREATE TABLE Categoria (
+ id_categoria int PRIMARY KEY ,
+ nombre_categoria VARCHAR(255) UNIQUE NOT NULL
+);
+ALTER TABLE Categoria MODIFY id_categoria int AUTO_INCREMENT;
+
+CREATE TABLE Pregunta (
+ id_pregunta INT PRIMARY KEY,
+ pregunta VARCHAR(255) UNIQUE NOT NULL ,
+ respuesta_correcta TEXT NOT NULL,
+ id_categoria INT,
+ FOREIGN KEY (id_categoria) REFERENCES Categoria(id_categoria)
+);
+ALTER TABLE Pregunta MODIFY id_pregunta int AUTO_INCREMENT;
+
+CREATE TABLE Distractor (
+ id_distractor INT PRIMARY KEY,
+ distractor VARCHAR(255) NOT NULL,
+ id_categoria INT,
+ id_pregunta INT NOT NULL,
+ FOREIGN KEY (id_categoria) REFERENCES Categoria(id_categoria),
+ FOREIGN KEY (id_pregunta) REFERENCES Pregunta(id_pregunta)
+);
+ALTER TABLE Distractor MODIFY id_distractor int AUTO_INCREMENT;
+ALTER TABLE Categoria CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
+ALTER TABLE Pregunta CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
+ALTER TABLE Distractor CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
+
diff --git a/questionservice/package-lock.json b/questionservice/package-lock.json
index ccd0f3d..4e019e9 100644
--- a/questionservice/package-lock.json
+++ b/questionservice/package-lock.json
@@ -11,9 +11,11 @@
"dependencies": {
"bcrypt": "^5.1.1",
"body-parser": "^1.20.2",
+ "dotenv": "^16.4.5",
"express": "^4.18.2",
"jsonwebtoken": "^9.0.2",
- "mongoose": "^8.0.4"
+ "mongoose": "^8.0.4",
+ "mysql2": "^3.9.2"
},
"devDependencies": {
"jest": "^29.7.0",
@@ -22,13 +24,13 @@
}
},
"node_modules/@ampproject/remapping": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz",
- "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==",
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
+ "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
"dev": true,
"dependencies": {
- "@jridgewell/gen-mapping": "^0.3.0",
- "@jridgewell/trace-mapping": "^0.3.9"
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
},
"engines": {
"node": ">=6.0.0"
@@ -128,9 +130,9 @@
}
},
"node_modules/@babel/core": {
- "version": "7.23.9",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.9.tgz",
- "integrity": "sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==",
+ "version": "7.24.0",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.0.tgz",
+ "integrity": "sha512-fQfkg0Gjkza3nf0c7/w6Xf34BW4YvzNfACRLmmb7XRLa6XHdR+K9AlJlxneFfWYf6uhOzuzZVTjF/8KfndZANw==",
"dev": true,
"dependencies": {
"@ampproject/remapping": "^2.2.0",
@@ -138,11 +140,11 @@
"@babel/generator": "^7.23.6",
"@babel/helper-compilation-targets": "^7.23.6",
"@babel/helper-module-transforms": "^7.23.3",
- "@babel/helpers": "^7.23.9",
- "@babel/parser": "^7.23.9",
- "@babel/template": "^7.23.9",
- "@babel/traverse": "^7.23.9",
- "@babel/types": "^7.23.9",
+ "@babel/helpers": "^7.24.0",
+ "@babel/parser": "^7.24.0",
+ "@babel/template": "^7.24.0",
+ "@babel/traverse": "^7.24.0",
+ "@babel/types": "^7.24.0",
"convert-source-map": "^2.0.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
@@ -295,9 +297,9 @@
}
},
"node_modules/@babel/helper-plugin-utils": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
- "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==",
+ "version": "7.24.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz",
+ "integrity": "sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==",
"dev": true,
"engines": {
"node": ">=6.9.0"
@@ -355,14 +357,14 @@
}
},
"node_modules/@babel/helpers": {
- "version": "7.23.9",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.9.tgz",
- "integrity": "sha512-87ICKgU5t5SzOT7sBMfCOZQ2rHjRU+Pcb9BoILMYz600W6DkVRLFBPwQ18gwUVvggqXivaUakpnxWQGbpywbBQ==",
+ "version": "7.24.0",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.0.tgz",
+ "integrity": "sha512-ulDZdc0Aj5uLc5nETsa7EPx2L7rM0YJM8r7ck7U73AXi7qOV44IHHRAYZHY6iU1rr3C5N4NtTmMRUJP6kwCWeA==",
"dev": true,
"dependencies": {
- "@babel/template": "^7.23.9",
- "@babel/traverse": "^7.23.9",
- "@babel/types": "^7.23.9"
+ "@babel/template": "^7.24.0",
+ "@babel/traverse": "^7.24.0",
+ "@babel/types": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
@@ -454,9 +456,9 @@
}
},
"node_modules/@babel/parser": {
- "version": "7.23.9",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz",
- "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==",
+ "version": "7.24.0",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.0.tgz",
+ "integrity": "sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==",
"dev": true,
"bin": {
"parser": "bin/babel-parser.js"
@@ -643,23 +645,23 @@
}
},
"node_modules/@babel/template": {
- "version": "7.23.9",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.23.9.tgz",
- "integrity": "sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA==",
+ "version": "7.24.0",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz",
+ "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==",
"dev": true,
"dependencies": {
"@babel/code-frame": "^7.23.5",
- "@babel/parser": "^7.23.9",
- "@babel/types": "^7.23.9"
+ "@babel/parser": "^7.24.0",
+ "@babel/types": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/traverse": {
- "version": "7.23.9",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.9.tgz",
- "integrity": "sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg==",
+ "version": "7.24.0",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.0.tgz",
+ "integrity": "sha512-HfuJlI8qq3dEDmNU5ChzzpZRWq+oxCZQyMzIMEqLho+AQnhMnKQUzH6ydo3RBl/YjPCuk68Y6s0Gx0AeyULiWw==",
"dev": true,
"dependencies": {
"@babel/code-frame": "^7.23.5",
@@ -668,8 +670,8 @@
"@babel/helper-function-name": "^7.23.0",
"@babel/helper-hoist-variables": "^7.22.5",
"@babel/helper-split-export-declaration": "^7.22.6",
- "@babel/parser": "^7.23.9",
- "@babel/types": "^7.23.9",
+ "@babel/parser": "^7.24.0",
+ "@babel/types": "^7.24.0",
"debug": "^4.3.1",
"globals": "^11.1.0"
},
@@ -701,9 +703,9 @@
"dev": true
},
"node_modules/@babel/types": {
- "version": "7.23.9",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.9.tgz",
- "integrity": "sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==",
+ "version": "7.24.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz",
+ "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==",
"dev": true,
"dependencies": {
"@babel/helper-string-parser": "^7.23.4",
@@ -1024,14 +1026,14 @@
}
},
"node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.4",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.4.tgz",
- "integrity": "sha512-Oud2QPM5dHviZNn4y/WhhYKSXksv+1xLEIsNrAbGcFzUN3ubqWRFT5gwPchNc5NuzILOU4tPBDTZ4VwhL8Y7cw==",
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
+ "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
"dev": true,
"dependencies": {
- "@jridgewell/set-array": "^1.0.1",
+ "@jridgewell/set-array": "^1.2.1",
"@jridgewell/sourcemap-codec": "^1.4.10",
- "@jridgewell/trace-mapping": "^0.3.9"
+ "@jridgewell/trace-mapping": "^0.3.24"
},
"engines": {
"node": ">=6.0.0"
@@ -1047,9 +1049,9 @@
}
},
"node_modules/@jridgewell/set-array": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
- "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
+ "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
"dev": true,
"engines": {
"node": ">=6.0.0"
@@ -1062,9 +1064,9 @@
"dev": true
},
"node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.23",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.23.tgz",
- "integrity": "sha512-9/4foRoUKp8s96tSkh8DlAAc5A0Ty8vLXld+l9gjKKY6ckwI8G15f0hskGmuLZu78ZlGa1vtsfOa+lnB4vG6Jg==",
+ "version": "0.3.25",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
+ "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
"dev": true,
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
@@ -1197,9 +1199,9 @@
}
},
"node_modules/@types/node": {
- "version": "20.11.20",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.20.tgz",
- "integrity": "sha512-7/rR21OS+fq8IyHTgtLkDK949uzsa6n8BkziAKtPVpugIkO6D+/ooXMvzXxDnZrmtXVfjb1bKQafYpb8s89LOg==",
+ "version": "20.11.24",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.24.tgz",
+ "integrity": "sha512-Kza43ewS3xoLgCEpQrsT+xRo/EJej1y0kVYGiLFE1NEODXGzTfwiC6tXTLMQskn1X4/Rjlh0MQUvx9W+L9long==",
"dev": true,
"dependencies": {
"undici-types": "~5.26.4"
@@ -1521,9 +1523,9 @@
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
},
"node_modules/bare-events": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.2.0.tgz",
- "integrity": "sha512-Yyyqff4PIFfSuthCZqLlPISTWHmnQxoPuAvkmgzsJEmG3CesdIv6Xweayl0JkCZJSB2yYIdJyEz97tpxNhgjbg==",
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.2.1.tgz",
+ "integrity": "sha512-9GYPpsPFvrWBkelIhOhTWtkeZxVxZOdb3VnFTCzlOo3OjvmTvzLoZFUT8kNFACx0vJej6QPney1Cf9BvzCNE/A==",
"dev": true,
"optional": true
},
@@ -1663,14 +1665,15 @@
}
},
"node_modules/call-bind": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.6.tgz",
- "integrity": "sha512-Mj50FLHtlsoVfRfnHaZvyrooHcrlceNZdL/QBvJJVd9Ta55qCQK0gs4ss2oZDeV9zFCs6ewzYgVE5yfVmfFpVg==",
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
+ "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
"dependencies": {
+ "es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
- "get-intrinsic": "^1.2.3",
- "set-function-length": "^1.2.0"
+ "get-intrinsic": "^1.2.4",
+ "set-function-length": "^1.2.1"
},
"engines": {
"node": ">= 0.4"
@@ -1698,9 +1701,9 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001591",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001591.tgz",
- "integrity": "sha512-PCzRMei/vXjJyL5mJtzNiUCKP59dm8Apqc3PH8gJkMnMXZGox93RbE76jHsmLwmIo6/3nsYIpJtx0O7u5PqFuQ==",
+ "version": "1.0.30001594",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001594.tgz",
+ "integrity": "sha512-VblSX6nYqyJVs8DKFMldE2IVCJjZ225LW00ydtUWwh5hk9IfkTOffO6r8gJNsH0qqqeAF8KrbMYA2VEwTlGW5g==",
"dev": true,
"funding": [
{
@@ -1975,17 +1978,19 @@
}
},
"node_modules/define-data-property": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.2.tgz",
- "integrity": "sha512-SRtsSqsDbgpJBbW3pABMCOt6rQyeM8s8RiyeSN8jYG8sYmt/kGJejbydttUsnDs1tadr19tvhT4ShwMyoqAm4g==",
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
+ "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
"dependencies": {
+ "es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
- "get-intrinsic": "^1.2.2",
- "gopd": "^1.0.1",
- "has-property-descriptors": "^1.0.1"
+ "gopd": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/delayed-stream": {
@@ -2002,6 +2007,14 @@
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
"integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ=="
},
+ "node_modules/denque": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz",
+ "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==",
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
"node_modules/depd": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
@@ -2055,6 +2068,17 @@
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
+ "node_modules/dotenv": {
+ "version": "16.4.5",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz",
+ "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://dotenvx.com"
+ }
+ },
"node_modules/ecdsa-sig-formatter": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
@@ -2069,9 +2093,9 @@
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
},
"node_modules/electron-to-chromium": {
- "version": "1.4.682",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.682.tgz",
- "integrity": "sha512-oCglfs8yYKs9RQjJFOHonSnhikPK3y+0SvSYc/YpYJV//6rqc0/hbwd0c7vgK4vrl6y2gJAwjkhkSGWK+z4KRA==",
+ "version": "1.4.692",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.692.tgz",
+ "integrity": "sha512-d5rZRka9n2Y3MkWRN74IoAsxR0HK3yaAt7T50e3iT9VZmCCQDT3geXUO5ZRMhDToa1pkCeQXuNo+0g+NfDOVPA==",
"dev": true
},
"node_modules/emittery": {
@@ -2108,6 +2132,17 @@
"is-arrayish": "^0.2.1"
}
},
+ "node_modules/es-define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
+ "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
+ "dependencies": {
+ "get-intrinsic": "^1.2.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/es-errors": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
@@ -2209,13 +2244,13 @@
}
},
"node_modules/express": {
- "version": "4.18.2",
- "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
- "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==",
+ "version": "4.18.3",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.18.3.tgz",
+ "integrity": "sha512-6VyCijWQ+9O7WuVMTRBTl+cjNNIzD5cY5mQ1WM8r/LEkI2u8EYpOotESNwzNlyCn3g+dmjKYI6BmNneSr/FSRw==",
"dependencies": {
"accepts": "~1.3.8",
"array-flatten": "1.1.1",
- "body-parser": "1.20.1",
+ "body-parser": "1.20.2",
"content-disposition": "0.5.4",
"content-type": "~1.0.4",
"cookie": "0.5.0",
@@ -2249,43 +2284,6 @@
"node": ">= 0.10.0"
}
},
- "node_modules/express/node_modules/body-parser": {
- "version": "1.20.1",
- "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
- "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
- "dependencies": {
- "bytes": "3.1.2",
- "content-type": "~1.0.4",
- "debug": "2.6.9",
- "depd": "2.0.0",
- "destroy": "1.2.0",
- "http-errors": "2.0.0",
- "iconv-lite": "0.4.24",
- "on-finished": "2.4.1",
- "qs": "6.11.0",
- "raw-body": "2.5.1",
- "type-is": "~1.6.18",
- "unpipe": "1.0.0"
- },
- "engines": {
- "node": ">= 0.8",
- "npm": "1.2.8000 || >= 1.4.16"
- }
- },
- "node_modules/express/node_modules/raw-body": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
- "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
- "dependencies": {
- "bytes": "3.1.2",
- "http-errors": "2.0.0",
- "iconv-lite": "0.4.24",
- "unpipe": "1.0.0"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
"node_modules/fast-fifo": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz",
@@ -2519,6 +2517,14 @@
"node": ">=10"
}
},
+ "node_modules/generate-function": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz",
+ "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==",
+ "dependencies": {
+ "is-property": "^1.0.2"
+ }
+ },
"node_modules/gensync": {
"version": "1.0.0-beta.2",
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
@@ -2631,20 +2637,20 @@
}
},
"node_modules/has-property-descriptors": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz",
- "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
+ "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
"dependencies": {
- "get-intrinsic": "^1.2.2"
+ "es-define-property": "^1.0.0"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-proto": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
- "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
+ "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
"engines": {
"node": ">= 0.4"
},
@@ -2669,9 +2675,9 @@
"integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ=="
},
"node_modules/hasown": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz",
- "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz",
+ "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==",
"dependencies": {
"function-bind": "^1.1.2"
},
@@ -2875,6 +2881,11 @@
"node": ">=0.12.0"
}
},
+ "node_modules/is-property": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
+ "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g=="
+ },
"node_modules/is-stream": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
@@ -3731,6 +3742,11 @@
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
"integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="
},
+ "node_modules/long": {
+ "version": "5.2.3",
+ "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz",
+ "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q=="
+ },
"node_modules/lru-cache": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
@@ -4062,9 +4078,9 @@
"dev": true
},
"node_modules/mongoose": {
- "version": "8.2.0",
- "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.2.0.tgz",
- "integrity": "sha512-la93n6zCYRbPS+c5N9oTDAktvREy5OT9OCljp1Tah0y3+p8UPMTAoabWaLZMdzYruOtF9/9GRf6MasaZjiZP1A==",
+ "version": "8.2.1",
+ "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.2.1.tgz",
+ "integrity": "sha512-UgZZbXSJH0pdU936qj3FyVI+sBsMoGowFnL5R/RYrA50ayn6+ZYdVr8ehsRgNxRcMYwoNld5XzHIfkFRJTePEw==",
"dependencies": {
"bson": "^6.2.0",
"kareem": "2.5.1",
@@ -4091,9 +4107,9 @@
}
},
"node_modules/mongoose/node_modules/bson": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/bson/-/bson-6.3.0.tgz",
- "integrity": "sha512-balJfqwwTBddxfnidJZagCBPP/f48zj9Sdp3OJswREOgsJzHiQSaOIAtApSgDQFYgHqAvFkp53AFSqjMDZoTFw==",
+ "version": "6.4.0",
+ "resolved": "https://registry.npmjs.org/bson/-/bson-6.4.0.tgz",
+ "integrity": "sha512-6/gSSEdbkuFlSb+ufj5jUSU4+wo8xQOwm2bDSqwmxiPE17JTpsP63eAwoN8iF8Oy4gJYj+PAL3zdRCTdaw5Y1g==",
"engines": {
"node": ">=16.20.1"
}
@@ -4225,6 +4241,62 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
+ "node_modules/mysql2": {
+ "version": "3.9.2",
+ "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.9.2.tgz",
+ "integrity": "sha512-3Cwg/UuRkAv/wm6RhtPE5L7JlPB877vwSF6gfLAS68H+zhH+u5oa3AieqEd0D0/kC3W7qIhYbH419f7O9i/5nw==",
+ "dependencies": {
+ "denque": "^2.1.0",
+ "generate-function": "^2.3.1",
+ "iconv-lite": "^0.6.3",
+ "long": "^5.2.1",
+ "lru-cache": "^8.0.0",
+ "named-placeholders": "^1.1.3",
+ "seq-queue": "^0.0.5",
+ "sqlstring": "^2.3.2"
+ },
+ "engines": {
+ "node": ">= 8.0"
+ }
+ },
+ "node_modules/mysql2/node_modules/iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/mysql2/node_modules/lru-cache": {
+ "version": "8.0.5",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz",
+ "integrity": "sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==",
+ "engines": {
+ "node": ">=16.14"
+ }
+ },
+ "node_modules/named-placeholders": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.3.tgz",
+ "integrity": "sha512-eLoBxg6wE/rZkJPhU/xRX1WTpkFEwDJEN96oxFrTsqBdbT5ec295Q+CoHrL9IT0DipqKhmGcaZmwOt8OON5x1w==",
+ "dependencies": {
+ "lru-cache": "^7.14.1"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/named-placeholders/node_modules/lru-cache": {
+ "version": "7.18.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
+ "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/natural-compare": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
@@ -4872,6 +4944,11 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
},
+ "node_modules/seq-queue": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz",
+ "integrity": "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q=="
+ },
"node_modules/serve-static": {
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
@@ -4934,11 +5011,11 @@
}
},
"node_modules/side-channel": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.5.tgz",
- "integrity": "sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==",
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
+ "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
"dependencies": {
- "call-bind": "^1.0.6",
+ "call-bind": "^1.0.7",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.4",
"object-inspect": "^1.13.1"
@@ -5032,6 +5109,14 @@
"integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
"dev": true
},
+ "node_modules/sqlstring": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz",
+ "integrity": "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/stack-utils": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz",
diff --git a/questionservice/package.json b/questionservice/package.json
index ad9e8d9..aaa67bb 100644
--- a/questionservice/package.json
+++ b/questionservice/package.json
@@ -6,27 +6,31 @@
"scripts": {
"start": "node question-Service.js",
"test": "jest"
-},
-"repository": {
+ },
+ "repository": {
"type": "git",
"url": "git+https://github.com/arquisoft/wiq_0.git"
-},
-"author": "",
-"license": "ISC",
-"bugs": {
+ },
+ "author": "",
+ "license": "ISC",
+ "bugs": {
"url": "https://github.com/arquisoft/wiq_0/issues"
-},
-"homepage": "https://github.com/arquisoft/wiq_0#readme",
-"dependencies": {
+ },
+ "homepage": "https://github.com/arquisoft/wiq_0#readme",
+ "dependencies": {
"bcrypt": "^5.1.1",
"body-parser": "^1.20.2",
+ "dotenv": "^16.4.5",
"express": "^4.18.2",
"jsonwebtoken": "^9.0.2",
- "mongoose": "^8.0.4"
-},
-"devDependencies": {
+ "mongoose": "^8.0.4",
+ "mysql2": "^3.9.2",
+ "node-cron": "^3.0.0"
+
+ },
+ "devDependencies": {
"jest": "^29.7.0",
"mongodb-memory-server": "^9.1.5",
"supertest": "^6.3.4"
-}
+ }
}
diff --git a/questionservice/question-service.js b/questionservice/question-service.js
index fd98a73..529a81c 100644
--- a/questionservice/question-service.js
+++ b/questionservice/question-service.js
@@ -4,14 +4,39 @@ const port = 8003;
// Importamos la función desde questionTemplates.js
const getQuestionTemplate = require('./questionTemplates');
+//agregar el servicio de guardarlas en bd
+const DatabaseManager = require('./DataBaseManager');
+const questionService = new DatabaseManager();
+const Scheduler = require('./scheduler');
+const scheduler = new Scheduler(); // Crea una nueva instancia de la clase
+scheduler.start();//iniciar el servicio de crear las preguntas
app.use(express.json());
app.post('/getquestion', async (req, res) => {
+ try{
+
+ const questionAndAnswer = await questionService.getGameQuestions(); // Obtenemos el json de pregunta y sus respuestas
+ //const questionAndAnswer = await getQuestionTemplate(); // Obtenemos el json de pregunta y sus respuestas
+ console.log(questionAndAnswer); // Imprime questionAndAnswer en la consola
+
+ res.json(questionAndAnswer); //Devolvemos a la gateway el json
+ }catch(error){
+ console.log("Error getting question from BD: " + error);
+ }
+ /*
try {
const questionAndAnswer = await getQuestionTemplate(); // Obtenemos el json de pregunta y sus respuestas
+ //la insertamos en bd
if (questionAndAnswer) {
+ // const correctAnswer = questionAndAnswer.answers.find(answer => answer.correct).answer;
+ //const distractors = questionAndAnswer.answers.filter(answer => answer.answer !== correctAnswer).map(answer => answer.answer);
+ try {
+ await questionService.addQuestion(questionAndAnswer);
+ } catch (error) {
+ console.log("Error adding question to BD: " + error);
+ }
res.json(questionAndAnswer); //Devolvemos a la gateway el json
} else {
// Si no se obtuvo una pregunta por alguna razón, enviamos un error genérico
@@ -22,8 +47,12 @@ app.post('/getquestion', async (req, res) => {
console.error("Error generating question:", error);
res.status(500).json({ error: "Internal server error when generating the question" });
}
+ */
});
+
+
+
app.listen(port, () => {
console.log(`Server listening on http://localhost:${port}`);
});
diff --git a/questionservice/questionTemplates.js b/questionservice/questionTemplates.js
index 27e1e17..5dfc232 100644
--- a/questionservice/questionTemplates.js
+++ b/questionservice/questionTemplates.js
@@ -8,13 +8,14 @@ const templates = [
const correctAnswer = { answer: country.capital, correct: true };
const fakeAnswers = fakeCities.map(city => ({ answer: city, correct: false }));
const answers = [correctAnswer, ...fakeAnswers];
-
+ const categoria="Geografía";
// Mezclamos las respuestas para que la posición de la correcta sea aleatoria
const shuffledAnswers = shuffleArray(answers);
return {
question: `¿Cuál es la capital de ${country.name}?`,
- answers: shuffledAnswers
+ answers: shuffledAnswers,
+ questionCategory: categoria
};
},
// Aquí podemos añadir más templates
diff --git a/questionservice/scheduler.js b/questionservice/scheduler.js
new file mode 100644
index 0000000..73a3f14
--- /dev/null
+++ b/questionservice/scheduler.js
@@ -0,0 +1,29 @@
+//clase encargada de generar preguntas cada hora , se tiene que isntaciar para poder usarsel y llamar a start
+//llamado desde el question-service.js
+const cron = require('node-cron');
+const DataBaseManager = require('./DataBaseManager'); // Asegúrate de que la ruta sea correcta
+const getQuestionTemplate = require('./questionTemplates');
+
+class Scheduler {
+ constructor() {
+ this.dbManager = new DataBaseManager();
+ }
+
+
+ start() {
+ cron.schedule('*/30 * * * *', async () => {
+ let success = false;
+ while (!success) {
+ try {
+ const templates = await getQuestionTemplate(); // Obtenemos el json de pregunta y sus respuestas
+ await this.dbManager.addQuestion(templates);
+ success = true;
+ } catch (error) {
+ console.error(error);
+ }
+ }
+ });
+ }
+}
+
+module.exports = Scheduler;
\ No newline at end of file
diff --git a/users/authservice/package.json b/users/authservice/package.json
index 6b5b623..7438a5b 100644
--- a/users/authservice/package.json
+++ b/users/authservice/package.json
@@ -9,14 +9,14 @@
},
"repository": {
"type": "git",
- "url": "git+https://github.com/arquisoft/wiq_0.git"
+ "url": "git+https://github.com/arquisoft/wiq_es04c.git"
},
"author": "",
"license": "ISC",
"bugs": {
- "url": "https://github.com/arquisoft/wiq_0/issues"
+ "url": "https://github.com/arquisoft/wiq_es04c/issues"
},
- "homepage": "https://github.com/arquisoft/wiq_0#readme",
+ "homepage": "https://github.com/arquisoft/wiq_es04c#readme",
"dependencies": {
"bcrypt": "^5.1.1",
"body-parser": "^1.20.2",
diff --git a/users/userservice/package.json b/users/userservice/package.json
index 2462c8e..9ea341c 100644
--- a/users/userservice/package.json
+++ b/users/userservice/package.json
@@ -9,14 +9,14 @@
},
"repository": {
"type": "git",
- "url": "git+https://github.com/arquisoft/wiq_0.git"
+ "url": "git+https://github.com/arquisoft/wiq_es04c.git"
},
"author": "",
"license": "ISC",
"bugs": {
- "url": "https://github.com/arquisoft/wiq_0/issues"
+ "url": "https://github.com/arquisoft/wiq_es04c/issues"
},
- "homepage": "https://github.com/arquisoft/wiq_0#readme",
+ "homepage": "https://github.com/arquisoft/wiq_es04c#readme",
"dependencies": {
"bcrypt": "^5.1.1",
"body-parser": "^1.20.2",
diff --git a/webapp/package-lock.json b/webapp/package-lock.json
index 27466ae..b369b04 100644
--- a/webapp/package-lock.json
+++ b/webapp/package-lock.json
@@ -15,8 +15,11 @@
"@testing-library/react": "^14.1.2",
"@testing-library/user-event": "^14.5.2",
"axios": "^1.6.5",
+ "bootstrap": "^5.3.3",
"react": "^18.2.0",
+ "react-bootstrap": "^2.10.1",
"react-dom": "^18.2.0",
+ "react-router-dom": "^6.1.0",
"react-scripts": "5.0.1",
"web-vitals": "^3.5.1"
},
@@ -5005,6 +5008,67 @@
"node": ">=12"
}
},
+ "node_modules/@react-aria/ssr": {
+ "version": "3.9.2",
+ "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.2.tgz",
+ "integrity": "sha512-0gKkgDYdnq1w+ey8KzG9l+H5Z821qh9vVjztk55rUg71vTk/Eaebeir+WtzcLLwTjw3m/asIjx8Y59y1lJZhBw==",
+ "dependencies": {
+ "@swc/helpers": "^0.5.0"
+ },
+ "engines": {
+ "node": ">= 12"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ }
+ },
+ "node_modules/@remix-run/router": {
+ "version": "1.15.1",
+ "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.15.1.tgz",
+ "integrity": "sha512-zcU0gM3z+3iqj8UX45AmWY810l3oUmXM7uH4dt5xtzvMhRtYVhKGOmgOd1877dOPPepfCjUv57w+syamWIYe7w==",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@restart/hooks": {
+ "version": "0.4.16",
+ "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.16.tgz",
+ "integrity": "sha512-f7aCv7c+nU/3mF7NWLtVVr0Ra80RqsO89hO72r+Y/nvQr5+q0UFGkocElTH6MJApvReVh6JHUFYn2cw1WdHF3w==",
+ "dependencies": {
+ "dequal": "^2.0.3"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0"
+ }
+ },
+ "node_modules/@restart/ui": {
+ "version": "1.6.6",
+ "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.6.6.tgz",
+ "integrity": "sha512-eC3puKuWE1SRYbojWHXnvCNHGgf3uzHCb6JOhnF4OXPibOIPEkR1sqDSkL643ydigxwh+ruCa1CmYHlzk7ikKA==",
+ "dependencies": {
+ "@babel/runtime": "^7.21.0",
+ "@popperjs/core": "^2.11.6",
+ "@react-aria/ssr": "^3.5.0",
+ "@restart/hooks": "^0.4.9",
+ "@types/warning": "^3.0.0",
+ "dequal": "^2.0.3",
+ "dom-helpers": "^5.2.0",
+ "uncontrollable": "^8.0.1",
+ "warning": "^4.0.3"
+ },
+ "peerDependencies": {
+ "react": ">=16.14.0",
+ "react-dom": ">=16.14.0"
+ }
+ },
+ "node_modules/@restart/ui/node_modules/uncontrollable": {
+ "version": "8.0.4",
+ "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-8.0.4.tgz",
+ "integrity": "sha512-ulRWYWHvscPFc0QQXvyJjY6LIXU56f0h8pQFvhxiKk5V1fcI8gp9Ht9leVAhrVjzqMw0BgjspBINx9r6oyJUvQ==",
+ "peerDependencies": {
+ "react": ">=16.14.0"
+ }
+ },
"node_modules/@rollup/plugin-babel": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz",
@@ -5354,6 +5418,14 @@
"url": "https://github.com/sponsors/gregberge"
}
},
+ "node_modules/@swc/helpers": {
+ "version": "0.5.6",
+ "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.6.tgz",
+ "integrity": "sha512-aYX01Ke9hunpoCexYAgQucEpARGQ5w/cqHFrIR+e9gdKb1QWTsVJuTJ2ozQzIAxLyRQe/m+2RqzkyOOGiMKRQA==",
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
"node_modules/@testing-library/dom": {
"version": "9.3.3",
"resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.3.tgz",
@@ -5980,6 +6052,11 @@
"integrity": "sha512-pAeZeUbLE4Z9Vi9wsWV2bYPTweEHeJJy0G4pEjOA/FSvy1Ad5U5Km8iDV6TKre1mjBiVNfAdVHKruP8bAh4Q5A==",
"dev": true
},
+ "node_modules/@types/warning": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.3.tgz",
+ "integrity": "sha512-D1XC7WK8K+zZEveUPY+cf4+kgauk8N4eHr/XIHXGlGYkHLud6hK9lYfZk1ry1TNh798cZUCgb6MqGEG8DkJt6Q=="
+ },
"node_modules/@types/webidl-conversions": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz",
@@ -7476,6 +7553,24 @@
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
},
+ "node_modules/bootstrap": {
+ "version": "5.3.3",
+ "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.3.tgz",
+ "integrity": "sha512-8HLCdWgyoMguSO9o+aH+iuZ+aht+mzW0u3HIMzVu7Srrpv7EBBxTnrFlSCskwdY1+EOFQSm7uMJhNQHkdPcmjg==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/twbs"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/bootstrap"
+ }
+ ],
+ "peerDependencies": {
+ "@popperjs/core": "^2.11.8"
+ }
+ },
"node_modules/boxen": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/boxen/-/boxen-7.0.0.tgz",
@@ -8093,6 +8188,11 @@
"node": ">= 0.4"
}
},
+ "node_modules/classnames": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz",
+ "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow=="
+ },
"node_modules/clean-css": {
"version": "5.3.3",
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz",
@@ -12409,6 +12509,14 @@
"node": ">= 0.4"
}
},
+ "node_modules/invariant": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
+ "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
+ "dependencies": {
+ "loose-envify": "^1.0.0"
+ }
+ },
"node_modules/ip": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz",
@@ -21441,6 +21549,23 @@
"react-is": "^16.13.1"
}
},
+ "node_modules/prop-types-extra": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz",
+ "integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==",
+ "dependencies": {
+ "react-is": "^16.3.2",
+ "warning": "^4.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=0.14.0"
+ }
+ },
+ "node_modules/prop-types-extra/node_modules/react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
+ },
"node_modules/prop-types/node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
@@ -21862,6 +21987,35 @@
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
"integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
},
+ "node_modules/react-bootstrap": {
+ "version": "2.10.1",
+ "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.10.1.tgz",
+ "integrity": "sha512-J3OpRZIvCTQK+Tg/jOkRUvpYLHMdGeU9KqFUBQrV0d/Qr/3nsINpiOJyZMWnM5SJ3ctZdhPA6eCIKpEJR3Ellg==",
+ "dependencies": {
+ "@babel/runtime": "^7.22.5",
+ "@restart/hooks": "^0.4.9",
+ "@restart/ui": "^1.6.6",
+ "@types/react-transition-group": "^4.4.6",
+ "classnames": "^2.3.2",
+ "dom-helpers": "^5.2.1",
+ "invariant": "^2.2.4",
+ "prop-types": "^15.8.1",
+ "prop-types-extra": "^1.1.0",
+ "react-transition-group": "^4.4.5",
+ "uncontrollable": "^7.2.1",
+ "warning": "^4.0.3"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.8",
+ "react": ">=16.14.0",
+ "react-dom": ">=16.14.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
"node_modules/react-dev-utils": {
"version": "12.0.1",
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz",
@@ -22001,6 +22155,11 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
},
+ "node_modules/react-lifecycles-compat": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
+ "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
+ },
"node_modules/react-refresh": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
@@ -22009,6 +22168,36 @@
"node": ">=0.10.0"
}
},
+ "node_modules/react-router": {
+ "version": "6.22.1",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.22.1.tgz",
+ "integrity": "sha512-0pdoRGwLtemnJqn1K0XHUbnKiX0S4X8CgvVVmHGOWmofESj31msHo/1YiqcJWK7Wxfq2a4uvvtS01KAQyWK/CQ==",
+ "dependencies": {
+ "@remix-run/router": "1.15.1"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8"
+ }
+ },
+ "node_modules/react-router-dom": {
+ "version": "6.22.1",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.22.1.tgz",
+ "integrity": "sha512-iwMyyyrbL7zkKY7MRjOVRy+TMnS/OPusaFVxM2P11x9dzSzGmLsebkCvYirGq0DWB9K9hOspHYYtDz33gE5Duw==",
+ "dependencies": {
+ "@remix-run/router": "1.15.1",
+ "react-router": "6.22.1"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8",
+ "react-dom": ">=16.8"
+ }
+ },
"node_modules/react-scripts": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz",
@@ -26267,6 +26456,20 @@
"through": "^2.3.8"
}
},
+ "node_modules/uncontrollable": {
+ "version": "7.2.1",
+ "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.2.1.tgz",
+ "integrity": "sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ==",
+ "dependencies": {
+ "@babel/runtime": "^7.6.3",
+ "@types/react": ">=16.9.11",
+ "invariant": "^2.2.4",
+ "react-lifecycles-compat": "^3.0.4"
+ },
+ "peerDependencies": {
+ "react": ">=15.0.0"
+ }
+ },
"node_modules/underscore": {
"version": "1.12.1",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz",
@@ -26629,6 +26832,14 @@
"makeerror": "1.0.12"
}
},
+ "node_modules/warning": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
+ "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
+ "dependencies": {
+ "loose-envify": "^1.0.0"
+ }
+ },
"node_modules/watchpack": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
diff --git a/webapp/package.json b/webapp/package.json
index 74e31be..f886afa 100644
--- a/webapp/package.json
+++ b/webapp/package.json
@@ -10,8 +10,11 @@
"@testing-library/react": "^14.1.2",
"@testing-library/user-event": "^14.5.2",
"axios": "^1.6.5",
+ "bootstrap": "^5.3.3",
"react": "^18.2.0",
+ "react-bootstrap": "^2.10.1",
"react-dom": "^18.2.0",
+ "react-router-dom": "^6.1.0",
"react-scripts": "5.0.1",
"web-vitals": "^3.5.1"
},
diff --git a/webapp/src/App.js b/webapp/src/App.js
index 76c708e..8668b33 100644
--- a/webapp/src/App.js
+++ b/webapp/src/App.js
@@ -5,7 +5,8 @@ import CssBaseline from '@mui/material/CssBaseline';
import Container from '@mui/material/Container';
import Typography from '@mui/material/Typography';
import Link from '@mui/material/Link';
-
+import Game from './components/game/Game';
+import progressBar from './components/game/progressBar';
function App() {
const [showLogin, setShowLogin] = useState(true);
@@ -15,12 +16,11 @@ function App() {
return (
-
-
-
- Welcome to the 2024 edition of the Software Architecture course
-
- {showLogin ? : }
+
+
+
+
+ {/*showLogin ? :
{showLogin ? (
@@ -32,6 +32,7 @@ function App() {
)}
+ */}
);
diff --git a/webapp/src/components/StartButton.js b/webapp/src/components/StartButton.js
new file mode 100644
index 0000000..a5caab8
--- /dev/null
+++ b/webapp/src/components/StartButton.js
@@ -0,0 +1,20 @@
+import React, { useContext } from 'react';
+import { Link, useNavigate } from 'react-router-dom';
+import { AuthContext } from './authcontext'; // Cambia AuthProvider a AuthContext
+import '../styles/startButton.css'
+const StartButton = () => {
+ const { isLoggedIn } = useContext(AuthContext);
+ const navigate = useNavigate();
+
+ const handleClick = () => {
+ navigate(isLoggedIn ? "/game" : "/login");
+ };
+
+ return (
+
+ );
+};
+
+export default StartButton;
\ No newline at end of file
diff --git a/webapp/src/components/adduser/AddUser.js b/webapp/src/components/adduser/AddUser.js
index 00d522a..c94ce9b 100644
--- a/webapp/src/components/adduser/AddUser.js
+++ b/webapp/src/components/adduser/AddUser.js
@@ -3,7 +3,7 @@ import React, { useState } from 'react';
import axios from 'axios';
import { Container, Typography, TextField, Button, Snackbar } from '@mui/material';
-const apiEndpoint = process.env.REACT_APP_API_ENDPOINT || 'http://localhost:8000';
+const apiEndpoint = process.env.API_URI || 'http://localhost:8000';
const AddUser = () => {
const [username, setUsername] = useState('');
diff --git a/webapp/src/components/authcontext.js b/webapp/src/components/authcontext.js
new file mode 100644
index 0000000..0907894
--- /dev/null
+++ b/webapp/src/components/authcontext.js
@@ -0,0 +1,19 @@
+// AuthContext.js
+//se encarga de manejar el estado de si un usuario esta logeado o no
+import React, { useState, createContext } from 'react';
+//contexto para la app
+export const AuthContext = createContext();
+//componente que maneja el incio de sesion
+export const AuthProvider = ({ children }) => {
+ const [isLoggedIn, setIsLoggedIn] = useState(false);
+
+ const handleLogin = () => {
+ setIsLoggedIn(true);
+ };
+
+ return (
+
+ {children}
+
+ );
+};
\ No newline at end of file
diff --git a/webapp/src/components/game/Game.js b/webapp/src/components/game/Game.js
index 0644228..0f00f7a 100644
--- a/webapp/src/components/game/Game.js
+++ b/webapp/src/components/game/Game.js
@@ -16,6 +16,9 @@ const Game = () => {
const [snackbarOpen, setSnackbarOpen] = useState(false);
const [snackbarMessage, setSnackbarMessage] = useState('');
const [snackbarSeverity, setSnackbarSeverity] = useState('success');
+ const [category, setCategory] = useState('');//depuracion
+ const [type, setType] = useState('');//depuracion
+
const handleSnackbarClose = (event, reason) => {
if (reason === 'clickaway') {
return;
@@ -46,6 +49,9 @@ const Game = () => {
setQuestion(response.data.question);
setAnswers(response.data.answers);
setLoadingMessage('');
+ setCategory(response.data.questionCategory); // Nueva línea
+ setType(response.data.questionType); // Nueva línea
+
// setQuestion(exampleData.question);
// setAnswers(exampleData.answers);
} catch (error) {
@@ -84,6 +90,16 @@ const Game = () => {
))}
+
+ {/* ... */}
+ {category && (
+ Category: {category}
+ )}
+ {type && (
+ Type: {type}
+ )}
+ {/* ... */}
+
{
+ this.remainingTime--;
+ if (this.remainingTime <= 0) {
+ clearInterval(this.intervalId);
+ }
+ }, 1000);
+ }
+
+ getProgress() {
+ return (this.remainingTime / this.totalTime) * 100;
+ }
+
+ restart() {
+ clearInterval(this.intervalId);
+ this.remainingTime = this.totalTime;
+ }
+ }
\ No newline at end of file
diff --git a/webapp/src/components/login/Login.js b/webapp/src/components/login/Login.js
index 03ce23f..b957839 100644
--- a/webapp/src/components/login/Login.js
+++ b/webapp/src/components/login/Login.js
@@ -1,10 +1,17 @@
// src/components/Login.js
-import React, { useState } from 'react';
+import React, { useContext, useState ,useEffect} from 'react';
import axios from 'axios';
import { Container, Typography, TextField, Button, Snackbar } from '@mui/material';
-import Game from '../game/Game.js';
-
+import Game from './game/Game.js';
+import { AuthContext } from './authcontext';
const Login = () => {
+ //hacer que el navbar guarde el contexo de si estas loggeado o no
+ //ademas metes en localStorage que es como una cookie , el usuario para poder sacar sus datos en historial etc
+ const{handleLogin}=useContext(AuthContext);
+
+
+
+
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [error, setError] = useState('');
@@ -12,7 +19,16 @@ const Login = () => {
const [createdAt, setCreatedAt] = useState('');
const [openSnackbar, setOpenSnackbar] = useState(false);
- const apiEndpoint = process.env.REACT_APP_API_ENDPOINT || 'http://localhost:8000';
+ const apiEndpoint = process.env.API_URI ||'http://localhost:8000';
+
+ useEffect(() => {
+ if (loginSuccess) {
+ handleLogin();
+ localStorage.setItem('username', username);
+
+ }
+ }, [loginSuccess,username]); // Este efecto se ejecutará cada vez que loginSuccess cambie
+
const loginUser = async () => {
try {
@@ -23,7 +39,6 @@ const Login = () => {
setCreatedAt(userCreatedAt);
setLoginSuccess(true);
-
setOpenSnackbar(true);
} catch (error) {
setError(error.response.data.error);
@@ -79,4 +94,4 @@ const Login = () => {
);
};
-export default Login;
+export default Login;
\ No newline at end of file
diff --git a/webapp/src/components/navbar/NavBar.js b/webapp/src/components/navbar/NavBar.js
index f8cc737..71414b3 100644
--- a/webapp/src/components/navbar/NavBar.js
+++ b/webapp/src/components/navbar/NavBar.js
@@ -1,40 +1,63 @@
-// En /src/components/Navbar.js
-import React from 'react';
-import './Navbar.css'; // Importa tu archivo de estilos si es necesario
+import React ,{useContext} from 'react';
+import '../styles/Navbar.css';
+import { Link } from 'react-router-dom';
+import { AuthContext } from './authcontext';
+import { Dropdown, Nav } from 'react-bootstrap';
-const Navbar = () => (
-