From f179ce61c148cd7d5373892c6ee70262dd506282 Mon Sep 17 00:00:00 2001 From: Jose Emilio Labra Gayo Date: Mon, 22 Jan 2024 13:12:17 +0100 Subject: [PATCH 01/44] Added fetch-depth 0 --- .github/workflows/build.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cd86c5c8..c9265703 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,6 +10,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + with: + fetch-depth: 0 - uses: actions/setup-node@v4 with: node-version: 20 From ff5fadb6689c621fb7a4f0c45d1268f4aa0f1ca7 Mon Sep 17 00:00:00 2001 From: "Jorge A. Fidalgo" <47144679+ExarcaFidalgo@users.noreply.github.com> Date: Mon, 22 Jan 2024 17:05:22 +0100 Subject: [PATCH 02/44] Update sonar-project.properties --- sonar-project.properties | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sonar-project.properties b/sonar-project.properties index cdc6bb02..8ce93a6f 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -1,17 +1,17 @@ -sonar.projectKey=Arquisoft_wiq_0 +sonar.projectKey=Arquisoft_wiq_es6b sonar.organization=arquisoft # This is the name and version displayed in the SonarCloud UI. -sonar.projectName=wiq_0 +sonar.projectName=wiq_es6b sonar.projectVersion=1.0 # Encoding of the source code. Default is default system encoding sonar.host.url=https://sonarcloud.io sonar.language=js -sonar.projectName=wiq_0 +sonar.projectName=wiq_es6b sonar.coverage.exclusions=**/*.test.js sonar.sources=webapp/src/components,users/authservice,users/userservice,gatewayservice sonar.sourceEncoding=UTF-8 sonar.exclusions=node_modules/** -sonar.javascript.lcov.reportPaths=**/coverage/lcov.info \ No newline at end of file +sonar.javascript.lcov.reportPaths=**/coverage/lcov.info From 3a7d874f9df5511bda8500dcbbbcdba9b52e0ee9 Mon Sep 17 00:00:00 2001 From: "Jorge A. Fidalgo" <47144679+ExarcaFidalgo@users.noreply.github.com> Date: Mon, 22 Jan 2024 17:05:33 +0100 Subject: [PATCH 03/44] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 62fe7191..f9835b51 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# wiq_0 +# wiq_es6b [![Deploy on release](https://github.com/Arquisoft/wiq_0/actions/workflows/release.yml/badge.svg)](https://github.com/Arquisoft/wiq_0/actions/workflows/release.yml) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=Arquisoft_wiq_0&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=Arquisoft_wiq_0) From f67f94d0c32726c86be57232a21fb75cd0fc5a2b Mon Sep 17 00:00:00 2001 From: "Jorge A. Fidalgo" <47144679+ExarcaFidalgo@users.noreply.github.com> Date: Mon, 22 Jan 2024 17:08:33 +0100 Subject: [PATCH 04/44] Update sonar-project.properties --- sonar-project.properties | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sonar-project.properties b/sonar-project.properties index cdc6bb02..b83524d3 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -1,17 +1,17 @@ -sonar.projectKey=Arquisoft_wiq_0 +sonar.projectKey=Arquisoft_wiq_es6c sonar.organization=arquisoft # This is the name and version displayed in the SonarCloud UI. -sonar.projectName=wiq_0 +sonar.projectName=wiq_es6c sonar.projectVersion=1.0 # Encoding of the source code. Default is default system encoding sonar.host.url=https://sonarcloud.io sonar.language=js -sonar.projectName=wiq_0 +sonar.projectName=wiq_es6c sonar.coverage.exclusions=**/*.test.js sonar.sources=webapp/src/components,users/authservice,users/userservice,gatewayservice sonar.sourceEncoding=UTF-8 sonar.exclusions=node_modules/** -sonar.javascript.lcov.reportPaths=**/coverage/lcov.info \ No newline at end of file +sonar.javascript.lcov.reportPaths=**/coverage/lcov.info From caa267ff805226c570c6f402c6e0fd35e8559d13 Mon Sep 17 00:00:00 2001 From: "Jorge A. Fidalgo" <47144679+ExarcaFidalgo@users.noreply.github.com> Date: Mon, 22 Jan 2024 17:08:42 +0100 Subject: [PATCH 05/44] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 62fe7191..36d220c0 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# wiq_0 +# wiq_es6c [![Deploy on release](https://github.com/Arquisoft/wiq_0/actions/workflows/release.yml/badge.svg)](https://github.com/Arquisoft/wiq_0/actions/workflows/release.yml) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=Arquisoft_wiq_0&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=Arquisoft_wiq_0) From 72fedaf86736fd82858bea08e508f1122227da93 Mon Sep 17 00:00:00 2001 From: Augusto Date: Tue, 23 Jan 2024 10:20:46 +0100 Subject: [PATCH 06/44] Fixing some old-fashioned code in the actions and README.md file --- .github/workflows/release.yml | 1 - README.md | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 08a91806..d1e6a758 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -123,6 +123,5 @@ jobs: key: ${{ secrets.DEPLOY_KEY }} command: | wget https://raw.githubusercontent.com/arquisoft/wiq_0/master/docker-compose.yml - wget https://raw.githubusercontent.com/arquisoft/wiq_0/master/docker-compose-deploy.override.yml docker compose down docker compose --profile prod up -d diff --git a/README.md b/README.md index 62fe7191..626be289 100644 --- a/README.md +++ b/README.md @@ -100,8 +100,8 @@ deploy: user: ${{ secrets.DEPLOY_USER }} key: ${{ secrets.DEPLOY_KEY }} command: | - wget https://raw.githubusercontent.com/arquisoft/wiq_0/master/docker-compose-deploy.yml -O docker-compose.yml - docker compose down --volumes + wget https://raw.githubusercontent.com/arquisoft/wiq_0/master/docker-compose.yml -O docker-compose.yml + docker compose down docker compose --profile prod up -d ``` From 09590d89a1847223f3d8494d66ed9087c124c49d Mon Sep 17 00:00:00 2001 From: fidalgoLXXVI Date: Tue, 23 Jan 2024 10:49:56 +0100 Subject: [PATCH 07/44] 0 por es6b --- .env | 2 +- .github/workflows/release.yml | 12 ++++++------ README.md | 10 +++++----- docker-compose.yml | 8 ++++---- docs/README.md | 4 ++-- gatewayservice/package.json | 6 +++--- users/authservice/package.json | 6 +++--- users/userservice/package.json | 6 +++--- 8 files changed, 27 insertions(+), 27 deletions(-) diff --git a/.env b/.env index 131b17e4..d1cb9ba3 100644 --- a/.env +++ b/.env @@ -1 +1 @@ -teamname="wiq_0" \ No newline at end of file +teamname="wiq_es6b" \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 08a91806..46569636 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -53,7 +53,7 @@ jobs: env: API_URI: http://${{ secrets.DEPLOY_HOST }}:8000 with: - name: arquisoft/wiq_0/webapp + name: arquisoft/wiq_es6b/webapp username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} registry: ghcr.io @@ -71,7 +71,7 @@ jobs: - name: Publish to Registry uses: elgohr/Publish-Docker-Github-Action@v5 with: - name: arquisoft/wiq_0/authservice + name: arquisoft/wiq_es6b/authservice username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} registry: ghcr.io @@ -88,7 +88,7 @@ jobs: - name: Publish to Registry uses: elgohr/Publish-Docker-Github-Action@v5 with: - name: arquisoft/wiq_0/userservice + name: arquisoft/wiq_es6b/userservice username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} registry: ghcr.io @@ -105,7 +105,7 @@ jobs: - name: Publish to Registry uses: elgohr/Publish-Docker-Github-Action@v5 with: - name: arquisoft/wiq_0/gatewayservice + name: arquisoft/wiq_es6b/gatewayservice username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} registry: ghcr.io @@ -122,7 +122,7 @@ jobs: user: ${{ secrets.DEPLOY_USER }} key: ${{ secrets.DEPLOY_KEY }} command: | - wget https://raw.githubusercontent.com/arquisoft/wiq_0/master/docker-compose.yml - wget https://raw.githubusercontent.com/arquisoft/wiq_0/master/docker-compose-deploy.override.yml + wget https://raw.githubusercontent.com/arquisoft/wiq_es6b/master/docker-compose.yml + wget https://raw.githubusercontent.com/arquisoft/wiq_es6b/master/docker-compose-deploy.override.yml docker compose down docker compose --profile prod up -d diff --git a/README.md b/README.md index f9835b51..ed45104e 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # wiq_es6b -[![Deploy on release](https://github.com/Arquisoft/wiq_0/actions/workflows/release.yml/badge.svg)](https://github.com/Arquisoft/wiq_0/actions/workflows/release.yml) -[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=Arquisoft_wiq_0&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=Arquisoft_wiq_0) -[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=Arquisoft_wiq_0&metric=coverage)](https://sonarcloud.io/summary/new_code?id=Arquisoft_wiq_0) +[![Deploy on release](https://github.com/Arquisoft/wiq_es6b/actions/workflows/release.yml/badge.svg)](https://github.com/Arquisoft/wiq_es6b/actions/workflows/release.yml) +[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=Arquisoft_wiq_es6b&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=Arquisoft_wiq_es6b) +[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=Arquisoft_wiq_es6b&metric=coverage)](https://sonarcloud.io/summary/new_code?id=Arquisoft_wiq_es6b) This is a base repo for the [Software Architecture course](http://arquisoft.github.io/) in [2023/2024 edition](https://arquisoft.github.io/course2324.html). @@ -22,7 +22,7 @@ Both the user and auth service share a Mongo database that is accessed with mong The fastest way for launching this sample project is using docker. Just clone the project: ```sh -git clone https://github.com/Arquisoft/wiq_0.git +git clone https://github.com/Arquisoft/wiq_es6b.git ``` and launch it with docker compose: @@ -100,7 +100,7 @@ deploy: user: ${{ secrets.DEPLOY_USER }} key: ${{ secrets.DEPLOY_KEY }} command: | - wget https://raw.githubusercontent.com/arquisoft/wiq_0/master/docker-compose-deploy.yml -O docker-compose.yml + wget https://raw.githubusercontent.com/arquisoft/wiq_es6b/master/docker-compose-deploy.yml -O docker-compose.yml docker compose down --volumes docker compose --profile prod up -d ``` diff --git a/docker-compose.yml b/docker-compose.yml index c105ed50..1895c6e1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,7 +13,7 @@ services: authservice: container_name: authservice-${teamname:-defaultASW} - image: ghcr.io/arquisoft/wiq_0/authservice:latest + image: ghcr.io/arquisoft/wiq_es6b/authservice:latest profiles: ["dev", "prod"] build: ./users/authservice depends_on: @@ -27,7 +27,7 @@ services: userservice: container_name: userservice-${teamname:-defaultASW} - image: ghcr.io/arquisoft/wiq_0/userservice:latest + image: ghcr.io/arquisoft/wiq_es6b/userservice:latest profiles: ["dev", "prod"] build: ./users/userservice depends_on: @@ -41,7 +41,7 @@ services: gatewayservice: container_name: gatewayservice-${teamname:-defaultASW} - image: ghcr.io/arquisoft/wiq_0/gatewayservice:latest + image: ghcr.io/arquisoft/wiq_es6b/gatewayservice:latest profiles: ["dev", "prod"] build: ./gatewayservice depends_on: @@ -58,7 +58,7 @@ services: webapp: container_name: webapp-${teamname:-defaultASW} - image: ghcr.io/arquisoft/wiq_0/webapp:latest + image: ghcr.io/arquisoft/wiq_es6b/webapp:latest profiles: ["dev", "prod"] build: ./webapp depends_on: diff --git a/docs/README.md b/docs/README.md index 61766e49..fcd7f8fd 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,6 +1,6 @@ ## The documentation In this project, the documentation is compiled locally and deployed to GitHub pages. -The deployment url is: [https://arquisoft.github.io/wiq_0/](https://arquisoft.github.io/wiq_0/). +The deployment url is: [https://arquisoft.github.io/wiq_es6b/](https://arquisoft.github.io/wiq_es6b/). ### Documentation build For the documentation, we are going to use [AsciiDoc](https://asciidoc.org/) and [PlantUML](https://plantuml.com) and follow the [Arc42](https://github.com/arc42/arc42-template) template. If you want to be able to generate the doc locally you need to install Ruby, Java and some dependencies to translate the AsciiDoc code into html. If you are in Linux you can install Ruby and Java simply by executing: @@ -30,6 +30,6 @@ npm run build The documentation will be generated under the `docs/build` directory. ### Documentation deployment -If we want to deploy it to GitHub pages, so it is accessible via [https://arquisoft.github.io/wiq_0/](https://arquisoft.github.io/wiq_0/), we need to execute `npm run deploy`. +If we want to deploy it to GitHub pages, so it is accessible via [https://arquisoft.github.io/wiq_es6b/](https://arquisoft.github.io/wiq_es6b/), we need to execute `npm run deploy`. If you check the `package.json` in this directory you can see how deploying is as easy as executing `gh-pages -d build`, which can be directly executed using `npm run deploy` in the docs directory. The `gh-pages` package is in charge of pushing the documentation generated directory (basically some htmls) to a special github branch called gh-pages. Everything pushed to this branch is accessible on the repository page. Note that we only want to push there the documentation. Also is important that the documentation build is not pushed to the other branches of the project. \ No newline at end of file diff --git a/gatewayservice/package.json b/gatewayservice/package.json index fd16c42c..54c1e969 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_es6b.git" }, "author": "", "license": "ISC", "bugs": { - "url": "https://github.com/arquisoft/wiq_0/issues" + "url": "https://github.com/arquisoft/wiq_es6b/issues" }, - "homepage": "https://github.com/arquisoft/wiq_0#readme", + "homepage": "https://github.com/arquisoft/wiq_es6b#readme", "dependencies": { "axios": "^1.6.5", "cors": "^2.8.5", diff --git a/users/authservice/package.json b/users/authservice/package.json index 6b5b6239..9d763cc3 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_es6b.git" }, "author": "", "license": "ISC", "bugs": { - "url": "https://github.com/arquisoft/wiq_0/issues" + "url": "https://github.com/arquisoft/wiq_es6b/issues" }, - "homepage": "https://github.com/arquisoft/wiq_0#readme", + "homepage": "https://github.com/arquisoft/wiq_es6b#readme", "dependencies": { "bcrypt": "^5.1.1", "body-parser": "^1.20.2", diff --git a/users/userservice/package.json b/users/userservice/package.json index 2462c8e0..e4573057 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_es6b.git" }, "author": "", "license": "ISC", "bugs": { - "url": "https://github.com/arquisoft/wiq_0/issues" + "url": "https://github.com/arquisoft/wiq_es6b/issues" }, - "homepage": "https://github.com/arquisoft/wiq_0#readme", + "homepage": "https://github.com/arquisoft/wiq_es6b#readme", "dependencies": { "bcrypt": "^5.1.1", "body-parser": "^1.20.2", From d7948e93a1c592ec1629fefe4f514c2022a6b901 Mon Sep 17 00:00:00 2001 From: fidalgoLXXVI Date: Tue, 23 Jan 2024 10:52:10 +0100 Subject: [PATCH 08/44] 0 por es6c --- .env | 2 +- .github/workflows/release.yml | 12 ++++++------ README.md | 10 +++++----- docker-compose.yml | 8 ++++---- docs/README.md | 4 ++-- gatewayservice/package.json | 6 +++--- users/authservice/package.json | 6 +++--- users/userservice/package.json | 6 +++--- 8 files changed, 27 insertions(+), 27 deletions(-) diff --git a/.env b/.env index 131b17e4..06a1dcd6 100644 --- a/.env +++ b/.env @@ -1 +1 @@ -teamname="wiq_0" \ No newline at end of file +teamname="wiq_es6c" \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 08a91806..5d3abf3f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -53,7 +53,7 @@ jobs: env: API_URI: http://${{ secrets.DEPLOY_HOST }}:8000 with: - name: arquisoft/wiq_0/webapp + name: arquisoft/wiq_es6c/webapp username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} registry: ghcr.io @@ -71,7 +71,7 @@ jobs: - name: Publish to Registry uses: elgohr/Publish-Docker-Github-Action@v5 with: - name: arquisoft/wiq_0/authservice + name: arquisoft/wiq_es6c/authservice username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} registry: ghcr.io @@ -88,7 +88,7 @@ jobs: - name: Publish to Registry uses: elgohr/Publish-Docker-Github-Action@v5 with: - name: arquisoft/wiq_0/userservice + name: arquisoft/wiq_es6c/userservice username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} registry: ghcr.io @@ -105,7 +105,7 @@ jobs: - name: Publish to Registry uses: elgohr/Publish-Docker-Github-Action@v5 with: - name: arquisoft/wiq_0/gatewayservice + name: arquisoft/wiq_es6c/gatewayservice username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} registry: ghcr.io @@ -122,7 +122,7 @@ jobs: user: ${{ secrets.DEPLOY_USER }} key: ${{ secrets.DEPLOY_KEY }} command: | - wget https://raw.githubusercontent.com/arquisoft/wiq_0/master/docker-compose.yml - wget https://raw.githubusercontent.com/arquisoft/wiq_0/master/docker-compose-deploy.override.yml + wget https://raw.githubusercontent.com/arquisoft/wiq_es6c/master/docker-compose.yml + wget https://raw.githubusercontent.com/arquisoft/wiq_es6c/master/docker-compose-deploy.override.yml docker compose down docker compose --profile prod up -d diff --git a/README.md b/README.md index 36d220c0..22c6f459 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # wiq_es6c -[![Deploy on release](https://github.com/Arquisoft/wiq_0/actions/workflows/release.yml/badge.svg)](https://github.com/Arquisoft/wiq_0/actions/workflows/release.yml) -[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=Arquisoft_wiq_0&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=Arquisoft_wiq_0) -[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=Arquisoft_wiq_0&metric=coverage)](https://sonarcloud.io/summary/new_code?id=Arquisoft_wiq_0) +[![Deploy on release](https://github.com/Arquisoft/wiq_es6c/actions/workflows/release.yml/badge.svg)](https://github.com/Arquisoft/wiq_es6c/actions/workflows/release.yml) +[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=Arquisoft_wiq_es6c&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=Arquisoft_wiq_es6c) +[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=Arquisoft_wiq_es6c&metric=coverage)](https://sonarcloud.io/summary/new_code?id=Arquisoft_wiq_es6c) This is a base repo for the [Software Architecture course](http://arquisoft.github.io/) in [2023/2024 edition](https://arquisoft.github.io/course2324.html). @@ -22,7 +22,7 @@ Both the user and auth service share a Mongo database that is accessed with mong The fastest way for launching this sample project is using docker. Just clone the project: ```sh -git clone https://github.com/Arquisoft/wiq_0.git +git clone https://github.com/Arquisoft/wiq_es6c.git ``` and launch it with docker compose: @@ -100,7 +100,7 @@ deploy: user: ${{ secrets.DEPLOY_USER }} key: ${{ secrets.DEPLOY_KEY }} command: | - wget https://raw.githubusercontent.com/arquisoft/wiq_0/master/docker-compose-deploy.yml -O docker-compose.yml + wget https://raw.githubusercontent.com/arquisoft/wiq_es6c/master/docker-compose-deploy.yml -O docker-compose.yml docker compose down --volumes docker compose --profile prod up -d ``` diff --git a/docker-compose.yml b/docker-compose.yml index c105ed50..6d256c2a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,7 +13,7 @@ services: authservice: container_name: authservice-${teamname:-defaultASW} - image: ghcr.io/arquisoft/wiq_0/authservice:latest + image: ghcr.io/arquisoft/wiq_es6c/authservice:latest profiles: ["dev", "prod"] build: ./users/authservice depends_on: @@ -27,7 +27,7 @@ services: userservice: container_name: userservice-${teamname:-defaultASW} - image: ghcr.io/arquisoft/wiq_0/userservice:latest + image: ghcr.io/arquisoft/wiq_es6c/userservice:latest profiles: ["dev", "prod"] build: ./users/userservice depends_on: @@ -41,7 +41,7 @@ services: gatewayservice: container_name: gatewayservice-${teamname:-defaultASW} - image: ghcr.io/arquisoft/wiq_0/gatewayservice:latest + image: ghcr.io/arquisoft/wiq_es6c/gatewayservice:latest profiles: ["dev", "prod"] build: ./gatewayservice depends_on: @@ -58,7 +58,7 @@ services: webapp: container_name: webapp-${teamname:-defaultASW} - image: ghcr.io/arquisoft/wiq_0/webapp:latest + image: ghcr.io/arquisoft/wiq_es6c/webapp:latest profiles: ["dev", "prod"] build: ./webapp depends_on: diff --git a/docs/README.md b/docs/README.md index 61766e49..9a7bce52 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,6 +1,6 @@ ## The documentation In this project, the documentation is compiled locally and deployed to GitHub pages. -The deployment url is: [https://arquisoft.github.io/wiq_0/](https://arquisoft.github.io/wiq_0/). +The deployment url is: [https://arquisoft.github.io/wiq_es6c/](https://arquisoft.github.io/wiq_es6c/). ### Documentation build For the documentation, we are going to use [AsciiDoc](https://asciidoc.org/) and [PlantUML](https://plantuml.com) and follow the [Arc42](https://github.com/arc42/arc42-template) template. If you want to be able to generate the doc locally you need to install Ruby, Java and some dependencies to translate the AsciiDoc code into html. If you are in Linux you can install Ruby and Java simply by executing: @@ -30,6 +30,6 @@ npm run build The documentation will be generated under the `docs/build` directory. ### Documentation deployment -If we want to deploy it to GitHub pages, so it is accessible via [https://arquisoft.github.io/wiq_0/](https://arquisoft.github.io/wiq_0/), we need to execute `npm run deploy`. +If we want to deploy it to GitHub pages, so it is accessible via [https://arquisoft.github.io/wiq_es6c/](https://arquisoft.github.io/wiq_es6c/), we need to execute `npm run deploy`. If you check the `package.json` in this directory you can see how deploying is as easy as executing `gh-pages -d build`, which can be directly executed using `npm run deploy` in the docs directory. The `gh-pages` package is in charge of pushing the documentation generated directory (basically some htmls) to a special github branch called gh-pages. Everything pushed to this branch is accessible on the repository page. Note that we only want to push there the documentation. Also is important that the documentation build is not pushed to the other branches of the project. \ No newline at end of file diff --git a/gatewayservice/package.json b/gatewayservice/package.json index fd16c42c..686c71df 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_es6c.git" }, "author": "", "license": "ISC", "bugs": { - "url": "https://github.com/arquisoft/wiq_0/issues" + "url": "https://github.com/arquisoft/wiq_es6c/issues" }, - "homepage": "https://github.com/arquisoft/wiq_0#readme", + "homepage": "https://github.com/arquisoft/wiq_es6c#readme", "dependencies": { "axios": "^1.6.5", "cors": "^2.8.5", diff --git a/users/authservice/package.json b/users/authservice/package.json index 6b5b6239..28020661 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_es6c.git" }, "author": "", "license": "ISC", "bugs": { - "url": "https://github.com/arquisoft/wiq_0/issues" + "url": "https://github.com/arquisoft/wiq_es6c/issues" }, - "homepage": "https://github.com/arquisoft/wiq_0#readme", + "homepage": "https://github.com/arquisoft/wiq_es6c#readme", "dependencies": { "bcrypt": "^5.1.1", "body-parser": "^1.20.2", diff --git a/users/userservice/package.json b/users/userservice/package.json index 2462c8e0..37ddcdc4 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_es6c.git" }, "author": "", "license": "ISC", "bugs": { - "url": "https://github.com/arquisoft/wiq_0/issues" + "url": "https://github.com/arquisoft/wiq_es6c/issues" }, - "homepage": "https://github.com/arquisoft/wiq_0#readme", + "homepage": "https://github.com/arquisoft/wiq_es6c#readme", "dependencies": { "bcrypt": "^5.1.1", "body-parser": "^1.20.2", From d6589685369805dcf58a0fbb681046675bd87234 Mon Sep 17 00:00:00 2001 From: Augusto Date: Tue, 23 Jan 2024 15:45:55 +0100 Subject: [PATCH 09/44] Adding the .env to the service deployment --- .github/workflows/release.yml | 1 + README.md | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d1e6a758..16bbbd07 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -123,5 +123,6 @@ jobs: key: ${{ secrets.DEPLOY_KEY }} command: | wget https://raw.githubusercontent.com/arquisoft/wiq_0/master/docker-compose.yml + wget https://raw.githubusercontent.com/arquisoft/wiq_0/master/.env docker compose down docker compose --profile prod up -d diff --git a/README.md b/README.md index 626be289..f169e049 100644 --- a/README.md +++ b/README.md @@ -101,6 +101,7 @@ deploy: key: ${{ secrets.DEPLOY_KEY }} command: | wget https://raw.githubusercontent.com/arquisoft/wiq_0/master/docker-compose.yml -O docker-compose.yml + wget https://raw.githubusercontent.com/arquisoft/wiq_0/master/.env docker compose down docker compose --profile prod up -d ``` From f7c58933d386c9299ba5fede1ac0c7fce0bce2fc Mon Sep 17 00:00:00 2001 From: Augusto <49859508+augustocristian@users.noreply.github.com> Date: Tue, 23 Jan 2024 17:11:41 +0100 Subject: [PATCH 10/44] Adding -O to wget to overwrite existing files --- .github/workflows/release.yml | 4 ++-- README.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 16bbbd07..d49ca89b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -122,7 +122,7 @@ jobs: user: ${{ secrets.DEPLOY_USER }} key: ${{ secrets.DEPLOY_KEY }} command: | - wget https://raw.githubusercontent.com/arquisoft/wiq_0/master/docker-compose.yml - wget https://raw.githubusercontent.com/arquisoft/wiq_0/master/.env + wget https://raw.githubusercontent.com/arquisoft/wiq_0/master/docker-compose.yml -O docker-compose.yml + wget https://raw.githubusercontent.com/arquisoft/wiq_0/master/.env -O .env docker compose down docker compose --profile prod up -d diff --git a/README.md b/README.md index f169e049..d3b331ea 100644 --- a/README.md +++ b/README.md @@ -101,7 +101,7 @@ deploy: key: ${{ secrets.DEPLOY_KEY }} command: | wget https://raw.githubusercontent.com/arquisoft/wiq_0/master/docker-compose.yml -O docker-compose.yml - wget https://raw.githubusercontent.com/arquisoft/wiq_0/master/.env + wget https://raw.githubusercontent.com/arquisoft/wiq_0/master/.env -O .env docker compose down docker compose --profile prod up -d ``` From 88c299b44ef9df515495c6e411b818b8814bcf77 Mon Sep 17 00:00:00 2001 From: Jose Emilio Labra Gayo Date: Fri, 26 Jan 2024 10:13:23 +0100 Subject: [PATCH 11/44] Changed welcome message and some devDependencies --- webapp/package-lock.json | 27 ++++++++++++++++++++++++--- webapp/package.json | 2 ++ webapp/src/App.js | 2 +- webapp/src/App.test.js | 2 +- 4 files changed, 28 insertions(+), 5 deletions(-) diff --git a/webapp/package-lock.json b/webapp/package-lock.json index 27466aee..bcc358d5 100644 --- a/webapp/package-lock.json +++ b/webapp/package-lock.json @@ -21,6 +21,8 @@ "web-vitals": "^3.5.1" }, "devDependencies": { + "@babel/plugin-proposal-private-property-in-object": "^7.21.11", + "@babel/plugin-transform-private-property-in-object": "^7.23.4", "axios-mock-adapter": "^1.22.0", "expect-puppeteer": "^9.0.2", "jest": "^29.3.1", @@ -658,9 +660,17 @@ } }, "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.21.0-placeholder-for-preset-env.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", - "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "version": "7.21.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.11.tgz", + "integrity": "sha512-0QZ8qP/3RLDVBwBFoWAwCtgcDZJVwA5LUJRZU8x2YFfKNuFq161wK3cuGrALu5yiPu+vzwTAg/sMWVNeWeNyaw==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-property-in-object instead.", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-create-class-features-plugin": "^7.21.0", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, "engines": { "node": ">=6.9.0" }, @@ -1904,6 +1914,17 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/preset-env/node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/preset-env/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", diff --git a/webapp/package.json b/webapp/package.json index 74e31bee..6e59b09b 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -42,6 +42,8 @@ ] }, "devDependencies": { + "@babel/plugin-proposal-private-property-in-object": "^7.21.11", + "@babel/plugin-transform-private-property-in-object": "^7.23.4", "axios-mock-adapter": "^1.22.0", "expect-puppeteer": "^9.0.2", "jest": "^29.3.1", diff --git a/webapp/src/App.js b/webapp/src/App.js index d932005b..910935ab 100644 --- a/webapp/src/App.js +++ b/webapp/src/App.js @@ -17,7 +17,7 @@ function App() { - Welcome to the 2024 edition of the Software Architecture course + Welcome to wiq_0 {showLogin ? : } diff --git a/webapp/src/App.test.js b/webapp/src/App.test.js index 5e3b7314..9aa27757 100644 --- a/webapp/src/App.test.js +++ b/webapp/src/App.test.js @@ -3,6 +3,6 @@ import App from './App'; test('renders learn react link', () => { render(); - const linkElement = screen.getByText(/Welcome to the 2024 edition of the Software Architecture course/i); + const linkElement = screen.getByText(/Welcome to wiq_0/i); expect(linkElement).toBeInTheDocument(); }); From dc7416337a4e499da356a46e2ecd9a16ad74417a Mon Sep 17 00:00:00 2001 From: fidalgoLXXVI Date: Fri, 26 Jan 2024 11:59:15 +0100 Subject: [PATCH 12/44] Revert "Merge branch 'master' into master" This reverts commit dbaea69630338b4e248756c4fb3fd721eaa7635e, reversing changes made to fa9aec33d69a9f6838de309eca53cfe07e6e6202. --- .env | 2 +- .github/workflows/release.yml | 12 ++++++------ README.md | 14 +++++++------- docker-compose.yml | 8 ++++---- docs/README.md | 4 ++-- gatewayservice/package.json | 6 +++--- sonar-project.properties | 8 ++++---- users/authservice/package.json | 6 +++--- users/userservice/package.json | 6 +++--- 9 files changed, 33 insertions(+), 33 deletions(-) diff --git a/.env b/.env index 06a1dcd6..131b17e4 100644 --- a/.env +++ b/.env @@ -1 +1 @@ -teamname="wiq_es6c" \ No newline at end of file +teamname="wiq_0" \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2c3c0e56..d49ca89b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -53,7 +53,7 @@ jobs: env: API_URI: http://${{ secrets.DEPLOY_HOST }}:8000 with: - name: arquisoft/wiq_es6c/webapp + name: arquisoft/wiq_0/webapp username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} registry: ghcr.io @@ -71,7 +71,7 @@ jobs: - name: Publish to Registry uses: elgohr/Publish-Docker-Github-Action@v5 with: - name: arquisoft/wiq_es6c/authservice + name: arquisoft/wiq_0/authservice username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} registry: ghcr.io @@ -88,7 +88,7 @@ jobs: - name: Publish to Registry uses: elgohr/Publish-Docker-Github-Action@v5 with: - name: arquisoft/wiq_es6c/userservice + name: arquisoft/wiq_0/userservice username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} registry: ghcr.io @@ -105,7 +105,7 @@ jobs: - name: Publish to Registry uses: elgohr/Publish-Docker-Github-Action@v5 with: - name: arquisoft/wiq_es6c/gatewayservice + name: arquisoft/wiq_0/gatewayservice username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} registry: ghcr.io @@ -122,7 +122,7 @@ jobs: user: ${{ secrets.DEPLOY_USER }} key: ${{ secrets.DEPLOY_KEY }} command: | - wget https://raw.githubusercontent.com/arquisoft/wiq_es6c/master/docker-compose.yml -O docker-compose.yml - wget https://raw.githubusercontent.com/arquisoft/wiq_es6c/master/.env -O .env + wget https://raw.githubusercontent.com/arquisoft/wiq_0/master/docker-compose.yml -O docker-compose.yml + wget https://raw.githubusercontent.com/arquisoft/wiq_0/master/.env -O .env docker compose down docker compose --profile prod up -d diff --git a/README.md b/README.md index 2316d34b..d3b331ea 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -# wiq_es6c +# wiq_0 -[![Deploy on release](https://github.com/Arquisoft/wiq_es6c/actions/workflows/release.yml/badge.svg)](https://github.com/Arquisoft/wiq_es6c/actions/workflows/release.yml) -[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=Arquisoft_wiq_es6c&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=Arquisoft_wiq_es6c) -[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=Arquisoft_wiq_es6c&metric=coverage)](https://sonarcloud.io/summary/new_code?id=Arquisoft_wiq_es6c) +[![Deploy on release](https://github.com/Arquisoft/wiq_0/actions/workflows/release.yml/badge.svg)](https://github.com/Arquisoft/wiq_0/actions/workflows/release.yml) +[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=Arquisoft_wiq_0&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=Arquisoft_wiq_0) +[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=Arquisoft_wiq_0&metric=coverage)](https://sonarcloud.io/summary/new_code?id=Arquisoft_wiq_0) This is a base repo for the [Software Architecture course](http://arquisoft.github.io/) in [2023/2024 edition](https://arquisoft.github.io/course2324.html). @@ -22,7 +22,7 @@ Both the user and auth service share a Mongo database that is accessed with mong The fastest way for launching this sample project is using docker. Just clone the project: ```sh -git clone https://github.com/Arquisoft/wiq_es6c.git +git clone https://github.com/Arquisoft/wiq_0.git ``` and launch it with docker compose: @@ -100,8 +100,8 @@ deploy: user: ${{ secrets.DEPLOY_USER }} key: ${{ secrets.DEPLOY_KEY }} command: | - wget https://raw.githubusercontent.com/arquisoft/wiq_es6c/master/docker-compose.yml -O docker-compose.yml - wget https://raw.githubusercontent.com/arquisoft/wiq_es6c/master/.env -O .env + wget https://raw.githubusercontent.com/arquisoft/wiq_0/master/docker-compose.yml -O docker-compose.yml + wget https://raw.githubusercontent.com/arquisoft/wiq_0/master/.env -O .env docker compose down docker compose --profile prod up -d ``` diff --git a/docker-compose.yml b/docker-compose.yml index 6d256c2a..c105ed50 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,7 +13,7 @@ services: authservice: container_name: authservice-${teamname:-defaultASW} - image: ghcr.io/arquisoft/wiq_es6c/authservice:latest + image: ghcr.io/arquisoft/wiq_0/authservice:latest profiles: ["dev", "prod"] build: ./users/authservice depends_on: @@ -27,7 +27,7 @@ services: userservice: container_name: userservice-${teamname:-defaultASW} - image: ghcr.io/arquisoft/wiq_es6c/userservice:latest + image: ghcr.io/arquisoft/wiq_0/userservice:latest profiles: ["dev", "prod"] build: ./users/userservice depends_on: @@ -41,7 +41,7 @@ services: gatewayservice: container_name: gatewayservice-${teamname:-defaultASW} - image: ghcr.io/arquisoft/wiq_es6c/gatewayservice:latest + image: ghcr.io/arquisoft/wiq_0/gatewayservice:latest profiles: ["dev", "prod"] build: ./gatewayservice depends_on: @@ -58,7 +58,7 @@ services: webapp: container_name: webapp-${teamname:-defaultASW} - image: ghcr.io/arquisoft/wiq_es6c/webapp:latest + image: ghcr.io/arquisoft/wiq_0/webapp:latest profiles: ["dev", "prod"] build: ./webapp depends_on: diff --git a/docs/README.md b/docs/README.md index 9a7bce52..61766e49 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,6 +1,6 @@ ## The documentation In this project, the documentation is compiled locally and deployed to GitHub pages. -The deployment url is: [https://arquisoft.github.io/wiq_es6c/](https://arquisoft.github.io/wiq_es6c/). +The deployment url is: [https://arquisoft.github.io/wiq_0/](https://arquisoft.github.io/wiq_0/). ### Documentation build For the documentation, we are going to use [AsciiDoc](https://asciidoc.org/) and [PlantUML](https://plantuml.com) and follow the [Arc42](https://github.com/arc42/arc42-template) template. If you want to be able to generate the doc locally you need to install Ruby, Java and some dependencies to translate the AsciiDoc code into html. If you are in Linux you can install Ruby and Java simply by executing: @@ -30,6 +30,6 @@ npm run build The documentation will be generated under the `docs/build` directory. ### Documentation deployment -If we want to deploy it to GitHub pages, so it is accessible via [https://arquisoft.github.io/wiq_es6c/](https://arquisoft.github.io/wiq_es6c/), we need to execute `npm run deploy`. +If we want to deploy it to GitHub pages, so it is accessible via [https://arquisoft.github.io/wiq_0/](https://arquisoft.github.io/wiq_0/), we need to execute `npm run deploy`. If you check the `package.json` in this directory you can see how deploying is as easy as executing `gh-pages -d build`, which can be directly executed using `npm run deploy` in the docs directory. The `gh-pages` package is in charge of pushing the documentation generated directory (basically some htmls) to a special github branch called gh-pages. Everything pushed to this branch is accessible on the repository page. Note that we only want to push there the documentation. Also is important that the documentation build is not pushed to the other branches of the project. \ No newline at end of file diff --git a/gatewayservice/package.json b/gatewayservice/package.json index 686c71df..fd16c42c 100644 --- a/gatewayservice/package.json +++ b/gatewayservice/package.json @@ -9,14 +9,14 @@ }, "repository": { "type": "git", - "url": "git+https://github.com/arquisoft/wiq_es6c.git" + "url": "git+https://github.com/arquisoft/wiq_0.git" }, "author": "", "license": "ISC", "bugs": { - "url": "https://github.com/arquisoft/wiq_es6c/issues" + "url": "https://github.com/arquisoft/wiq_0/issues" }, - "homepage": "https://github.com/arquisoft/wiq_es6c#readme", + "homepage": "https://github.com/arquisoft/wiq_0#readme", "dependencies": { "axios": "^1.6.5", "cors": "^2.8.5", diff --git a/sonar-project.properties b/sonar-project.properties index b83524d3..cdc6bb02 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -1,17 +1,17 @@ -sonar.projectKey=Arquisoft_wiq_es6c +sonar.projectKey=Arquisoft_wiq_0 sonar.organization=arquisoft # This is the name and version displayed in the SonarCloud UI. -sonar.projectName=wiq_es6c +sonar.projectName=wiq_0 sonar.projectVersion=1.0 # Encoding of the source code. Default is default system encoding sonar.host.url=https://sonarcloud.io sonar.language=js -sonar.projectName=wiq_es6c +sonar.projectName=wiq_0 sonar.coverage.exclusions=**/*.test.js sonar.sources=webapp/src/components,users/authservice,users/userservice,gatewayservice sonar.sourceEncoding=UTF-8 sonar.exclusions=node_modules/** -sonar.javascript.lcov.reportPaths=**/coverage/lcov.info +sonar.javascript.lcov.reportPaths=**/coverage/lcov.info \ No newline at end of file diff --git a/users/authservice/package.json b/users/authservice/package.json index 28020661..6b5b6239 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_es6c.git" + "url": "git+https://github.com/arquisoft/wiq_0.git" }, "author": "", "license": "ISC", "bugs": { - "url": "https://github.com/arquisoft/wiq_es6c/issues" + "url": "https://github.com/arquisoft/wiq_0/issues" }, - "homepage": "https://github.com/arquisoft/wiq_es6c#readme", + "homepage": "https://github.com/arquisoft/wiq_0#readme", "dependencies": { "bcrypt": "^5.1.1", "body-parser": "^1.20.2", diff --git a/users/userservice/package.json b/users/userservice/package.json index 37ddcdc4..2462c8e0 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_es6c.git" + "url": "git+https://github.com/arquisoft/wiq_0.git" }, "author": "", "license": "ISC", "bugs": { - "url": "https://github.com/arquisoft/wiq_es6c/issues" + "url": "https://github.com/arquisoft/wiq_0/issues" }, - "homepage": "https://github.com/arquisoft/wiq_es6c#readme", + "homepage": "https://github.com/arquisoft/wiq_0#readme", "dependencies": { "bcrypt": "^5.1.1", "body-parser": "^1.20.2", From e049274c2b68dea1b3ee1716d98f1189948325a4 Mon Sep 17 00:00:00 2001 From: fidalgoLXXVI Date: Fri, 26 Jan 2024 12:16:25 +0100 Subject: [PATCH 13/44] Revert "Merge branch 'master' of https://github.com/Arquisoft/wiq_0" This reverts commit fa9aec33d69a9f6838de309eca53cfe07e6e6202, reversing changes made to 88c299b44ef9df515495c6e411b818b8814bcf77. --- .github/workflows/release.yml | 4 ++-- README.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f1fe99e8..4b7216b0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -122,7 +122,7 @@ jobs: user: ${{ secrets.DEPLOY_USER }} key: ${{ secrets.DEPLOY_KEY }} command: | - wget https://raw.githubusercontent.com/arquisoft/wiq_es6b/master/docker-compose.yml -O docker-compose.yml - wget https://raw.githubusercontent.com/arquisoft/wiq_es6b/master/.env -O .env + wget https://raw.githubusercontent.com/arquisoft/wiq_0/master/docker-compose.yml -O docker-compose.yml + wget https://raw.githubusercontent.com/arquisoft/wiq_0/master/.env -O .env docker compose down docker compose --profile prod up -d diff --git a/README.md b/README.md index 0aa0cd7e..68b8a113 100644 --- a/README.md +++ b/README.md @@ -100,8 +100,8 @@ deploy: user: ${{ secrets.DEPLOY_USER }} key: ${{ secrets.DEPLOY_KEY }} command: | - wget https://raw.githubusercontent.com/arquisoft/wiq_es6b/master/docker-compose.yml -O docker-compose.yml - wget https://raw.githubusercontent.com/arquisoft/wiq_es6b/master/.env -O .env + wget https://raw.githubusercontent.com/arquisoft/wiq_0/master/docker-compose.yml -O docker-compose.yml + wget https://raw.githubusercontent.com/arquisoft/wiq_0/master/.env -O .env docker compose down docker compose --profile prod up -d ``` From e9278f2c61350abd4d8ce0e281488b8d1f8e00b9 Mon Sep 17 00:00:00 2001 From: fidalgoLXXVI Date: Fri, 26 Jan 2024 12:29:00 +0100 Subject: [PATCH 14/44] Expiando mis pecados --- .env | 2 +- .github/workflows/release.yml | 8 ++++---- README.md | 10 +++++----- docker-compose.yml | 8 ++++---- docs/README.md | 4 ++-- gatewayservice/package.json | 6 +++--- users/authservice/package.json | 6 +++--- users/userservice/package.json | 6 +++--- 8 files changed, 25 insertions(+), 25 deletions(-) diff --git a/.env b/.env index d1cb9ba3..131b17e4 100644 --- a/.env +++ b/.env @@ -1 +1 @@ -teamname="wiq_es6b" \ No newline at end of file +teamname="wiq_0" \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4b7216b0..d49ca89b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -53,7 +53,7 @@ jobs: env: API_URI: http://${{ secrets.DEPLOY_HOST }}:8000 with: - name: arquisoft/wiq_es6b/webapp + name: arquisoft/wiq_0/webapp username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} registry: ghcr.io @@ -71,7 +71,7 @@ jobs: - name: Publish to Registry uses: elgohr/Publish-Docker-Github-Action@v5 with: - name: arquisoft/wiq_es6b/authservice + name: arquisoft/wiq_0/authservice username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} registry: ghcr.io @@ -88,7 +88,7 @@ jobs: - name: Publish to Registry uses: elgohr/Publish-Docker-Github-Action@v5 with: - name: arquisoft/wiq_es6b/userservice + name: arquisoft/wiq_0/userservice username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} registry: ghcr.io @@ -105,7 +105,7 @@ jobs: - name: Publish to Registry uses: elgohr/Publish-Docker-Github-Action@v5 with: - name: arquisoft/wiq_es6b/gatewayservice + name: arquisoft/wiq_0/gatewayservice username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} registry: ghcr.io diff --git a/README.md b/README.md index 68b8a113..d3b331ea 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -# wiq_es6b +# wiq_0 -[![Deploy on release](https://github.com/Arquisoft/wiq_es6b/actions/workflows/release.yml/badge.svg)](https://github.com/Arquisoft/wiq_es6b/actions/workflows/release.yml) -[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=Arquisoft_wiq_es6b&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=Arquisoft_wiq_es6b) -[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=Arquisoft_wiq_es6b&metric=coverage)](https://sonarcloud.io/summary/new_code?id=Arquisoft_wiq_es6b) +[![Deploy on release](https://github.com/Arquisoft/wiq_0/actions/workflows/release.yml/badge.svg)](https://github.com/Arquisoft/wiq_0/actions/workflows/release.yml) +[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=Arquisoft_wiq_0&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=Arquisoft_wiq_0) +[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=Arquisoft_wiq_0&metric=coverage)](https://sonarcloud.io/summary/new_code?id=Arquisoft_wiq_0) This is a base repo for the [Software Architecture course](http://arquisoft.github.io/) in [2023/2024 edition](https://arquisoft.github.io/course2324.html). @@ -22,7 +22,7 @@ Both the user and auth service share a Mongo database that is accessed with mong The fastest way for launching this sample project is using docker. Just clone the project: ```sh -git clone https://github.com/Arquisoft/wiq_es6b.git +git clone https://github.com/Arquisoft/wiq_0.git ``` and launch it with docker compose: diff --git a/docker-compose.yml b/docker-compose.yml index 1895c6e1..c105ed50 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,7 +13,7 @@ services: authservice: container_name: authservice-${teamname:-defaultASW} - image: ghcr.io/arquisoft/wiq_es6b/authservice:latest + image: ghcr.io/arquisoft/wiq_0/authservice:latest profiles: ["dev", "prod"] build: ./users/authservice depends_on: @@ -27,7 +27,7 @@ services: userservice: container_name: userservice-${teamname:-defaultASW} - image: ghcr.io/arquisoft/wiq_es6b/userservice:latest + image: ghcr.io/arquisoft/wiq_0/userservice:latest profiles: ["dev", "prod"] build: ./users/userservice depends_on: @@ -41,7 +41,7 @@ services: gatewayservice: container_name: gatewayservice-${teamname:-defaultASW} - image: ghcr.io/arquisoft/wiq_es6b/gatewayservice:latest + image: ghcr.io/arquisoft/wiq_0/gatewayservice:latest profiles: ["dev", "prod"] build: ./gatewayservice depends_on: @@ -58,7 +58,7 @@ services: webapp: container_name: webapp-${teamname:-defaultASW} - image: ghcr.io/arquisoft/wiq_es6b/webapp:latest + image: ghcr.io/arquisoft/wiq_0/webapp:latest profiles: ["dev", "prod"] build: ./webapp depends_on: diff --git a/docs/README.md b/docs/README.md index fcd7f8fd..61766e49 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,6 +1,6 @@ ## The documentation In this project, the documentation is compiled locally and deployed to GitHub pages. -The deployment url is: [https://arquisoft.github.io/wiq_es6b/](https://arquisoft.github.io/wiq_es6b/). +The deployment url is: [https://arquisoft.github.io/wiq_0/](https://arquisoft.github.io/wiq_0/). ### Documentation build For the documentation, we are going to use [AsciiDoc](https://asciidoc.org/) and [PlantUML](https://plantuml.com) and follow the [Arc42](https://github.com/arc42/arc42-template) template. If you want to be able to generate the doc locally you need to install Ruby, Java and some dependencies to translate the AsciiDoc code into html. If you are in Linux you can install Ruby and Java simply by executing: @@ -30,6 +30,6 @@ npm run build The documentation will be generated under the `docs/build` directory. ### Documentation deployment -If we want to deploy it to GitHub pages, so it is accessible via [https://arquisoft.github.io/wiq_es6b/](https://arquisoft.github.io/wiq_es6b/), we need to execute `npm run deploy`. +If we want to deploy it to GitHub pages, so it is accessible via [https://arquisoft.github.io/wiq_0/](https://arquisoft.github.io/wiq_0/), we need to execute `npm run deploy`. If you check the `package.json` in this directory you can see how deploying is as easy as executing `gh-pages -d build`, which can be directly executed using `npm run deploy` in the docs directory. The `gh-pages` package is in charge of pushing the documentation generated directory (basically some htmls) to a special github branch called gh-pages. Everything pushed to this branch is accessible on the repository page. Note that we only want to push there the documentation. Also is important that the documentation build is not pushed to the other branches of the project. \ No newline at end of file diff --git a/gatewayservice/package.json b/gatewayservice/package.json index 54c1e969..fd16c42c 100644 --- a/gatewayservice/package.json +++ b/gatewayservice/package.json @@ -9,14 +9,14 @@ }, "repository": { "type": "git", - "url": "git+https://github.com/arquisoft/wiq_es6b.git" + "url": "git+https://github.com/arquisoft/wiq_0.git" }, "author": "", "license": "ISC", "bugs": { - "url": "https://github.com/arquisoft/wiq_es6b/issues" + "url": "https://github.com/arquisoft/wiq_0/issues" }, - "homepage": "https://github.com/arquisoft/wiq_es6b#readme", + "homepage": "https://github.com/arquisoft/wiq_0#readme", "dependencies": { "axios": "^1.6.5", "cors": "^2.8.5", diff --git a/users/authservice/package.json b/users/authservice/package.json index 9d763cc3..6b5b6239 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_es6b.git" + "url": "git+https://github.com/arquisoft/wiq_0.git" }, "author": "", "license": "ISC", "bugs": { - "url": "https://github.com/arquisoft/wiq_es6b/issues" + "url": "https://github.com/arquisoft/wiq_0/issues" }, - "homepage": "https://github.com/arquisoft/wiq_es6b#readme", + "homepage": "https://github.com/arquisoft/wiq_0#readme", "dependencies": { "bcrypt": "^5.1.1", "body-parser": "^1.20.2", diff --git a/users/userservice/package.json b/users/userservice/package.json index e4573057..2462c8e0 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_es6b.git" + "url": "git+https://github.com/arquisoft/wiq_0.git" }, "author": "", "license": "ISC", "bugs": { - "url": "https://github.com/arquisoft/wiq_es6b/issues" + "url": "https://github.com/arquisoft/wiq_0/issues" }, - "homepage": "https://github.com/arquisoft/wiq_es6b#readme", + "homepage": "https://github.com/arquisoft/wiq_0#readme", "dependencies": { "bcrypt": "^5.1.1", "body-parser": "^1.20.2", From 1f0cbfb2d0812b70fc5ca92df1a863f60c59586b Mon Sep 17 00:00:00 2001 From: Augusto Date: Mon, 12 Feb 2024 10:20:05 +0100 Subject: [PATCH 15/44] Minor fixes to tear-down the container --- .github/workflows/release.yml | 2 +- README.md | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d49ca89b..2905c196 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -124,5 +124,5 @@ jobs: command: | wget https://raw.githubusercontent.com/arquisoft/wiq_0/master/docker-compose.yml -O docker-compose.yml wget https://raw.githubusercontent.com/arquisoft/wiq_0/master/.env -O .env - docker compose down + docker compose --profile prod down docker compose --profile prod up -d diff --git a/README.md b/README.md index d3b331ea..fb89a4a1 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,12 @@ and launch it with docker compose: docker compose --profile dev up --build ``` +and tear it down: + +```sh +docker compose --profile dev down +``` + ### Starting Component by component First, start the database. Either install and run Mongo or run it using docker: @@ -102,7 +108,7 @@ deploy: command: | wget https://raw.githubusercontent.com/arquisoft/wiq_0/master/docker-compose.yml -O docker-compose.yml wget https://raw.githubusercontent.com/arquisoft/wiq_0/master/.env -O .env - docker compose down + docker compose --profile prod down docker compose --profile prod up -d ``` From 304dd1527f03ee8f80ee1ae786081e90edb3b871 Mon Sep 17 00:00:00 2001 From: Augusto <49859508+augustocristian@users.noreply.github.com> Date: Thu, 14 Mar 2024 19:22:09 +0100 Subject: [PATCH 16/44] Adding --pull always to the deployment command to force image download/update (#15) Related to: https://github.com/orgs/Arquisoft/discussions/54 --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2905c196..cb96d06b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -125,4 +125,4 @@ jobs: wget https://raw.githubusercontent.com/arquisoft/wiq_0/master/docker-compose.yml -O docker-compose.yml wget https://raw.githubusercontent.com/arquisoft/wiq_0/master/.env -O .env docker compose --profile prod down - docker compose --profile prod up -d + docker compose --profile prod up -d --pull always From 227b3f5e2c7b5f8dc9ff10f1f9840f5953566c3f Mon Sep 17 00:00:00 2001 From: Augusto <49859508+augustocristian@users.noreply.github.com> Date: Sun, 17 Mar 2024 21:27:33 +0100 Subject: [PATCH 17/44] Added OpenAPI specification for wiq_0 gateway service (#17) - Included an openapi.yaml file with the v0.2.0 of the specification - Some changes in the gateway.js to create the swagger sever - Added --pull always option to the README --- README.md | 2 +- gatewayservice/gateway-service.js | 17 +++++ gatewayservice/openapi.yaml | 110 ++++++++++++++++++++++++++++++ gatewayservice/package.json | 5 +- 4 files changed, 132 insertions(+), 2 deletions(-) create mode 100644 gatewayservice/openapi.yaml diff --git a/README.md b/README.md index fb89a4a1..806935e5 100644 --- a/README.md +++ b/README.md @@ -109,7 +109,7 @@ deploy: wget https://raw.githubusercontent.com/arquisoft/wiq_0/master/docker-compose.yml -O docker-compose.yml wget https://raw.githubusercontent.com/arquisoft/wiq_0/master/.env -O .env docker compose --profile prod down - docker compose --profile prod up -d + docker compose --profile prod up -d --pull always ``` This action uses three secrets that must be configured in the repository: diff --git a/gatewayservice/gateway-service.js b/gatewayservice/gateway-service.js index 88b84c8f..84d7d8fa 100644 --- a/gatewayservice/gateway-service.js +++ b/gatewayservice/gateway-service.js @@ -2,6 +2,11 @@ const express = require('express'); const axios = require('axios'); const cors = require('cors'); const promBundle = require('express-prom-bundle'); +//libraries required for OpenAPI-Swagger +const swaggerUi = require('swagger-ui-express'); +const fs = require("fs") +const YAML = require('yaml') + const app = express(); const port = 8000; @@ -41,9 +46,21 @@ app.post('/adduser', async (req, res) => { } }); +// Read the OpenAPI YAML file synchronously +const file = fs.readFileSync('./openapi.yaml', 'utf8'); + +// Parse the YAML content into a JavaScript object representing the Swagger document +const swaggerDocument = YAML.parse(file); + +// Serve the Swagger UI documentation at the '/api-doc' endpoint +// This middleware serves the Swagger UI files and sets up the Swagger UI page +// It takes the parsed Swagger document as input +app.use('/api-doc', swaggerUi.serve, swaggerUi.setup(swaggerDocument)); + // Start the gateway service const server = app.listen(port, () => { console.log(`Gateway Service listening at http://localhost:${port}`); }); + module.exports = server diff --git a/gatewayservice/openapi.yaml b/gatewayservice/openapi.yaml new file mode 100644 index 00000000..c253e705 --- /dev/null +++ b/gatewayservice/openapi.yaml @@ -0,0 +1,110 @@ +openapi: 3.0.0 +info: + title: Gatewayservice API + description: Gateway OpenAPI specification. + version: 0.2.0 +servers: + - url: http://localhost:8000 + description: Development server + - url: http://SOMEIP:8000 + description: Production server +paths: + /adduser: + post: + summary: Add a new user to the database. + operationId: addUser + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + username: + type: string + description: User ID. + password: + type: string + description: User password. + responses: + '200': + description: User added successfully. + '400': + description: Failed to add user. + content: + application/json: + schema: + type: object + properties: + error: + type: string + description: Error information. + /health: + get: + summary: Check the health status of the service. + operationId: checkHealth + responses: + '200': + description: Service is healthy. + content: + application/json: + schema: + type: object + properties: + status: + type: string + description: Health status. + /login: + post: + summary: Log in to the system. + operationId: loginUser + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + username: + type: string + description: User ID. + password: + type: string + description: User password. + responses: + '200': + description: Login successful. Returns user token, username, and creation date. + content: + application/json: + schema: + type: object + properties: + token: + type: string + description: User token. + username: + type: string + description: Username. + createdAt: + type: string + description: Creation date. + '401': + description: Invalid credentials. + content: + application/json: + schema: + type: object + properties: + error: + type: string + description: Invalid Credentials. + '500': + description: Internal server error. + content: + application/json: + schema: + type: object + properties: + error: + type: string + description: Error information. diff --git a/gatewayservice/package.json b/gatewayservice/package.json index fd16c42c..1d5f9df7 100644 --- a/gatewayservice/package.json +++ b/gatewayservice/package.json @@ -21,7 +21,10 @@ "axios": "^1.6.5", "cors": "^2.8.5", "express": "^4.18.2", - "express-prom-bundle": "^7.0.0" + "express-openapi": "^12.1.3", + "express-prom-bundle": "^7.0.0", + "swagger-ui-express": "^5.0.0", + "yaml": "^2.4.1" }, "devDependencies": { "jest": "^29.7.0", From 6e9d94e8cfac7fc4d1c9312051fe4dda206b5540 Mon Sep 17 00:00:00 2001 From: Augusto <49859508+augustocristian@users.noreply.github.com> Date: Sun, 17 Mar 2024 21:32:42 +0100 Subject: [PATCH 18/44] Sync package.json with package-lock.json (#18) * Sync package-lock.json --- gatewayservice/package-lock.json | 261 ++++++++++++++++++++++++++++--- 1 file changed, 241 insertions(+), 20 deletions(-) diff --git a/gatewayservice/package-lock.json b/gatewayservice/package-lock.json index fc5f2d60..430cbe99 100644 --- a/gatewayservice/package-lock.json +++ b/gatewayservice/package-lock.json @@ -12,7 +12,10 @@ "axios": "^1.6.5", "cors": "^2.8.5", "express": "^4.18.2", - "express-prom-bundle": "^7.0.0" + "express-openapi": "^12.1.3", + "express-prom-bundle": "^7.0.0", + "swagger-ui-express": "^5.0.0", + "yaml": "^2.4.1" }, "devDependencies": { "jest": "^29.7.0", @@ -1277,6 +1280,37 @@ "node": ">= 0.6" } }, + "node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -1333,7 +1367,6 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, "dependencies": { "sprintf-js": "~1.0.2" } @@ -1474,8 +1507,7 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/bintrees": { "version": "1.0.2", @@ -1510,7 +1542,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1751,8 +1782,7 @@ "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "node_modules/content-disposition": { "version": "0.5.4", @@ -1942,6 +1972,14 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/difunc": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/difunc/-/difunc-0.0.4.tgz", + "integrity": "sha512-zBiL4ALDmviHdoLC0g0G6wVme5bwAow9WfhcZLLopXCAWgg3AEf7RYTs2xugszIGulRHzEVDF/SHl9oyQU07Pw==", + "dependencies": { + "esprima": "^4.0.0" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -2015,7 +2053,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -2121,6 +2158,21 @@ "node": ">= 0.10.0" } }, + "node_modules/express-normalize-query-params-middleware": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/express-normalize-query-params-middleware/-/express-normalize-query-params-middleware-0.5.1.tgz", + "integrity": "sha512-KUBjEukYL9KJkrphVX3ZgMHgMTdgaSJe+FIOeWwJIJpCw8UZQPIylt0MYddSyUwbms4LQ8RC4wmavcLUP9uduA==" + }, + "node_modules/express-openapi": { + "version": "12.1.3", + "resolved": "https://registry.npmjs.org/express-openapi/-/express-openapi-12.1.3.tgz", + "integrity": "sha512-F570dVC5ENSkLu1SpDFPRQ13Y3a/7Udh0rfHyn3O1QrE81fPmlhnAo1JRgoNtbMRJ6goHNymxU1TVSllgFZBlQ==", + "dependencies": { + "express-normalize-query-params-middleware": "^0.5.0", + "openapi-framework": "^12.1.3", + "openapi-types": "^12.1.3" + } + }, "node_modules/express-prom-bundle": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/express-prom-bundle/-/express-prom-bundle-7.0.0.tgz", @@ -2138,6 +2190,11 @@ "prom-client": ">=15.0.0" } }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -2264,11 +2321,18 @@ "node": ">= 0.6" } }, + "node_modules/fs-routes": { + "version": "12.1.3", + "resolved": "https://registry.npmjs.org/fs-routes/-/fs-routes-12.1.3.tgz", + "integrity": "sha512-Vwxi5StpKj/pgH7yRpNpVFdaZr16z71KNTiYuZEYVET+MfZ31Zkf7oxUmNgyZxptG8BolRtdMP90agIhdyiozg==", + "peerDependencies": { + "glob": ">=7.1.6" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "node_modules/fsevents": { "version": "2.3.3", @@ -2349,7 +2413,6 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -2526,7 +2589,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -2563,6 +2625,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-dir/-/is-dir-1.0.0.tgz", + "integrity": "sha512-vLwCNpTNkFC5k7SBRxPubhOCryeulkOsSkjbGyZ8eOzZmzMS+hSEO/Kn9ZOVhFNAlRZTFc4ZKql48hESuYUPIQ==" + }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -3328,7 +3395,6 @@ "version": "3.14.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -3355,6 +3421,11 @@ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -3403,6 +3474,11 @@ "node": ">=8" } }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -3552,7 +3628,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -3643,7 +3718,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, "dependencies": { "wrappy": "1" } @@ -3663,6 +3737,97 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/openapi-default-setter": { + "version": "12.1.3", + "resolved": "https://registry.npmjs.org/openapi-default-setter/-/openapi-default-setter-12.1.3.tgz", + "integrity": "sha512-wHKwvEuOWwke5WcQn8pyCTXT5WQ+rm9FpJmDeEVECEBWjEyB/MVLYfXi+UQeSHTTu2Tg4VDHHmzbjOqN6hYeLQ==", + "dependencies": { + "openapi-types": "^12.1.3" + } + }, + "node_modules/openapi-framework": { + "version": "12.1.3", + "resolved": "https://registry.npmjs.org/openapi-framework/-/openapi-framework-12.1.3.tgz", + "integrity": "sha512-p30PHWVXda9gGxm+t/1X2XvEcufW1YhzeDQwc5SsgDnBXt8gkuu1SwrioGJ66wxVYEzfSRTTf/FMLhI49ut8fQ==", + "dependencies": { + "difunc": "0.0.4", + "fs-routes": "^12.1.3", + "glob": "*", + "is-dir": "^1.0.0", + "js-yaml": "^3.10.0", + "openapi-default-setter": "^12.1.3", + "openapi-request-coercer": "^12.1.3", + "openapi-request-validator": "^12.1.3", + "openapi-response-validator": "^12.1.3", + "openapi-schema-validator": "^12.1.3", + "openapi-security-handler": "^12.1.3", + "openapi-types": "^12.1.3", + "ts-log": "^2.1.4" + } + }, + "node_modules/openapi-jsonschema-parameters": { + "version": "12.1.3", + "resolved": "https://registry.npmjs.org/openapi-jsonschema-parameters/-/openapi-jsonschema-parameters-12.1.3.tgz", + "integrity": "sha512-aHypKxWHwu2lVqfCIOCZeJA/2NTDiP63aPwuoIC+5ksLK5/IQZ3oKTz7GiaIegz5zFvpMDxDvLR2DMQQSkOAug==", + "dependencies": { + "openapi-types": "^12.1.3" + } + }, + "node_modules/openapi-request-coercer": { + "version": "12.1.3", + "resolved": "https://registry.npmjs.org/openapi-request-coercer/-/openapi-request-coercer-12.1.3.tgz", + "integrity": "sha512-CT2ZDhBmAZpHhAzHhEN+/J5oMK3Ds99ayLLdXh2Aw1DCcn72EM8VuIGVwG5fSjvkMsgtn7FgltFosHqeM6PRFQ==", + "dependencies": { + "openapi-types": "^12.1.3", + "ts-log": "^2.1.4" + } + }, + "node_modules/openapi-request-validator": { + "version": "12.1.3", + "resolved": "https://registry.npmjs.org/openapi-request-validator/-/openapi-request-validator-12.1.3.tgz", + "integrity": "sha512-HW1sG00A9Hp2oS5g8CBvtaKvRAc4h5E4ksmuC5EJgmQ+eAUacL7g+WaYCrC7IfoQaZrjxDfeivNZUye/4D8pwA==", + "dependencies": { + "ajv": "^8.3.0", + "ajv-formats": "^2.1.0", + "content-type": "^1.0.4", + "openapi-jsonschema-parameters": "^12.1.3", + "openapi-types": "^12.1.3", + "ts-log": "^2.1.4" + } + }, + "node_modules/openapi-response-validator": { + "version": "12.1.3", + "resolved": "https://registry.npmjs.org/openapi-response-validator/-/openapi-response-validator-12.1.3.tgz", + "integrity": "sha512-beZNb6r1SXAg1835S30h9XwjE596BYzXQFAEZlYAoO2imfxAu5S7TvNFws5k/MMKMCOFTzBXSjapqEvAzlblrQ==", + "dependencies": { + "ajv": "^8.4.0", + "openapi-types": "^12.1.3" + } + }, + "node_modules/openapi-schema-validator": { + "version": "12.1.3", + "resolved": "https://registry.npmjs.org/openapi-schema-validator/-/openapi-schema-validator-12.1.3.tgz", + "integrity": "sha512-xTHOmxU/VQGUgo7Cm0jhwbklOKobXby+/237EG967+3TQEYJztMgX9Q5UE2taZKwyKPUq0j11dngpGjUuxz1hQ==", + "dependencies": { + "ajv": "^8.1.0", + "ajv-formats": "^2.0.2", + "lodash.merge": "^4.6.1", + "openapi-types": "^12.1.3" + } + }, + "node_modules/openapi-security-handler": { + "version": "12.1.3", + "resolved": "https://registry.npmjs.org/openapi-security-handler/-/openapi-security-handler-12.1.3.tgz", + "integrity": "sha512-25UTAflxqqpjCLrN6rRhINeM1L+MCDixMltiAqtBa9Zz/i7UkWwYwdzqgZY3Cx3vRZElFD09brYxo5VleeP3HQ==", + "dependencies": { + "openapi-types": "^12.1.3" + } + }, + "node_modules/openapi-types": { + "version": "12.1.3", + "resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-12.1.3.tgz", + "integrity": "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==" + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -3753,7 +3918,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -3886,6 +4050,14 @@ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "engines": { + "node": ">=6" + } + }, "node_modules/pure-rand": { "version": "6.0.4", "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.4.tgz", @@ -3953,6 +4125,14 @@ "node": ">=0.10.0" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -4171,8 +4351,7 @@ "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, "node_modules/stack-utils": { "version": "2.0.6", @@ -4389,6 +4568,25 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/swagger-ui-dist": { + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.12.0.tgz", + "integrity": "sha512-Rt1xUpbHulJVGbiQjq9yy9/r/0Pg6TmpcG+fXTaMePDc8z5WUw4LfaWts5qcNv/8ewPvBIbY7DKq7qReIKNCCQ==" + }, + "node_modules/swagger-ui-express": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/swagger-ui-express/-/swagger-ui-express-5.0.0.tgz", + "integrity": "sha512-tsU9tODVvhyfkNSvf03E6FAk+z+5cU3lXAzMy6Pv4av2Gt2xA0++fogwC4qo19XuFf6hdxevPuVCSKFuMHJhFA==", + "dependencies": { + "swagger-ui-dist": ">=5.0.0" + }, + "engines": { + "node": ">= v0.10.32" + }, + "peerDependencies": { + "express": ">=4.0.0 || >=5.0.0-beta" + } + }, "node_modules/tdigest": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.2.tgz", @@ -4447,6 +4645,11 @@ "node": ">=0.6" } }, + "node_modules/ts-log": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/ts-log/-/ts-log-2.2.5.tgz", + "integrity": "sha512-PGcnJoTBnVGy6yYNFxWVNkdcAuAMstvutN9MgDJIV6L0oG8fB+ZNNy1T+wJzah8RPGor1mZuPQkVfXNDpy9eHA==" + }, "node_modules/type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", @@ -4523,6 +4726,14 @@ "browserslist": ">= 4.21.0" } }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, "node_modules/url-value-parser": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/url-value-parser/-/url-value-parser-2.2.0.tgz", @@ -4605,8 +4816,7 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/write-file-atomic": { "version": "4.0.2", @@ -4636,6 +4846,17 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, + "node_modules/yaml": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.1.tgz", + "integrity": "sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", From 789b3f2f5781074503f8bd8ed6a56f73a2e7f9e5 Mon Sep 17 00:00:00 2001 From: Augusto <49859508+augustocristian@users.noreply.github.com> Date: Sun, 17 Mar 2024 22:04:35 +0100 Subject: [PATCH 19/44] Adding some examples to the OpenAPI spec (#19) --- gatewayservice/openapi.yaml | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/gatewayservice/openapi.yaml b/gatewayservice/openapi.yaml index c253e705..67bffccb 100644 --- a/gatewayservice/openapi.yaml +++ b/gatewayservice/openapi.yaml @@ -23,12 +23,37 @@ paths: username: type: string description: User ID. + example: student password: type: string description: User password. + example: pass responses: '200': description: User added successfully. + content: + application/json: + schema: + type: object + properties: + username: + type: string + description: User ID + password: + type: string + description: Hashed password + example: $2b$10$ZKdNYLWFQxzt5Rei/YTc/OsZNi12YiWz30JeUFHNdAt7MyfmkTuvC + _id: + type: string + description: Identification + example: 65f756db3fa22d227a4b7c7d + createdAt: + type: string + description: Creation date. + example: '2024-03-17T20:47:23.935Z' + ___v: + type: integer + example: '0' '400': description: Failed to add user. content: @@ -39,6 +64,7 @@ paths: error: type: string description: Error information. + example: getaddrinfo EAI_AGAIN mongodb /health: get: summary: Check the health status of the service. @@ -54,6 +80,7 @@ paths: status: type: string description: Health status. + example: OK /login: post: summary: Log in to the system. @@ -68,9 +95,11 @@ paths: username: type: string description: User ID. + example: student password: type: string description: User password. + example: pass responses: '200': description: Login successful. Returns user token, username, and creation date. @@ -82,12 +111,15 @@ paths: token: type: string description: User token. + example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI2NWY3NTZkYjNmYTIyZDIyN2E0YjdjN2QiLCJpYXQiOjE3MTA3MDg3NDUsImV4cCI6MTcxMDcxMjM0NX0.VMG_5DOyQ4GYlJQRcu1I6ICG1IGzuo2Xuei093ONHxw username: type: string description: Username. + example: student createdAt: type: string description: Creation date. + example: '2024-03-17T20:47:23.935Z' '401': description: Invalid credentials. content: @@ -97,7 +129,8 @@ paths: properties: error: type: string - description: Invalid Credentials. + description: Shows the error info.. + example: Invalid credentials '500': description: Internal server error. content: @@ -108,3 +141,4 @@ paths: error: type: string description: Error information. + example: Internal Server Error From 7c88c7ee6b75e92b9578cfd38c7fc8ba7993ed81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Gonz=C3=A1lez?= Date: Mon, 18 Mar 2024 09:47:05 +0100 Subject: [PATCH 20/44] Fixing OpenAPI E2E Tests - Reemplace the host IP for production in the specification file - Changed the routes to avoid Fnotfound during the E2E test suite execution --- .github/workflows/release.yml | 4 ++++ gatewayservice/gateway-service.js | 19 ++++++++++++------- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cb96d06b..48a92d37 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -102,6 +102,10 @@ jobs: needs: [e2e-tests] steps: - uses: actions/checkout@v4 + - name: Update OpenAPI configuration + run: | + DEPLOY_HOST=${{ secrets.DEPLOY_HOST }} + sed -i "s/SOMEIP/${DEPLOY_HOST}/g" gatewayservice/openapi.yaml - name: Publish to Registry uses: elgohr/Publish-Docker-Github-Action@v5 with: diff --git a/gatewayservice/gateway-service.js b/gatewayservice/gateway-service.js index 84d7d8fa..444b71dc 100644 --- a/gatewayservice/gateway-service.js +++ b/gatewayservice/gateway-service.js @@ -47,15 +47,20 @@ app.post('/adduser', async (req, res) => { }); // Read the OpenAPI YAML file synchronously -const file = fs.readFileSync('./openapi.yaml', 'utf8'); +openapiPath='./openapi.yaml' +if (fs.existsSync(openapiPath)) { + const file = fs.readFileSync(openapiPath, 'utf8'); -// Parse the YAML content into a JavaScript object representing the Swagger document -const swaggerDocument = YAML.parse(file); + // Parse the YAML content into a JavaScript object representing the Swagger document + const swaggerDocument = YAML.parse(file); -// Serve the Swagger UI documentation at the '/api-doc' endpoint -// This middleware serves the Swagger UI files and sets up the Swagger UI page -// It takes the parsed Swagger document as input -app.use('/api-doc', swaggerUi.serve, swaggerUi.setup(swaggerDocument)); + // Serve the Swagger UI documentation at the '/api-doc' endpoint + // This middleware serves the Swagger UI files and sets up the Swagger UI page + // It takes the parsed Swagger document as input + app.use('/api-doc', swaggerUi.serve, swaggerUi.setup(swaggerDocument)); +} else { + console.log("Not configuring OpenAPI. Configuration file not present.") +} // Start the gateway service const server = app.listen(port, () => { From 98b87b98a8ee796c6391e54ea0ff6df75dd1ef23 Mon Sep 17 00:00:00 2001 From: coral2742 Date: Mon, 18 Mar 2024 14:17:46 +0100 Subject: [PATCH 21/44] =?UTF-8?q?:sparkles:=20Temporizador=20a=C3=B1adido?= =?UTF-8?q?=20con=20cuenta=20atr=C3=A1s=20de=2020=20segundos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- webapp/src/Timer.css | 71 ++++++++++++++++++++++++++++++++++ webapp/src/components/Game.js | 35 +++++++---------- webapp/src/components/Juego.js | 33 ---------------- webapp/src/components/Timer.js | 37 ++++++++++++++++++ 4 files changed, 121 insertions(+), 55 deletions(-) create mode 100644 webapp/src/Timer.css delete mode 100644 webapp/src/components/Juego.js create mode 100644 webapp/src/components/Timer.js diff --git a/webapp/src/Timer.css b/webapp/src/Timer.css new file mode 100644 index 00000000..2fe296ea --- /dev/null +++ b/webapp/src/Timer.css @@ -0,0 +1,71 @@ +.Timer { + font-family: sans-serif; + text-align: center; + height: 50vh; + display: flex; + justify-content: center; + align-items: center; + } + + .Timer .container { + position: relative; + transform: scale(200%); + } + + .Timer .text { + position: absolute; + color: #007bff; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + font-weight: bold; + font-size: 36px; + } + + .Timer .container svg { + width: 150px; + height: 150px; + /* background-color: red; */ + transform: rotate(-90deg); + } + + .Timer .container svg circle { + fill: transparent; + stroke: #415262; + stroke-width: 4; + transform: translate(5px, 5px); + transition: all 2s; + z-index: 0; + } + + .Timer .container svg circle:nth-child(2) { + fill: transparent; + stroke: #007bff; + stroke-width: 6; + stroke-dasharray: 440; + /* stroke-dashoffset: 0; */ + transition: all 0.1s; + } + + .Timer .dot { + position: absolute; + width: 100%; + height: 100%; + /* background-color: rgba(0, 128, 0, 0.281); */ + transition: all 0.1s; + z-index: 9999; + } + + .Timer .dot::before { + content: ""; + width: 20px; + height: 20px; + background-color: #007bff; + z-index: 1000; + position: absolute; + border-radius: 10px; + top: -2px; + transform: translate(-10px); + box-shadow: 0 0 20px 4px #007bff; + } + \ No newline at end of file diff --git a/webapp/src/components/Game.js b/webapp/src/components/Game.js index dedadb54..93eddc2a 100644 --- a/webapp/src/components/Game.js +++ b/webapp/src/components/Game.js @@ -1,9 +1,12 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, StrictMode } from 'react'; import axios from 'axios'; import { Container, Typography, Button, Paper, TimerIcon } from '@mui/material'; import './Game.css'; +import '../Timer.css'; +import Timer from './Timer'; + const colorPreguntas= 'rgba(51, 139, 173, 0.764)'; const colorOnMousePreguntas= 'rgba(28, 84, 106, 0.764)'; @@ -19,23 +22,12 @@ const Game = () => { const [questionCounter, setQuestionCounter] = useState(0); const [incorrectCounter, setIncorrectCounter] = useState(0); - // Temporizador - const [seconds, setSeconds] = useState(120); // 2 minutes - useEffect(() => { handleShowQuestion(); }, []); - - useEffect(() => { - const intervalId = setInterval(() => { - setSeconds(prevSeconds => prevSeconds - 1); - }, 1000); - - return () => clearInterval(intervalId); - }, []); // This method will call the create question service const handleShowQuestion = async () => { @@ -121,6 +113,14 @@ const Game = () => { ))} + + +
+ + + +
+
-
- - -
- Time Remaining: {Math.floor(seconds / 60)}:{(seconds % 60).toLocaleString('en-US', { minimumIntegerDigits: 2 })} -
-
+ - {/* */}
diff --git a/webapp/src/components/Juego.js b/webapp/src/components/Juego.js deleted file mode 100644 index b9a524a4..00000000 --- a/webapp/src/components/Juego.js +++ /dev/null @@ -1,33 +0,0 @@ -// Juego.js -import React from 'react'; -import { Button, Typography, Container, Paper } from '@mui/material'; - -function Juego() { - return ( - - - - Saber y Ganar Juego - - - Pregunta: ¿Cuál es la capital de Francia? - - {/* Botones de opción */} - - - - - - - ); -} - -export default Juego; diff --git a/webapp/src/components/Timer.js b/webapp/src/components/Timer.js new file mode 100644 index 00000000..bb68c6e1 --- /dev/null +++ b/webapp/src/components/Timer.js @@ -0,0 +1,37 @@ +import { useEffect, useState } from "react"; +import "../Timer.css"; + +export default function Timer() { + const [loadingPercent, setLoadingPercent] = useState(0); + const [dot, setDot] = useState(0); + const [text, setText] = useState("20"); + + useEffect(() => { + const interval = setInterval(() => { + const secs = 20 - (new Date().getSeconds() % 21); + + const currentLoadingPercent = 440 - 440 * (secs / 20); + setLoadingPercent(currentLoadingPercent); + + const currentDot = 360 * (secs / 20); + setDot(currentDot); + + setText(secs >= 10 ? secs : `0${secs}`); + }, 1000); + + return () => clearInterval(interval); + }, []); + + return ( +
+
+
{text}
+
+ + + + +
+
+ ); +} From 997e0bcaae2c57c1f0b5927f6f726ec0ee83a5b2 Mon Sep 17 00:00:00 2001 From: Jose Emilio Labra Gayo Date: Tue, 19 Mar 2024 06:40:36 +0100 Subject: [PATCH 22/44] Small local changes --- README.md | 3 ++- webapp/README.md | 11 +++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 806935e5..e78fdd6c 100644 --- a/README.md +++ b/README.md @@ -117,4 +117,5 @@ This action uses three secrets that must be configured in the repository: - DEPLOY_USER: user with permission to execute the commands in the remote machine. - DEPLOY_KEY: key to authenticate the user in the remote machine. -Note that this action logs in the remote machine and downloads the docker-compose file from the repository and launches it. Obviously, previous actions have been executed which have uploaded the docker images to the GitHub Packages repository. +Note that this action logs in the remote machine and downloads the docker-compose file from the repository and launches it. +Obviously, previous actions have been executed which have uploaded the docker images to the GitHub Packages repository. diff --git a/webapp/README.md b/webapp/README.md index 9568101e..33dd89a5 100644 --- a/webapp/README.md +++ b/webapp/README.md @@ -108,14 +108,21 @@ E2E tests are maybe the most difficult part to integrate in our system. We have In this project, the E2E testing user stories are defined using Cucumber. Cucumber uses a language called Gherkin to define the user stories. You can find the example in the `features` directory. Then, the actual tests are in the folder `steps`. We are going to configure jest to execute only the tests of this directory (check the `jest.config.ts` file in the `e2e` directory). -The E2E tests have two extra difficulties. The first one, we need a browser to perform the tests as if the user was using the application. For this matter, we use `jest-puppeteer` that will launch a Chromium instance for running the tests. The browser is started in the `beforeAll` function. Note that the browser is launched in a headless mode. This is necessary for the tests to run in the CI environment. If you want to debug the tests you can always turn this feature off. The second problem is that we need all our services at the same time to be able to run the tests. For achieving this, we are going to use the package `start-server-and-test`. This package, allows us to launch multiple servers and then run the tests. No need for any configuration. We can configure it straight in the `package.json` file: +The E2E tests have two extra difficulties. The first one, we need a browser to perform the tests as if the user was using the application. +For this matter, we use `jest-puppeteer` that will launch a Chromium instance for running the tests. +The browser is started in the `beforeAll` function. Note that the browser is launched in a headless mode. +This is necessary for the tests to run in the CI environment. If you want to debug the tests you can always turn this feature off. +The second problem is that we need all our services at the same time to be able to run the tests. +For achieving this, we are going to use the package `start-server-and-test`. +This package, allows us to launch multiple servers and then run the tests. +No need for any configuration. We can configure it straight in the `package.json` file: ```json "test:e2e": "start-server-and-test 'node e2e/test-environment-setup.js' http://localhost:8000/health prod 3000 \"cd e2e && jest\"", ``` -The package accepts pairs of parameters (launch a server and an URL to check if it is running. It also accepts npm commands (for instance prod, for the webapp, that will run `npm run prod`). The last parameter of the task will be launching Jest to run the E2E tests. +The package accepts pairs of parameters (launch a server and an URL to check if it is running. It also accepts npm commands (for instance prod, for the webapp, that will run `npm run prod`). The last parameter of the task will be launching Jest to run the e2e tests. Note that we are handling all the setup for the auth and user microservices using the file `test-environment-setup.js`. This file has the code needed to run everything, including an in-memory Mongo database to be able to execute the tests. From 8d15121ee0a23c84b91701f76ded2272014deecf Mon Sep 17 00:00:00 2001 From: uo264915 Date: Sun, 24 Mar 2024 12:38:45 +0100 Subject: [PATCH 23/44] =?UTF-8?q?Sincronizaci=C3=B3n=20con=20develop=20(24?= =?UTF-8?q?=20Marzo)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- webapp/src/components/Game.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/webapp/src/components/Game.js b/webapp/src/components/Game.js index dedadb54..f5126220 100644 --- a/webapp/src/components/Game.js +++ b/webapp/src/components/Game.js @@ -18,6 +18,8 @@ const Game = () => { const [questionCounter, setQuestionCounter] = useState(0); const [incorrectCounter, setIncorrectCounter] = useState(0); + + const [numberOfQuestions, setNumberOfQuestions] = useState(10); // Temporizador const [seconds, setSeconds] = useState(120); // 2 minutes @@ -84,13 +86,20 @@ const Game = () => { button.onmouse = null; }); + // FIN DE LA PARTIDA + finishGame(); + // Cambiar a la siguiente pregunta después de 3 segundos setTimeout(() => { handleShowQuestion(); }, 1500); - + } + const finishGame = () => { + if ((correctCounter + incorrectCounter) == numberOfQuestions){ + + } } const incrementCorrect = () => { From 492a21608c7115ce23217315eee6ba0758082457 Mon Sep 17 00:00:00 2001 From: uo264915 Date: Thu, 28 Mar 2024 01:05:55 +0100 Subject: [PATCH 24/44] =?UTF-8?q?[APP]=20Implementaci=C3=B3n=20interfaz=20?= =?UTF-8?q?de=20MainPage=20Arquisoft/wiq=5Fes2b#76=20[APP]=20Implementaci?= =?UTF-8?q?=C3=B3n=20CSS=20com=C3=BAn=20para=20todas=20las=20pantallas=20A?= =?UTF-8?q?rquisoft/wiq=5Fes2b#73=20[APP]=20Configurar=20el=20fin=20de=20p?= =?UTF-8?q?artida=20(Cuando=20se=20llega=20a=20X=20preguntas)=20=20Arquiso?= =?UTF-8?q?ft/wiq=5Fes2b#72?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- webapp/src/components/Game.css | 9 +++ webapp/src/components/Game.js | 89 ++++++++++++++++++++++++++---- webapp/src/components/MainPage.css | 12 ++++ webapp/src/components/MainPage.js | 3 +- 4 files changed, 102 insertions(+), 11 deletions(-) create mode 100644 webapp/src/components/MainPage.css diff --git a/webapp/src/components/Game.css b/webapp/src/components/Game.css index 1e4d4c29..dca78363 100644 --- a/webapp/src/components/Game.css +++ b/webapp/src/components/Game.css @@ -17,3 +17,12 @@ button[title="btnsPreg"]{ background-color: rgba(41, 120, 152, 0.764); } +button[title="puntuacion"]:disabled{ + margin: 1em; + background-color: rgba(31, 60, 134, 0.764); + color: white; + padding-top: 0.4em; + padding-bottom: 0.2em; + font-size: 1.5em; +} + diff --git a/webapp/src/components/Game.js b/webapp/src/components/Game.js index b76e69a7..c0b86be1 100644 --- a/webapp/src/components/Game.js +++ b/webapp/src/components/Game.js @@ -20,6 +20,9 @@ const Game = () => { const [incorrectCounter, setIncorrectCounter] = useState(0); const [numberOfQuestions, setNumberOfQuestions] = useState(10); + const [questionsToAnswer, setQuestionsToAnswer] = useState(10); + const [isFinished, setFinished] = useState(false); + const [percentage, setPercentage] = useState(0); // Temporizador const [seconds, setSeconds] = useState(120); // 2 minutes @@ -38,6 +41,13 @@ const Game = () => { return () => clearInterval(intervalId); }, []); + + + useEffect(() => { + if (isGameFinished()){ + finishGame(); + } + }, [correctCounter]); // This method will call the create question service const handleShowQuestion = async () => { @@ -56,7 +66,15 @@ const Game = () => { button.onmouse = colorOnMousePreguntas; }); + // FIN DE LA PARTIDA + if (isGameFinished()){ + setFinished(true); + } + + incrementQuestion(); + + }catch (error){ console.error('Error:', error); } @@ -85,30 +103,55 @@ const Game = () => { button.disabled = true; button.onmouse = null; }); + + + decrementQuestionsToAnswer(); + + + if (!isFinished){ + // Cambiar a la siguiente pregunta después de 3 segundos + setTimeout(() => { + handleShowQuestion(); + }, 1500); + } + + } - // FIN DE LA PARTIDA - finishGame(); + const isGameFinished = () => { + return questionCounter >= numberOfQuestions; + } - // Cambiar a la siguiente pregunta después de 3 segundos - setTimeout(() => { - handleShowQuestion(); - }, 1500); + const finishGame = () => { + const buttons = document.querySelectorAll('button[title="btnsPreg"]'); + buttons.forEach(button => { + button.disabled = true; + button.onmouse = null; + }); + console.log("finishGame " + correctCounter); + var correctas = (correctCounter / numberOfQuestions); + setPercentage(correctas * 100); } const incrementCorrect = () => { - setCorrectCounter(correctCounter + 1); + setCorrectCounter(correct => correct + 1); }; const incrementIncorrect = () => { - setIncorrectCounter(incorrectCounter + 1); + setIncorrectCounter(incorrect => incorrect + 1); + } + + const decrementQuestionsToAnswer = () => { + setQuestionsToAnswer(toAnswer => toAnswer - 1); } const incrementQuestion = () => { - setQuestionCounter(questionCounter + 1); + setQuestionCounter(qc => qc + 1); } return ( + + {!isFinished && ( Saber y Ganar Juego @@ -124,14 +167,23 @@ const Game = () => { ))} + )} + {!isFinished && ( + + )} + {!isFinished && ( - + )} + {!isFinished && ( + )}
@@ -142,6 +194,23 @@ const Game = () => {
+ + + {isFinished && ( +
+ + + Partida finalizada. ¡Gracias por jugar! + +
+ +
+
+
+ )} + {/* From 78acdb32fda006ce5720f22f33b2c0b20c7aa000 Mon Sep 17 00:00:00 2001 From: uo264915 Date: Sat, 30 Mar 2024 14:03:43 +0100 Subject: [PATCH 27/44] Finalizacion del juego y mostrar puntuacion [APP] Configurar el fin de partida (Cuando se llega a X preguntas) Arquisoft/wiq_es2b#72 --- webapp/src/components/Game.js | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/webapp/src/components/Game.js b/webapp/src/components/Game.js index de9b0ebf..2d8815b0 100644 --- a/webapp/src/components/Game.js +++ b/webapp/src/components/Game.js @@ -43,9 +43,10 @@ const Game = () => { useEffect(() => { - if (isGameFinished()){ + if (isGameFinished() && !isFinished){ finishGame(); - } + setFinished(true) +; } }, [correctCounter]); // This method will call the create question service @@ -66,7 +67,8 @@ const Game = () => { }); // FIN DE LA PARTIDA - if (isGameFinished()){ + if (isGameFinished() && !isFinished){ + finishGame(); setFinished(true); } @@ -125,8 +127,14 @@ const Game = () => { button.onmouse = null; }); console.log("finishGame " + correctCounter); - var correctas = (correctCounter / numberOfQuestions); - setPercentage(correctas * 100); + var correctas = (correctCounter / numberOfQuestions) * 100; + console.log("corr1 " + correctas); + if (!Number.isInteger(percentage)){ + correctas = correctas.toFixed(2); + console.log("dentro " + correctas); + } + console.log("corr2 " + correctas); + setPercentage(correctas); } const incrementCorrect = () => { @@ -200,7 +208,7 @@ const Game = () => {
From 7d11d8ad4302b54bf9276248a44913fc8b31e718 Mon Sep 17 00:00:00 2001 From: Raymond Debasa Peralta Date: Mon, 1 Apr 2024 11:24:03 +0200 Subject: [PATCH 28/44] Historial de usuario implementado + errores varios --- gatewayservice/gateway-service.js | 24 ++++++ users/userservice/playedGame-model.js | 17 +++++ users/userservice/question-model.js | 11 +++ users/userservice/user-model.js | 1 + users/userservice/user-service.js | 77 +++++++++++++++++-- webapp/src/components/Game.js | 62 ++++++++++++++- webapp/src/components/HistoricalUserData.js | 85 +++++++++++++++++++++ webapp/src/components/Login.js | 2 +- webapp/src/components/MainPage.js | 10 ++- webapp/src/index.js | 2 + 10 files changed, 280 insertions(+), 11 deletions(-) create mode 100644 users/userservice/playedGame-model.js create mode 100644 users/userservice/question-model.js create mode 100644 webapp/src/components/HistoricalUserData.js diff --git a/gatewayservice/gateway-service.js b/gatewayservice/gateway-service.js index a20b94cc..c152dec2 100644 --- a/gatewayservice/gateway-service.js +++ b/gatewayservice/gateway-service.js @@ -41,6 +41,28 @@ app.post('/adduser', async (req, res) => { } }); +app.post('/addgame', async (req, res) => { + try { + const userResponse = await axios.post(userServiceUrl+'/addgame', req.body); + res.json(userResponse.data); + } catch (error) { + res.status(error.response.status).json({ error: error.response.data.error }); + } +}); + + +app.get('/getgamehistory/:username', async (req, res) => { + try { + const username = req.params.username; + const userResponse = await axios.get(`${userServiceUrl}/getgamehistory/${username}`); + res.json(userResponse.data); + } catch (error) { + res.status(error.response.status).json({ error: error.response.data.error }); + } +}); + + + app.post('/createquestion', async (req, res) => { try { // Create a petition to the URL (le llegará a creation-service.js) with the option /createquestion and the req.body params @@ -63,6 +85,8 @@ app.post('/getquestionshistory', async (req, res) => { } }); + + // Start the gateway service const server = app.listen(port, () => { console.log(`Gateway Service listening at http://localhost:${port}`); diff --git a/users/userservice/playedGame-model.js b/users/userservice/playedGame-model.js new file mode 100644 index 00000000..ef3f07cd --- /dev/null +++ b/users/userservice/playedGame-model.js @@ -0,0 +1,17 @@ +const mongoose = require('mongoose'); + +const gameSchema = new mongoose.Schema({ + username: { type: String, required: true }, + duration: Number, + questions: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Question' }], + date: { type: Date, default: Date.now } , + percentage: Number, + totalQuestions: Number, + correctAnswers: Number, + incorrectAnswers: Number +}); + +const Game = mongoose.model('Game', gameSchema); + +module.exports = Game; + diff --git a/users/userservice/question-model.js b/users/userservice/question-model.js new file mode 100644 index 00000000..80b3edcd --- /dev/null +++ b/users/userservice/question-model.js @@ -0,0 +1,11 @@ +const mongoose = require('mongoose'); + +const questionSchema = new mongoose.Schema({ + question: String, + correctAnswer: String, + userAnswer: String +}); + +const Question = mongoose.model('Question', questionSchema); + +module.exports = Question; diff --git a/users/userservice/user-model.js b/users/userservice/user-model.js index 71d81b5f..a1bd2e1b 100644 --- a/users/userservice/user-model.js +++ b/users/userservice/user-model.js @@ -4,6 +4,7 @@ const userSchema = new mongoose.Schema({ username: { type: String, required: true, + unique: true }, password: { type: String, diff --git a/users/userservice/user-service.js b/users/userservice/user-service.js index be958427..90115523 100644 --- a/users/userservice/user-service.js +++ b/users/userservice/user-service.js @@ -4,6 +4,8 @@ const mongoose = require('mongoose'); const bcrypt = require('bcrypt'); const bodyParser = require('body-parser'); const User = require('./user-model') +const Game = require('./playedGame-model') +const Question = require('./question-model') const app = express(); const port = 8001; @@ -20,9 +22,9 @@ mongoose.connect(mongoUri); // Function to validate required fields in the request body function validateRequiredFields(req, requiredFields) { for (const field of requiredFields) { - if (!(field in req.body)) { - throw new Error(`Missing required field: ${field}`); - } + if (!(field in req.body)) { + throw new Error(`Missing required field: ${field}`); + } } } @@ -42,17 +44,78 @@ app.post('/adduser', async (req, res) => { await newUser.save(); res.json(newUser); } catch (error) { - res.status(400).json({ error: error.message }); - }}); + res.status(400).json({ + error: error.message + }); + } +}); + +app.post('/addgame', async (req, res) => { + try { + // Obtener los datos del juego desde el cuerpo de la solicitud + const gameData = req.body; + + // Convertir las preguntas del juego en ObjectId + const questionIds = await Promise.all(gameData.questions.map(async (question) => { + const existingQuestion = await Question.findOne({ + question: question.question, + correctAnswer: question.correctAnswer, + userAnswer: question.userAnswer + }); + if (existingQuestion) { + return existingQuestion._id; + } else { + const newQuestion = new Question(question); + await newQuestion.save(); + return newQuestion._id; + } + })); + + // Reemplazar las preguntas en el juego con sus ObjectId + gameData.questions = questionIds; + + // Crear una nueva instancia del modelo de juego con los datos proporcionados + const newGame = new Game(gameData); + + // Guardar el nuevo juego en la base de datos + await newGame.save(); + + // Enviar una respuesta de éxito + res.status(200).json({ message: "Partida guardada exitosamente" }); + } catch (error) { + // Manejar errores y enviar una respuesta de error con el mensaje de error + console.error("Error al guardar el juego:", error); + res.status(400).json({ error: error.message }); + } +}); + + + +app.get('/getgamehistory/:username', async (req, res) => { + try { + const username = req.params.username; + console.log("se esta intentnado encontrar el hisotrial del usuario "+username); + // Buscar las partidas asociadas al nombre de usuario proporcionado + const games = await Game.find({ username }); + console.log("se encontro para "+username+" estos juegos " +games); + res.json(games); + } catch (error) { + res.status(400).json({ + error: error.message + }); + } +}); const server = app.listen(port, () => { - console.log(`User Service listening at http://localhost:${port}`); + console.log(`User Service listening at http://localhost:${port}`); }); + + // Listen for the 'close' event on the Express.js server server.on('close', () => { // Close the Mongoose connection mongoose.connection.close(); - }); +}); module.exports = server \ No newline at end of file diff --git a/webapp/src/components/Game.js b/webapp/src/components/Game.js index 2d8815b0..1b781cea 100644 --- a/webapp/src/components/Game.js +++ b/webapp/src/components/Game.js @@ -1,6 +1,7 @@ import React, { useState, useEffect } from 'react'; import axios from 'axios'; import { Container, Typography, Button, Paper} from '@mui/material'; +import { useNavigate, useParams } from 'react-router-dom'; import './Game.css'; @@ -8,6 +9,7 @@ const colorPreguntas= 'rgba(51, 139, 173, 0.764)'; const colorOnMousePreguntas= 'rgba(28, 84, 106, 0.764)'; const Game = () => { + const navigate = useNavigate(); const apiEndpoint = process.env.REACT_APP_API_ENDPOINT || 'http://localhost:8000'; const [questionObject, setQuestionObject] = useState(''); @@ -119,6 +121,30 @@ const Game = () => { const isGameFinished = () => { return questionCounter >= numberOfQuestions; } + const handleMainPage = () => { + let path= '/mainPage'; + navigate(path); +}; + +const getQuestions = () => { + + const questionsList = [ + { + question: '¿Cuál es la capital de Francia?', + correctAnswer: 'París', + userAnswer: 'París' + }, + { + question: '¿Cuál es el río más largo del mundo?', + correctAnswer: 'El río Amazonas', + userAnswer: 'Hola' + }, + + ]; + + return questionsList; +}; + const finishGame = () => { const buttons = document.querySelectorAll('button[title="btnsPreg"]'); @@ -135,8 +161,36 @@ const Game = () => { } console.log("corr2 " + correctas); setPercentage(correctas); + const username=localStorage.getItem('username'); + const newGame = { + username: username, + duration: seconds, + questions: getQuestions() , + percentage: correctas, + totalQuestions: numberOfQuestions, + correctAnswers: correctCounter, + incorrectAnswers: numberOfQuestions-correctCounter + }; + console.log("Se va a guardar la siguiente partida:"); + console.log("Username:", newGame.username); + console.log("Duración:", newGame.duration); + console.log("Preguntas:", newGame.questions); + console.log("Porcentaje de Aciertos:", newGame.percentage); + console.log("Número Total de Preguntas:", newGame.totalQuestions); + console.log("Número de Respuestas Correctas:", newGame.correctAnswers); + console.log("Número de Respuestas Incorrectas:", newGame.incorrectAnswers); + + + + axios.post(`${apiEndpoint}/addgame`, newGame) + .then(response => { + console.log("Respuesta del servidor:", response.data); + }) + .catch(error => { + console.error("Error al enviar la solicitud:", error); + }); } - + const incrementCorrect = () => { setCorrectCounter(correct => correct + 1); }; @@ -189,7 +243,7 @@ const Game = () => { Incorrectas: {incorrectCounter} )} - + {!isFinished && (
@@ -197,6 +251,7 @@ const Game = () => { Time Remaining: {Math.floor(seconds / 60)}:{(seconds % 60).toLocaleString('en-US', { minimumIntegerDigits: 2 })}
+ )} @@ -210,6 +265,9 @@ const Game = () => { + diff --git a/webapp/src/components/HistoricalUserData.js b/webapp/src/components/HistoricalUserData.js new file mode 100644 index 00000000..8dba559f --- /dev/null +++ b/webapp/src/components/HistoricalUserData.js @@ -0,0 +1,85 @@ +import React, { useState } from 'react'; +import axios from 'axios'; +import { useNavigate } from 'react-router-dom'; +import { Container, Button } from '@mui/material'; + +const HistoricalUserData = () => { + const navigate = useNavigate(); + const apiEndpoint = process.env.REACT_APP_API_ENDPOINT || 'http://localhost:8000'; + + const [gameHistory, setGameHistory] = useState([]); + + + const handleLoadHistory = async () => { + try { + const username=localStorage.getItem('username'); + const response = await axios.get(`${apiEndpoint}/getgamehistory/${username}`, {}); + + setGameHistory(response.data); + + console.log("el historial actual es "+gameHistory); + + } catch (error) { + console.error('Error:', error); + } + }; + const handlePreviousPage = async () => { + let path= '/MainPage'; + navigate(path); + } + + + return ( + + + + +
+

Historial de Partidas:

+ + + + + + + + + + + + + {gameHistory.map((game) => ( + + + + + + + + + + {game.questions && game.questions.map((question, index) => ( + + + + ))} + + ))} + +
FechaTiempo de partida (s)Porcentaje de AciertosNúmero de PreguntasNúmero de AciertosNúmero de Fallos
{game.date}{game.duration}{game.percentage}%{game.totalQuestions}{game.correctAnswers}{game.incorrectAnswers}
+

Pregunta {index + 1}: {question.question}

+

Respuesta Correcta: {question.correctAnswer}

+

Respuesta del Usuario: {question.userAnswer}

+

La respuesta fue: {question.correctAnswer === question.userAnswer ? 'Correcta' : 'Incorrecta'}

+
+
+
+ ); + +}; + +export default HistoricalUserData; diff --git a/webapp/src/components/Login.js b/webapp/src/components/Login.js index 0e39f9b6..478b48be 100644 --- a/webapp/src/components/Login.js +++ b/webapp/src/components/Login.js @@ -21,7 +21,7 @@ const Login = () => { const loginUser = async () => { try { await axios.post(`${apiEndpoint}/login`, { username, password }); - + localStorage.setItem('username',username); setLoginSuccess(true); setOpenSnackbar(true); diff --git a/webapp/src/components/MainPage.js b/webapp/src/components/MainPage.js index 09ecef3c..c2ed9596 100644 --- a/webapp/src/components/MainPage.js +++ b/webapp/src/components/MainPage.js @@ -16,6 +16,11 @@ const MainPage = () => { navigate(path); }; + const handleShowHistoricalUserData = () => { + let path= '/HistoricalUserData'; + navigate(path); + }; + return (
@@ -31,7 +36,10 @@ const MainPage = () => { Empezar juego +
diff --git a/webapp/src/index.js b/webapp/src/index.js index 3923d310..9f794123 100644 --- a/webapp/src/index.js +++ b/webapp/src/index.js @@ -7,6 +7,7 @@ import App from './App'; import Game from './components/Game'; import HistoricalData from './components/HistoricalData'; import MainPage from './components/MainPage'; +import HistoricalUserData from './components/HistoricalUserData'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( @@ -17,6 +18,7 @@ root.render( }> }> }> + }> From e80c658add3e53d1661079b0b711d858ee8f0b75 Mon Sep 17 00:00:00 2001 From: uo264915 Date: Mon, 1 Apr 2024 11:36:03 +0200 Subject: [PATCH 29/44] =?UTF-8?q?Implementaci=C3=B3n=20CSS=20de=20Historic?= =?UTF-8?q?alData=20y=20otros=20cambios?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- webapp/src/components/HistoricalData.css | 50 ++++++++++++++++++++ webapp/src/components/HistoricalData.js | 15 +++--- webapp/src/components/HistoricalQuestions.js | 39 +++++++++++++++ webapp/src/components/MainPage.js | 8 ++++ 4 files changed, 105 insertions(+), 7 deletions(-) create mode 100644 webapp/src/components/HistoricalData.css create mode 100644 webapp/src/components/HistoricalQuestions.js diff --git a/webapp/src/components/HistoricalData.css b/webapp/src/components/HistoricalData.css new file mode 100644 index 00000000..1e20a1c4 --- /dev/null +++ b/webapp/src/components/HistoricalData.css @@ -0,0 +1,50 @@ +.contenedor { + display: flex; + flex-direction: column; + align-items: center; +} + +div[title="botones"]{ + display: grid; + grid-template-columns: 1fr 1fr; + align-items: center; + margin-top: 2em; + margin-bottom: 2em; + grid-gap: 2em; +} + +button{ + margin: 1em; + padding: 0.25em; + background-color: rgba(31, 60, 134, 0.764); + color: white; + font-size: 0.75em; +} + +table { + width: 90%; + border-collapse: collapse; + color: black; + } + + th, td { + padding: 0.25em; + text-align: center; + border: 0.1em solid #000; + } + + th[title='pregunta'] { + background-color: rgba(41, 120, 152, 0.764); + } + + th[title='correcta'] { + background-color: rgba(79, 141, 18, 0.726); + } + + th[title='incorrecta'] { + background-color: rgba(230, 72, 72, 0.952); + } + + td{ + background-color: rgba(61, 178, 224, 0.764); + } \ No newline at end of file diff --git a/webapp/src/components/HistoricalData.js b/webapp/src/components/HistoricalData.js index 6e746026..379f4b8b 100644 --- a/webapp/src/components/HistoricalData.js +++ b/webapp/src/components/HistoricalData.js @@ -2,6 +2,7 @@ import axios from 'axios'; import React, { useState} from 'react'; import { useNavigate} from 'react-router-dom'; import { Container, Button} from '@mui/material'; +import './HistoricalData.css'; const HistoricalData = () => { const navigate = useNavigate(); @@ -26,9 +27,9 @@ const HistoricalData = () => { return ( - + -
+
@@ -41,11 +42,11 @@ const HistoricalData = () => { - - - - - + + + + + diff --git a/webapp/src/components/HistoricalQuestions.js b/webapp/src/components/HistoricalQuestions.js new file mode 100644 index 00000000..2e734412 --- /dev/null +++ b/webapp/src/components/HistoricalQuestions.js @@ -0,0 +1,39 @@ +import axios from 'axios'; +import React, { useState} from 'react'; +import { useNavigate} from 'react-router-dom'; +import { Container, Button} from '@mui/material'; + +const HistoricalQuestions = () => { + const navigate = useNavigate(); + const apiEndpoint = process.env.REACT_APP_API_ENDPOINT || 'http://localhost:8000'; + + const [questionsHistory, setQuestionsHistory] = useState([]); + + const handleShowHistory = async () => { + try{ + // It makes a petition to the api and store the response + const response = await axios.post(`${apiEndpoint}/getquestionshistory`, { }); + setQuestionsHistory(response.data); + }catch (error){ + console.error('Error:', error); + } + } + + const handlePreviousPage = async () => { + let path= '/MainPage'; + navigate(path); + } + + return ( + + + +
+ +
+
+ + ); +}; + +export default HistoricalQuestions; \ No newline at end of file diff --git a/webapp/src/components/MainPage.js b/webapp/src/components/MainPage.js index 09ecef3c..ea0152d1 100644 --- a/webapp/src/components/MainPage.js +++ b/webapp/src/components/MainPage.js @@ -16,6 +16,11 @@ const MainPage = () => { navigate(path); }; + const handleShowHistoricalQuestions = () => { + let path= '/HistoricalQuestions'; + navigate(path); + }; + return (
@@ -33,6 +38,9 @@ const MainPage = () => { +
) From b33132f6b801f40c5c9dccffcb5ce72b7d2f70c0 Mon Sep 17 00:00:00 2001 From: Raymond Debasa Peralta Date: Mon, 1 Apr 2024 12:18:20 +0200 Subject: [PATCH 30/44] Ajustes Histotico del usuario --- users/userservice/user-service.js | 6 +-- webapp/src/components/Game.js | 42 ++++++++++++++------- webapp/src/components/HistoricalUserData.js | 12 ++++-- 3 files changed, 39 insertions(+), 21 deletions(-) diff --git a/users/userservice/user-service.js b/users/userservice/user-service.js index 90115523..9f083dba 100644 --- a/users/userservice/user-service.js +++ b/users/userservice/user-service.js @@ -94,10 +94,10 @@ app.post('/addgame', async (req, res) => { app.get('/getgamehistory/:username', async (req, res) => { try { const username = req.params.username; - console.log("se esta intentnado encontrar el hisotrial del usuario "+username); + console.log("Se está intentando encontrar el historial del usuario " + username); // Buscar las partidas asociadas al nombre de usuario proporcionado - const games = await Game.find({ username }); - console.log("se encontro para "+username+" estos juegos " +games); + const games = await Game.find({ username }).populate('questions'); + console.log("Se encontraron los juegos para " + username + ": ", games); res.json(games); } catch (error) { res.status(400).json({ diff --git a/webapp/src/components/Game.js b/webapp/src/components/Game.js index 1b781cea..39a27037 100644 --- a/webapp/src/components/Game.js +++ b/webapp/src/components/Game.js @@ -25,6 +25,11 @@ const Game = () => { const [isFinished, setFinished] = useState(false); const [percentage, setPercentage] = useState(0); + + //para el final de partida + const [gameUserOptions, setGameUserOptions] = useState([]); + const [gameCorrectOptions, setGameCorrectOptions] = useState([]); + const [gameQuestions, setGameQuestions] = useState([]); // Temporizador const [seconds, setSeconds] = useState(120); // 2 minutes @@ -60,6 +65,14 @@ const Game = () => { setQuestionObject(response.data.responseQuestionObject); setCorrectOption(response.data.responseCorrectOption); setAnswerOptions(response.data.responseAnswerOptions); + + //guardar para el final + // Actualizar las preguntas del juego + setGameQuestions(prevQuestions => [...prevQuestions, response.data.responseQuestionObject]); + // Actualizar las opciones correctas del juego + setGameCorrectOptions(prevCorrectOptions => [...prevCorrectOptions, response.data.responseCorrectOption]); + + const buttons = document.querySelectorAll('button[title="btnsPreg"]'); buttons.forEach(button => { button.name = "sinContestar"; @@ -85,6 +98,8 @@ const Game = () => { // Method that checks if the answer clicked is the correct one const handleAnswerClick = (option, index) => { + // Almacenar la opción seleccionada por el usuario en gameUserOptions + setGameUserOptions(prevUserOptions => [...prevUserOptions, option]); if(option === correctOption) { const buttonId = `button_${index}`; const correctButton = document.getElementById(buttonId); @@ -127,25 +142,22 @@ const Game = () => { }; const getQuestions = () => { - - const questionsList = [ - { - question: '¿Cuál es la capital de Francia?', - correctAnswer: 'París', - userAnswer: 'París' - }, - { - question: '¿Cuál es el río más largo del mundo?', - correctAnswer: 'El río Amazonas', - userAnswer: 'Hola' - }, - - ]; + const questionsList = []; + + // Iterar sobre cada pregunta generada dinámicamente y agregarla a la lista + for (let i = 0; i < gameQuestions.length; i++) { + const questionObject = gameQuestions[i]; + const correctAnswer = gameCorrectOptions[i]; + const userAnswer = gameUserOptions[i] || ''; // Establecer la respuesta del usuario como cadena vacía si no hay respuesta + questionsList.push({ question: questionObject, correctAnswer, userAnswer }); + } return questionsList; }; + + const finishGame = () => { const buttons = document.querySelectorAll('button[title="btnsPreg"]'); buttons.forEach(button => { @@ -161,6 +173,8 @@ const getQuestions = () => { } console.log("corr2 " + correctas); setPercentage(correctas); + + //a partir de aqui guardar la partida const username=localStorage.getItem('username'); const newGame = { username: username, diff --git a/webapp/src/components/HistoricalUserData.js b/webapp/src/components/HistoricalUserData.js index 8dba559f..22e2695e 100644 --- a/webapp/src/components/HistoricalUserData.js +++ b/webapp/src/components/HistoricalUserData.js @@ -12,10 +12,13 @@ const HistoricalUserData = () => { const handleLoadHistory = async () => { try { - const username=localStorage.getItem('username'); - const response = await axios.get(`${apiEndpoint}/getgamehistory/${username}`, {}); - - setGameHistory(response.data); + const username = localStorage.getItem('username'); + const response = await axios.get(`${apiEndpoint}/getgamehistory/${username}`); + + // Ordenar la lista de historial de partidas por fecha (de más reciente a más antigua) + const sortedHistory = response.data.sort((a, b) => new Date(b.date) - new Date(a.date)); + + setGameHistory(sortedHistory); console.log("el historial actual es "+gameHistory); @@ -23,6 +26,7 @@ const HistoricalUserData = () => { console.error('Error:', error); } }; + const handlePreviousPage = async () => { let path= '/MainPage'; navigate(path); From 2c0cf10f7309116275ceb4f7d6be319332c2f6db Mon Sep 17 00:00:00 2001 From: coral2742 Date: Mon, 1 Apr 2024 13:16:35 +0200 Subject: [PATCH 31/44] :sparkles: Modificaciones del reloj de juego --- webapp/src/components/Game.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/webapp/src/components/Game.js b/webapp/src/components/Game.js index 93eddc2a..e452d31d 100644 --- a/webapp/src/components/Game.js +++ b/webapp/src/components/Game.js @@ -68,6 +68,15 @@ const Game = () => { const incorrectButton = document.getElementById(buttonId); incorrectButton.style.backgroundColor = "rgba(208, 22, 22, 0.952)"; incrementIncorrect(); + // mostrar la correcta + for (let correctIndex = 0; correctIndex < 4; correctIndex++){ + const buttonIdCorrect = `button_${correctIndex}`; + const correctButton = document.getElementById(buttonIdCorrect); + if (correctButton) { + correctButton.style.backgroundColor = "rgba(79, 141, 18, 0.726)"; + } + } + } const buttons = document.querySelectorAll('button[title="btnsPreg"]'); From 0e50e0e8e5f340a834945ea0df009b5d4bff7729 Mon Sep 17 00:00:00 2001 From: coral2742 Date: Wed, 3 Apr 2024 16:33:35 +0200 Subject: [PATCH 32/44] =?UTF-8?q?:sparkles:=20Especificaci=C3=B3n=20de=20A?= =?UTF-8?q?PI=20con=20Openapi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gatewayservice/openapi.yaml | 89 +++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/gatewayservice/openapi.yaml b/gatewayservice/openapi.yaml index 67bffccb..bc411488 100644 --- a/gatewayservice/openapi.yaml +++ b/gatewayservice/openapi.yaml @@ -142,3 +142,92 @@ paths: type: string description: Error information. example: Internal Server Error + /addgame: + post: + summary: Add a new game to the database. + operationId: addGame + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + gameName: + type: string + description: Name of the game. + example: Game1 + responses: + '200': + description: Game added successfully. + content: + application/json: + schema: + type: object + properties: + message: + type: string + description: Message indicating success. + example: Game added successfully. + '400': + description: Failed to add game. + content: + application/json: + schema: + type: object + properties: + error: + type: string + description: Error information. + example: Game already exists. + + + /getgamehistory/{username}: + get: + summary: Get game history for a specific user. + operationId: getGameHistory + parameters: + - name: username + in: path + description: Username for which to retrieve game history. + required: true + schema: + type: string + example: student + responses: + '200': + description: Game history retrieved successfully. + content: + application/json: + schema: + type: array + items: + type: object + properties: + gameId: + type: string + description: ID of the game. + example: 12345 + gameName: + type: string + description: Name of the game. + example: Game1 + score: + type: integer + description: Score achieved in the game. + example: 100 + datePlayed: + type: string + description: Date when the game was played. + example: '2024-03-20T15:00:00Z' + '400': + description: Failed to retrieve game history. + content: + application/json: + schema: + type: object + properties: + error: + type: string + description: Error information. + example: User not found. \ No newline at end of file From f86c7a36bde75533827d103886129b29d17c9022 Mon Sep 17 00:00:00 2001 From: baraganio Date: Thu, 4 Apr 2024 21:27:37 +0200 Subject: [PATCH 33/44] Arreglando las respuestas que no traen nombre (traen la etiqueta Q1234) --- questions/creationservice/creation-service.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/questions/creationservice/creation-service.js b/questions/creationservice/creation-service.js index 7fc89323..102d437c 100644 --- a/questions/creationservice/creation-service.js +++ b/questions/creationservice/creation-service.js @@ -34,10 +34,14 @@ function getQuestionInfo(info){ // Select 4 random rows of the data for (let i = 0; i Date: Sun, 7 Apr 2024 14:10:14 +0200 Subject: [PATCH 34/44] Resolucion problemas fin de partida --- .github/workflows/release.yml | 4 -- webapp/src/components/Game.js | 22 ++++++----- webapp/src/components/HistoricalQuestions.js | 39 -------------------- webapp/src/components/MainPage.js | 7 ---- 4 files changed, 12 insertions(+), 60 deletions(-) delete mode 100644 webapp/src/components/HistoricalQuestions.js diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d79bea68..fc3e6a08 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -169,8 +169,4 @@ jobs: docker compose --profile prod down docker compose --profile prod up -d --pull always - wget https://raw.githubusercontent.com/arquisoft/wiq_0/master/docker-compose.yml -O docker-compose.yml - wget https://raw.githubusercontent.com/arquisoft/wiq_0/master/.env -O .env - docker compose --profile prod down - docker compose --profile prod up -d --pull always diff --git a/webapp/src/components/Game.js b/webapp/src/components/Game.js index d394909d..a96ed7ba 100644 --- a/webapp/src/components/Game.js +++ b/webapp/src/components/Game.js @@ -23,8 +23,8 @@ const Game = () => { const [questionCounter, setQuestionCounter] = useState(0); const [incorrectCounter, setIncorrectCounter] = useState(0); - const [numberOfQuestions, setNumberOfQuestions] = useState(10); - const [questionsToAnswer, setQuestionsToAnswer] = useState(10); + const [numberOfQuestions] = useState(3); + const [questionsToAnswer, setQuestionsToAnswer] = useState(3); const [isFinished, setFinished] = useState(false); const [percentage, setPercentage] = useState(0); @@ -55,9 +55,16 @@ const Game = () => { useEffect(() => { if (isGameFinished() && !isFinished){ finishGame(); - setFinished(true) + setFinished(true); ; } }, [correctCounter]); + + useEffect(() => { + if (isGameFinished() && !isFinished){ + finishGame(); + setFinished(true); +; } + }, [incorrectCounter]); // This method will call the create question service const handleShowQuestion = async () => { @@ -84,11 +91,8 @@ const Game = () => { button.onmouse = colorOnMousePreguntas; }); - - incrementQuestion(); - }catch (error){ console.error('Error:', error); } @@ -134,13 +138,11 @@ const Game = () => { decrementQuestionsToAnswer(); - - if (!isFinished){ + if (!isGameFinished()) { setTimeout(() => { handleShowQuestion(); - }, 850); + }, 1000); } - } const isGameFinished = () => { diff --git a/webapp/src/components/HistoricalQuestions.js b/webapp/src/components/HistoricalQuestions.js deleted file mode 100644 index 2e734412..00000000 --- a/webapp/src/components/HistoricalQuestions.js +++ /dev/null @@ -1,39 +0,0 @@ -import axios from 'axios'; -import React, { useState} from 'react'; -import { useNavigate} from 'react-router-dom'; -import { Container, Button} from '@mui/material'; - -const HistoricalQuestions = () => { - const navigate = useNavigate(); - const apiEndpoint = process.env.REACT_APP_API_ENDPOINT || 'http://localhost:8000'; - - const [questionsHistory, setQuestionsHistory] = useState([]); - - const handleShowHistory = async () => { - try{ - // It makes a petition to the api and store the response - const response = await axios.post(`${apiEndpoint}/getquestionshistory`, { }); - setQuestionsHistory(response.data); - }catch (error){ - console.error('Error:', error); - } - } - - const handlePreviousPage = async () => { - let path= '/MainPage'; - navigate(path); - } - - return ( - - - -
- -
-
- - ); -}; - -export default HistoricalQuestions; \ No newline at end of file diff --git a/webapp/src/components/MainPage.js b/webapp/src/components/MainPage.js index 6a2231c8..9bba6333 100644 --- a/webapp/src/components/MainPage.js +++ b/webapp/src/components/MainPage.js @@ -21,10 +21,6 @@ const MainPage = () => { navigate(path); }; - const handleShowHistoricalQuestions = () => { - let path= '/HistoricalQuestions'; - navigate(path); - }; return ( @@ -46,9 +42,6 @@ const MainPage = () => { - ) From e0cdd4f2362a03bfce22020ee725d1e7b6c85702 Mon Sep 17 00:00:00 2001 From: coral2742 Date: Sun, 7 Apr 2024 17:57:31 +0200 Subject: [PATCH 35/44] sparkles: Cambios en temporizador --- webapp/src/App.css | 13 +++++++-- webapp/src/components/Game.js | 25 ++++++++++++++-- webapp/src/components/Timer2.js | 51 +++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 6 deletions(-) create mode 100644 webapp/src/components/Timer2.js diff --git a/webapp/src/App.css b/webapp/src/App.css index 74b5e053..60638c44 100644 --- a/webapp/src/App.css +++ b/webapp/src/App.css @@ -1,9 +1,10 @@ .App { text-align: center; + font-family: Arial, sans-serif; } .App-logo { - height: 40vmin; + height: 150px; pointer-events: none; } @@ -14,18 +15,24 @@ } .App-header { - background-color: #282c34; + background-color: #007bff; min-height: 100vh; display: flex; flex-direction: column; align-items: center; justify-content: center; - font-size: calc(10px + 2vmin); + font-size: 24px; color: white; } .App-link { color: #61dafb; + text-decoration: none; + transition: color 0.3s ease; +} + +.App-link:hover { + color: #007bff; } @keyframes App-logo-spin { diff --git a/webapp/src/components/Game.js b/webapp/src/components/Game.js index 92c0a98e..c0d1ee2a 100644 --- a/webapp/src/components/Game.js +++ b/webapp/src/components/Game.js @@ -7,6 +7,7 @@ import './Game.css'; import '../Timer.css'; import Timer from './Timer'; +import Timer2 from './Timer2'; const colorPreguntas= 'rgba(51, 139, 173, 0.764)'; const colorOnMousePreguntas= 'rgba(28, 84, 106, 0.764)'; @@ -36,6 +37,15 @@ const Game = () => { // Temporizador const [seconds, setSeconds] = useState(120); + const [resetTimer, setResetTimer] = useState(false); // Estado para controlar el reinicio del temporizador + + const handleResetTimer = () => { + setResetTimer(prevResetTimer => !prevResetTimer); // Cambiar el estado de resetTimer para reiniciar el temporizador + }; + + + + useEffect(() => { @@ -236,6 +246,7 @@ const getQuestions = () => { setQuestionCounter(qc => qc + 1); } + return ( @@ -248,11 +259,16 @@ const getQuestions = () => { {!isFinished && (
- - - +
+ + +
+ {/* Pasar la función de reinicio como prop al Timer2 */}
+ + + )} @@ -268,6 +284,9 @@ const getQuestions = () => { + diff --git a/webapp/src/components/Timer2.js b/webapp/src/components/Timer2.js new file mode 100644 index 00000000..2dba7ba7 --- /dev/null +++ b/webapp/src/components/Timer2.js @@ -0,0 +1,51 @@ +import { useEffect, useRef, useState } from "react"; +import "../Timer.css"; + +function Timer2() { + const [time, setTime] = useState(20); // Comenzar desde 20 segundos en lugar de 0 + + useEffect(() => { + const id = setInterval(() => { + setTime((prev) => { + if (prev > 0) { + return prev - 1; // Decrementar el tiempo + } else { + return 20; // Reiniciar el tiempo a 20 segundos cuando llega a 0 + } + }); + }, 1000); + + return () => clearInterval(id); // Limpiar el intervalo cuando el componente se desmonta + }, []); + + // Calcular el porcentaje de tiempo transcurrido para el círculo + const percentage = ((20 - time) / 20) * 100; // Calcular el porcentaje en base al tiempo restante + + return ( +
+
+
{time}
+
+ + + + +
+

+
+ {/* No se necesita botón de pausa */} + {/* Botón para reiniciar el temporizador */} +
+
+ ); +} + +export default Timer2; From 3e8ddb7a9f92f45d93d02a0d8322a0a3e4f8c052 Mon Sep 17 00:00:00 2001 From: "coral (UO285240)" Date: Sun, 7 Apr 2024 19:01:38 +0200 Subject: [PATCH 36/44] =?UTF-8?q?:sparkles:=20Peque=C3=B1os=20cambios=20en?= =?UTF-8?q?=20temporizador?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- webapp/src/components/Game.js | 20 +++----------------- webapp/src/components/Timer2.js | 2 +- 2 files changed, 4 insertions(+), 18 deletions(-) diff --git a/webapp/src/components/Game.js b/webapp/src/components/Game.js index c0d1ee2a..68066398 100644 --- a/webapp/src/components/Game.js +++ b/webapp/src/components/Game.js @@ -1,4 +1,4 @@ -import React, { useState, useEffect, StrictMode } from 'react'; +import React, { useState, useEffect, StrictMode, useRef } from 'react'; import axios from 'axios'; import { Container, Typography, Button, Paper} from '@mui/material'; import { useNavigate, useParams } from 'react-router-dom'; @@ -34,19 +34,10 @@ const Game = () => { const [gameUserOptions, setGameUserOptions] = useState([]); const [gameCorrectOptions, setGameCorrectOptions] = useState([]); const [gameQuestions, setGameQuestions] = useState([]); + // Temporizador const [seconds, setSeconds] = useState(120); - const [resetTimer, setResetTimer] = useState(false); // Estado para controlar el reinicio del temporizador - - const handleResetTimer = () => { - setResetTimer(prevResetTimer => !prevResetTimer); // Cambiar el estado de resetTimer para reiniciar el temporizador - }; - - - - - useEffect(() => { handleShowQuestion(); @@ -263,7 +254,7 @@ const getQuestions = () => {
- {/* Pasar la función de reinicio como prop al Timer2 */} +
@@ -284,11 +275,6 @@ const getQuestions = () => { - - - )} diff --git a/webapp/src/components/Timer2.js b/webapp/src/components/Timer2.js index 2dba7ba7..bfeb7f82 100644 --- a/webapp/src/components/Timer2.js +++ b/webapp/src/components/Timer2.js @@ -1,4 +1,4 @@ -import { useEffect, useRef, useState } from "react"; +import { useEffect, useState } from "react"; import "../Timer.css"; function Timer2() { From d0fb79666561ea7003f07a51b5b504e1141ef563 Mon Sep 17 00:00:00 2001 From: "coral (UO285240)" Date: Sun, 7 Apr 2024 19:59:31 +0200 Subject: [PATCH 37/44] :sparkles: Temporizador solucionado --- webapp/src/components/Game.js | 75 ++++++++++++++++++++++++++++++--- webapp/src/components/Timer.js | 37 ---------------- webapp/src/components/Timer2.js | 51 ---------------------- 3 files changed, 69 insertions(+), 94 deletions(-) delete mode 100644 webapp/src/components/Timer.js delete mode 100644 webapp/src/components/Timer2.js diff --git a/webapp/src/components/Game.js b/webapp/src/components/Game.js index aa7a736d..d1f21b3f 100644 --- a/webapp/src/components/Game.js +++ b/webapp/src/components/Game.js @@ -1,4 +1,4 @@ -import React, { useState, useEffect, StrictMode, useRef } from 'react'; +import React, { useState, useEffect } from 'react'; import axios from 'axios'; import { Container, Typography, Button, Paper} from '@mui/material'; import { useNavigate, useParams } from 'react-router-dom'; @@ -6,8 +6,6 @@ import { useNavigate, useParams } from 'react-router-dom'; import './Game.css'; import '../Timer.css'; -import Timer from './Timer'; -import Timer2 from './Timer2'; const colorPreguntas= 'rgba(51, 139, 173, 0.764)'; const colorOnMousePreguntas= 'rgba(28, 84, 106, 0.764)'; @@ -27,6 +25,8 @@ const Game = () => { const [numberOfQuestions] = useState(3); const [questionsToAnswer, setQuestionsToAnswer] = useState(3); const [isFinished, setFinished] = useState(false); + + // Porcentaje de aciertos const [percentage, setPercentage] = useState(0); @@ -38,6 +38,44 @@ const Game = () => { // Temporizador const [seconds, setSeconds] = useState(120); + // Temporizador desde 20 segundos + const [time, setTime] = useState(20); + + // Estado para controlar si el temporizador está activo o no + const [isTimerActive, setIsTimerActive] = useState(true); + + useEffect(() => { + const id = setInterval(() => { + if (isTimerActive) { // Solo decrementa el tiempo si el temporizador está activo + setTime((prev) => { + if (prev > 0) { + return prev - 1; + } else { + return 20; // Reiniciar el tiempo a 20 segundos cuando llega a 0 + } + }); + } + }, 1000); + + return () => clearInterval(id); // Limpiar el intervalo cuando el componente se desmonta + }, [isTimerActive]); // Asegúrate de que el efecto se ejecute cada vez que cambie el estado del temporizador + + + // Calcular el porcentaje de tiempo transcurrido para el círculo + const percentageTime = ((20 - time) / 20) * 100; // Calcular el porcentaje en base al tiempo restante + + + // Función para detener el temporizador + const stopTimer = () => { + setIsTimerActive(false); // Cambiar el estado para detener el temporizador + }; + + // Función para activar el temporizador + const restartTimer = () => { + setTime(20); // Reiniciar el tiempo a 20 segundos + setIsTimerActive(true); // Volver a activar el temporizador + }; + useEffect(() => { handleShowQuestion(); @@ -79,7 +117,7 @@ const Game = () => { //guardar para el final // Actualizar las preguntas del juego - setGameQuestions(prevQuestions => [...prevQuestions, response.data.responseQuestionObject]); + setGameQuestions(prevQuestions => [...prevQuestions, response.data.responseQuestionObject]); // Actualizar las opciones correctas del juego setGameCorrectOptions(prevCorrectOptions => [...prevCorrectOptions, response.data.responseCorrectOption]); @@ -94,6 +132,9 @@ const Game = () => { incrementQuestion(); + // Resetear temporizador a 20 segundos + restartTimer(); + }catch (error){ console.error('Error:', error); } @@ -103,6 +144,7 @@ const Game = () => { const handleAnswerClick = (option, index) => { // Almacenar la opción seleccionada por el usuario en gameUserOptions setGameUserOptions(prevUserOptions => [...prevUserOptions, option]); + if(option === correctOption) { const buttonId = `button_${index}`; const correctButton = document.getElementById(buttonId); @@ -115,6 +157,9 @@ const Game = () => { const incorrectButton = document.getElementById(buttonId); incorrectButton.style.backgroundColor = "rgba(208, 22, 22, 0.952)"; + // parar el temporizador + stopTimer(); + // mostrar la correcta for (let correctIndex = 0; correctIndex < 4; correctIndex++){ const buttonIdCorrect = `button_${correctIndex}`; @@ -250,8 +295,24 @@ const getQuestions = () => { -
- +
+
+
{time}
+
+ + + + +
+
@@ -313,6 +374,8 @@ const getQuestions = () => { Ir a la página principal
+ + )} diff --git a/webapp/src/components/Timer.js b/webapp/src/components/Timer.js deleted file mode 100644 index bb68c6e1..00000000 --- a/webapp/src/components/Timer.js +++ /dev/null @@ -1,37 +0,0 @@ -import { useEffect, useState } from "react"; -import "../Timer.css"; - -export default function Timer() { - const [loadingPercent, setLoadingPercent] = useState(0); - const [dot, setDot] = useState(0); - const [text, setText] = useState("20"); - - useEffect(() => { - const interval = setInterval(() => { - const secs = 20 - (new Date().getSeconds() % 21); - - const currentLoadingPercent = 440 - 440 * (secs / 20); - setLoadingPercent(currentLoadingPercent); - - const currentDot = 360 * (secs / 20); - setDot(currentDot); - - setText(secs >= 10 ? secs : `0${secs}`); - }, 1000); - - return () => clearInterval(interval); - }, []); - - return ( -
-
-
{text}
-
- - - - -
-
- ); -} diff --git a/webapp/src/components/Timer2.js b/webapp/src/components/Timer2.js deleted file mode 100644 index bfeb7f82..00000000 --- a/webapp/src/components/Timer2.js +++ /dev/null @@ -1,51 +0,0 @@ -import { useEffect, useState } from "react"; -import "../Timer.css"; - -function Timer2() { - const [time, setTime] = useState(20); // Comenzar desde 20 segundos en lugar de 0 - - useEffect(() => { - const id = setInterval(() => { - setTime((prev) => { - if (prev > 0) { - return prev - 1; // Decrementar el tiempo - } else { - return 20; // Reiniciar el tiempo a 20 segundos cuando llega a 0 - } - }); - }, 1000); - - return () => clearInterval(id); // Limpiar el intervalo cuando el componente se desmonta - }, []); - - // Calcular el porcentaje de tiempo transcurrido para el círculo - const percentage = ((20 - time) / 20) * 100; // Calcular el porcentaje en base al tiempo restante - - return ( -
-
-
{time}
-
- - - - -
-

-
- {/* No se necesita botón de pausa */} - {/* Botón para reiniciar el temporizador */} -
-
- ); -} - -export default Timer2; From 838e0930dcaffc4604ccee665da94637f25f2091 Mon Sep 17 00:00:00 2001 From: "coral (UO285240)" Date: Sun, 7 Apr 2024 20:00:01 +0200 Subject: [PATCH 38/44] :sparkles: 6 preguntas por partida --- webapp/src/components/Game.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webapp/src/components/Game.js b/webapp/src/components/Game.js index d1f21b3f..1ab644f6 100644 --- a/webapp/src/components/Game.js +++ b/webapp/src/components/Game.js @@ -22,8 +22,8 @@ const Game = () => { const [questionCounter, setQuestionCounter] = useState(0); const [incorrectCounter, setIncorrectCounter] = useState(0); - const [numberOfQuestions] = useState(3); - const [questionsToAnswer, setQuestionsToAnswer] = useState(3); + const [numberOfQuestions] = useState(6); + const [questionsToAnswer, setQuestionsToAnswer] = useState(6); const [isFinished, setFinished] = useState(false); // Porcentaje de aciertos From 49839263213118564fec4878311582e58614902e Mon Sep 17 00:00:00 2001 From: "coral (UO285240)" Date: Sun, 7 Apr 2024 20:58:09 +0200 Subject: [PATCH 39/44] :sparkles: Pregunta incorrecta si pasa de tiempo --- webapp/src/components/Game.js | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/webapp/src/components/Game.js b/webapp/src/components/Game.js index 1ab644f6..f494ff54 100644 --- a/webapp/src/components/Game.js +++ b/webapp/src/components/Game.js @@ -35,11 +35,14 @@ const Game = () => { const [gameCorrectOptions, setGameCorrectOptions] = useState([]); const [gameQuestions, setGameQuestions] = useState([]); - // Temporizador const [seconds, setSeconds] = useState(120); + + + // Temporizador desde 20 segundos const [time, setTime] = useState(20); + const [isTimedOut, setTimedOut] = useState(false); // Estado para controlar si el temporizador está activo o no const [isTimerActive, setIsTimerActive] = useState(true); @@ -51,7 +54,8 @@ const Game = () => { if (prev > 0) { return prev - 1; } else { - return 20; // Reiniciar el tiempo a 20 segundos cuando llega a 0 + // Se acabó el tiempo + setTimedOut(true); } }); } @@ -316,9 +320,23 @@ const getQuestions = () => { + )} + {isTimedOut && ( +
+
+

¡Tiempo agotado!

+ + + incrementIncorrect(); + incrementQuestion(); + + restartTimer(); + +
+
+ )} - )} From f2f42365f7fd93db350d18c759d9f73cf1442f93 Mon Sep 17 00:00:00 2001 From: coral2742 Date: Sun, 7 Apr 2024 22:21:12 +0200 Subject: [PATCH 40/44] :sparkles: Manejo de tiempo agotado con modal --- webapp/src/components/Game.js | 37 ++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/webapp/src/components/Game.js b/webapp/src/components/Game.js index f494ff54..dab497f2 100644 --- a/webapp/src/components/Game.js +++ b/webapp/src/components/Game.js @@ -61,23 +61,23 @@ const Game = () => { } }, 1000); - return () => clearInterval(id); // Limpiar el intervalo cuando el componente se desmonta - }, [isTimerActive]); // Asegúrate de que el efecto se ejecute cada vez que cambie el estado del temporizador + return () => clearInterval(id); + }, [isTimerActive]); - // Calcular el porcentaje de tiempo transcurrido para el círculo - const percentageTime = ((20 - time) / 20) * 100; // Calcular el porcentaje en base al tiempo restante + // Calcular el porcentaje de tiempo transcurrido para el círculo del temporizador + const percentageTime = ((20 - time) / 20) * 100; - // Función para detener el temporizador + // Detener el temporizador const stopTimer = () => { - setIsTimerActive(false); // Cambiar el estado para detener el temporizador + setIsTimerActive(false); }; - // Función para activar el temporizador + // Activar el temporizador const restartTimer = () => { setTime(20); // Reiniciar el tiempo a 20 segundos - setIsTimerActive(true); // Volver a activar el temporizador + setIsTimerActive(true); }; @@ -322,20 +322,21 @@ const getQuestions = () => { )} - {isTimedOut && ( -
-
-

¡Tiempo agotado!

- - + {isTimedOut && ( + + + ¡Tiempo agotado! + + + + )} -
-
- )} From 457372310e0357777e1850798d2101bf02df2aa4 Mon Sep 17 00:00:00 2001 From: baraganio Date: Sun, 7 Apr 2024 23:20:56 +0200 Subject: [PATCH 41/44] Cambiando alguna peticiones post por get --- gatewayservice/gateway-service.js | 8 ++++---- questions/creationservice/creation-service.js | 2 +- questions/retrieveservice/retrieve-service.js | 2 +- webapp/src/components/Game.js | 2 +- webapp/src/components/HistoricalData.js | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/gatewayservice/gateway-service.js b/gatewayservice/gateway-service.js index 9399e3a8..82e9f886 100644 --- a/gatewayservice/gateway-service.js +++ b/gatewayservice/gateway-service.js @@ -69,10 +69,10 @@ app.get('/getgamehistory/:username', async (req, res) => { -app.post('/createquestion', async (req, res) => { +app.get('/createquestion', async (req, res) => { try { // Create a petition to the URL (le llegará a creation-service.js) with the option /createquestion and the req.body params - const questionResponse = await axios.post(creationServiceUrl+'/createquestion', req.body); + const questionResponse = await axios.get(creationServiceUrl+'/createquestion', req.body); // Return a json response with what we obtained on the petition res.json(questionResponse.data); } catch (error) { @@ -80,10 +80,10 @@ app.post('/createquestion', async (req, res) => { } }); -app.post('/getquestionshistory', async (req, res) => { +app.get('/getquestionshistory', async (req, res) => { try { // Create a petition to the URL (le llegará a retrieve-service.js) with the option /getgeneratedquestions and the req.body params - const questionResponse = await axios.post(retrieveServiceUrl+'/getquestionshistory', req.body); + const questionResponse = await axios.get(retrieveServiceUrl+'/getquestionshistory', req.body); // Return a json response with what we obtained on the petition res.json(questionResponse.data); } catch (error) { diff --git a/questions/creationservice/creation-service.js b/questions/creationservice/creation-service.js index 102d437c..1243145c 100644 --- a/questions/creationservice/creation-service.js +++ b/questions/creationservice/creation-service.js @@ -77,7 +77,7 @@ async function saveQuestion(){ } } -app.post('/createquestion', async (req, res) => { +app.get('/createquestion', async (req, res) => { selectRandomQuery(); const apiUrl = `https://query.wikidata.org/sparql?query=${encodeURIComponent(queries[randomQuerySelector])}&format=json`; diff --git a/questions/retrieveservice/retrieve-service.js b/questions/retrieveservice/retrieve-service.js index 3ece0bc3..0d65c42a 100644 --- a/questions/retrieveservice/retrieve-service.js +++ b/questions/retrieveservice/retrieve-service.js @@ -11,7 +11,7 @@ const mongoUri = process.env.MONGODB_URI || 'mongodb://localhost:27017/questiond mongoose.connect(mongoUri); -app.post('/getquestionshistory', async (req, res) => { +app.get('/getquestionshistory', async (req, res) => { const questions = await Question.find({}); var solution = []; diff --git a/webapp/src/components/Game.js b/webapp/src/components/Game.js index 92c0a98e..cf3017a5 100644 --- a/webapp/src/components/Game.js +++ b/webapp/src/components/Game.js @@ -63,7 +63,7 @@ const Game = () => { const handleShowQuestion = async () => { try{ // It makes a petition to the api and store the response - const response = await axios.post(`${apiEndpoint}/createquestion`, { }); + const response = await axios.get(`${apiEndpoint}/createquestion`, { }); // Extract all the info of the response and store it setQuestionObject(response.data.responseQuestionObject); setCorrectOption(response.data.responseCorrectOption); diff --git a/webapp/src/components/HistoricalData.js b/webapp/src/components/HistoricalData.js index 6e746026..72407410 100644 --- a/webapp/src/components/HistoricalData.js +++ b/webapp/src/components/HistoricalData.js @@ -12,7 +12,7 @@ const HistoricalData = () => { const handleShowHistory = async () => { try{ // It makes a petition to the api and store the response - const response = await axios.post(`${apiEndpoint}/getquestionshistory`, { }); + const response = await axios.get(`${apiEndpoint}/getquestionshistory`, { }); setQuestionsHistory(response.data); }catch (error){ console.error('Error:', error); From 597fe01ee64772f7a3fb5740fec540cd4cb6407f Mon Sep 17 00:00:00 2001 From: baraganio Date: Sun, 7 Apr 2024 23:39:47 +0200 Subject: [PATCH 42/44] Merge con develop --- .github/workflows/release.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2c9768ee..da48ef08 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -163,6 +163,4 @@ jobs: wget https://raw.githubusercontent.com/arquisoft/wiq_es2b/master/docker-compose.yml -O docker-compose.yml wget https://raw.githubusercontent.com/arquisoft/wiq_es2b/master/.env -O .env docker compose --profile prod down - docker compose --profile prod up -d --pull always - ->>>>>>>>> Temporary merge branch 2 + docker compose --profile prod up -d --pull always \ No newline at end of file From 668b401a67f64eeaaca1c4533732809d5e3fa80e Mon Sep 17 00:00:00 2001 From: Carlos Sanchez <108028059+baraganio@users.noreply.github.com> Date: Mon, 8 Apr 2024 00:04:50 +0200 Subject: [PATCH 43/44] Update 06_runtime_view --- docs/src/06_runtime_view.adoc | 80 ++++++++++------------------------- 1 file changed, 22 insertions(+), 58 deletions(-) diff --git a/docs/src/06_runtime_view.adoc b/docs/src/06_runtime_view.adoc index e10f375b..c9e002f6 100644 --- a/docs/src/06_runtime_view.adoc +++ b/docs/src/06_runtime_view.adoc @@ -3,63 +3,27 @@ ifndef::imagesdir[:imagesdir: ../images] [[section-runtime-view]] == Runtime View - -[role="arc42help"] -**** -.Contents -The runtime view describes concrete behavior and interactions of the system’s building blocks in form of scenarios from the following areas: - -* important use cases or features: how do building blocks execute them? -* interactions at critical external interfaces: how do building blocks cooperate with users and neighboring systems? -* operation and administration: launch, start-up, stop -* error and exception scenarios - -Remark: The main criterion for the choice of possible scenarios (sequences, workflows) is their *architectural relevance*. It is *not* important to describe a large number of scenarios. You should rather document a representative selection. - -.Motivation -You should understand how (instances of) building blocks of your system perform their job and communicate at runtime. -You will mainly capture scenarios in your documentation to communicate your architecture to stakeholders that are less willing or able to read and understand the static models (building block view, deployment view). - -.Form -There are many notations for describing scenarios, e.g. - -* numbered list of steps (in natural language) -* activity diagrams or flow charts -* sequence diagrams -* BPMN or EPCs (event process chains) -* state machines -* ... - - -.Further Information - -See https://docs.arc42.org/section-6/[Runtime View] in the arc42 documentation. - -**** - -=== - - -* __ -* __ - -It is possible to use a sequence diagram: - -[plantuml,"Sequence diagram",png] +=== User plays a game +When the game is started, the app will call the createquestion service that is in charge of provide generated questions from wikidata information. +[plantuml,"Start a game",png] ---- -actor Alice -actor Bob -database Pod as "Bob's Pod" -Alice -> Bob: Authentication Request -Bob --> Alice: Authentication Response -Alice --> Pod: Store route -Alice -> Bob: Another authentication Request -Alice <-- Bob: another authentication Response +actor a as "User" +participant q as "Game GUI" +participant w as "CreateQuestions service" +database d as "Database" + + +a -> q: Start the game +loop number of questions +q -> w: Ask for a question +w -->q: Returns the question +q -> d: Store the question +q -> a: Returns the question + +a -> q: Pick an answer +q -> a: Shows if the answer was valid or not +a -> q: Asks for next question +end +q -> a: Show the game stats +q -> d: Store the game with questions, answers and stats ---- - -=== - -=== ... - -=== From cfd29cd7becf52e8f98f9f11d84e0616c786f39f Mon Sep 17 00:00:00 2001 From: uo264915 Date: Mon, 8 Apr 2024 00:32:26 +0200 Subject: [PATCH 44/44] Arreglos de warnings --- package-lock.json | 2 +- webapp/src/components/Game.js | 9 ++++++--- webapp/src/components/MainPage.js | 6 +++--- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6b9c122e..e12e1c11 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "WIQ_ES2B", + "name": "wiq_es2b", "lockfileVersion": 2, "requires": true, "packages": { diff --git a/webapp/src/components/Game.js b/webapp/src/components/Game.js index d48854c7..8c44e537 100644 --- a/webapp/src/components/Game.js +++ b/webapp/src/components/Game.js @@ -1,7 +1,7 @@ import React, { useState, useEffect } from 'react'; import axios from 'axios'; import { Container, Typography, Button, Paper} from '@mui/material'; -import { useNavigate, useParams } from 'react-router-dom'; +import { useNavigate } from 'react-router-dom'; import './Game.css'; @@ -83,6 +83,7 @@ const Game = () => { useEffect(() => { handleShowQuestion(); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); useEffect(() => { @@ -99,14 +100,16 @@ const Game = () => { if (isGameFinished() && !isFinished){ finishGame(); setFinished(true); -; } + } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [correctCounter]); useEffect(() => { if (isGameFinished() && !isFinished){ finishGame(); setFinished(true); -; } + } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [incorrectCounter]); // This method will call the create question service diff --git a/webapp/src/components/MainPage.js b/webapp/src/components/MainPage.js index 9bba6333..757bf60a 100644 --- a/webapp/src/components/MainPage.js +++ b/webapp/src/components/MainPage.js @@ -1,6 +1,6 @@ -import React, { useState } from 'react'; -import { Container, Typography, TextField, Button, Snackbar } from '@mui/material'; -import { useNavigate, useParams } from 'react-router-dom'; +import React, { } from 'react'; +import { Container, Typography, Button } from '@mui/material'; +import { useNavigate } from 'react-router-dom'; import './MainPage.css'; const MainPage = () => {
PreguntaOpción correctaOpción incorrecta 1Opción incorrecta 2Opción incorrecta 3PreguntaOpción correctaOpción incorrecta 1Opción incorrecta 2Opción incorrecta 3