From 1587ce4d62047a5eea47b1c02b2491cd597d02ed Mon Sep 17 00:00:00 2001 From: David Mears Date: Mon, 29 Jul 2024 14:35:33 +0100 Subject: [PATCH 01/49] WIP - front end can talk to R API --- README.md | 12 +++++++++--- db/scripts/build | 3 ++- db/scripts/common | 4 ++-- db/scripts/run | 2 +- db/scripts/runQuery | 2 +- pages/rApi.vue | 21 +++++++++++++++++++++ scripts/run-dependencies | 19 +++++++++++++++++++ server/api/r.ts | 26 ++++++++++++++++++++++++++ 8 files changed, 81 insertions(+), 8 deletions(-) create mode 100644 pages/rApi.vue create mode 100755 scripts/run-dependencies create mode 100644 server/api/r.ts diff --git a/README.md b/README.md index 6544ebe7..dfd1a820 100644 --- a/README.md +++ b/README.md @@ -34,11 +34,11 @@ The tests under e2e, which are run by playwright, are for testing the full-stack Use Node 20. Have Docker installed. Copy `.env.example` to `.env`. -Build and run the database container: + +Build and run the database container and R API container using this script: ```bash -./db/scripts/build -./db/scripts/run +run-dev-dependencies ``` Install the JS dependencies: @@ -47,6 +47,12 @@ Install the JS dependencies: npm install ``` +If you're using a fresh database, then you'll need to run the migrations: + +```bash +npx prisma migrate dev +``` + Prisma ORM can only query the database once you 'generate' the Prisma Client, which generates into `node_modules/.prisma/client`. This should happen when you install the JS dependencies and whenever you run a migration, but if the Prisma client gets out of sync or doesn't generate, you can manually generate it: ```bash diff --git a/db/scripts/build b/db/scripts/build index c62e8f18..da8185d0 100755 --- a/db/scripts/build +++ b/db/scripts/build @@ -1,5 +1,6 @@ #!/usr/bin/env bash -set -e +set -euxo pipefail + HERE=$(dirname $0) . $HERE/common diff --git a/db/scripts/common b/db/scripts/common index fda8acbc..22b7dc7a 100644 --- a/db/scripts/common +++ b/db/scripts/common @@ -1,5 +1,5 @@ #!/usr/bin/env bash -set -ex +set -euxo pipefail if [[ -v "GITHUB_SHA" ]]; then GIT_ID=${GITHUB_SHA:0:7} @@ -13,7 +13,7 @@ else GIT_BRANCH=$(git symbolic-ref --short HEAD) fi -ORG=jameel-institute +ORG=mrc-ide IMAGE_NAME=daedalus-web-app-db TAG_SHA="${ORG}/${IMAGE_NAME}:${GIT_ID}" TAG_BRANCH="${ORG}/${IMAGE_NAME}:${GIT_BRANCH}" diff --git a/db/scripts/run b/db/scripts/run index a6d1379c..d2c2fb4c 100755 --- a/db/scripts/run +++ b/db/scripts/run @@ -1,5 +1,5 @@ #!/usr/bin/env bash -set -e +set -euxo pipefail HERE=$(dirname $0) . $HERE/common diff --git a/db/scripts/runQuery b/db/scripts/runQuery index f346ac58..23787dc8 100755 --- a/db/scripts/runQuery +++ b/db/scripts/runQuery @@ -1,5 +1,5 @@ #!/bin/bash -set -e +set -eux # Check if the SQL query is passed as an argument if [ -z "$1" ]; then diff --git a/pages/rApi.vue b/pages/rApi.vue new file mode 100644 index 00000000..d4ade209 --- /dev/null +++ b/pages/rApi.vue @@ -0,0 +1,21 @@ + + + + + diff --git a/scripts/run-dependencies b/scripts/run-dependencies new file mode 100755 index 00000000..993597e1 --- /dev/null +++ b/scripts/run-dependencies @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +set -exo pipefail + +HERE=$(realpath "$(dirname $0)") + +# Build and run the database +# TODO: Make build step skippable +"$HERE"/../db/scripts/build +"$HERE"/../db/scripts/run + +# TODO: Check if this wait, copied from packit, is necessary +# docker exec daedalus-web-app-db wait-for-db + +# Build and run the R API +R_API_ADDRESS='mrcide/daedalus.api:latest' +docker pull $R_API_ADDRESS # There will be a 'latest' tag: https://github.com/jameel-institute/daedalus.api/pull/2#issuecomment-2252491603 +docker run -d --name daedalus-api --rm -p 8001:8001 $R_API_ADDRESS + diff --git a/server/api/r.ts b/server/api/r.ts new file mode 100644 index 00000000..297230ba --- /dev/null +++ b/server/api/r.ts @@ -0,0 +1,26 @@ +const rApiAddress = "http://localhost:8001"; + +export default defineEventHandler(async (event) => { + // const body = await readBody(event); + // console.log(body); + // console.log(event); + + // const rApiQueryParams = { test: 'test' } + + // TODO forward the method too + + const response = await $fetch(rApiAddress, { + // query: rApiQueryParams, + async onRequestError({ request, _options, error }) { + console.log("[fetch request error]", request, error); + }, + }) + .catch((error) => { + console.log('got here innit') + + + console.error(error.data); + }); + + return response; +}) From 704d4b7a532f62cba20d20abd02c7dcc8111644f Mon Sep 17 00:00:00 2001 From: David Mears Date: Mon, 29 Jul 2024 15:00:56 +0100 Subject: [PATCH 02/49] Add .nvmrc --- .nvmrc | 1 + 1 file changed, 1 insertion(+) create mode 100644 .nvmrc diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 00000000..9a2a0e21 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +v20 From 985a75fbd4a61175358b91ea981adb72c51cbe9d Mon Sep 17 00:00:00 2001 From: David Mears Date: Mon, 29 Jul 2024 17:38:12 +0100 Subject: [PATCH 03/49] Update scripts --- README.md | 11 ++++++-- db/Dockerfile | 3 --- db/bin/start-with-config.sh | 0 scripts/run-dependencies | 52 ++++++++++++++++++++++++++++-------- scripts/run-dev-dependencies | 18 +++++++++++++ 5 files changed, 68 insertions(+), 16 deletions(-) mode change 100644 => 100755 db/bin/start-with-config.sh create mode 100755 scripts/run-dev-dependencies diff --git a/README.md b/README.md index dfd1a820..af79e637 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,12 @@ Copy `.env.example` to `.env`. Build and run the database container and R API container using this script: ```bash -run-dev-dependencies +scripts/run-dev-dependencies +``` + +Or skip the 'build' step for the db, and try to run an existing image: +```bash +scripts/run-dev-dependencies --db-build-skip ``` Install the JS dependencies: @@ -65,6 +70,8 @@ Start the development server on `http://localhost:3000`: npm run dev ``` +(Or see the 'production' section of this README for how to run the app in production mode.) + You can also expose it to your local network, so that you can try it out on a mobile device, using: ```bash @@ -128,7 +135,7 @@ Playwright tests produce HTML reports when they run, whether on CI or not, showi ## Production -Build the application for production: +Build the Nuxt application for production: ```bash npm run build diff --git a/db/Dockerfile b/db/Dockerfile index e672d1be..fc2f049a 100644 --- a/db/Dockerfile +++ b/db/Dockerfile @@ -20,8 +20,5 @@ RUN chown -R postgres:postgres /etc/daedalus-web-app ENV PATH="/usr/local/bin:$PATH" RUN docker-entrypoint.sh --version -# Ensure the start script is executable -RUN chmod +x /daedalus-web-app-bin/start-with-config.sh - ENTRYPOINT ["/daedalus-web-app-bin/start-with-config.sh"] CMD ["/etc/daedalus-web-app/postgresql.conf"] diff --git a/db/bin/start-with-config.sh b/db/bin/start-with-config.sh old mode 100644 new mode 100755 diff --git a/scripts/run-dependencies b/scripts/run-dependencies index 993597e1..7f07911e 100755 --- a/scripts/run-dependencies +++ b/scripts/run-dependencies @@ -1,19 +1,49 @@ #!/usr/bin/env bash -set -exo pipefail +set -eo pipefail HERE=$(realpath "$(dirname $0)") -# Build and run the database -# TODO: Make build step skippable -"$HERE"/../db/scripts/build -"$HERE"/../db/scripts/run +usage() { + echo "Options:" + echo " -h, --help Show list of flags" + echo " --db-build-skip Skip building the db" +} -# TODO: Check if this wait, copied from packit, is necessary -# docker exec daedalus-web-app-db wait-for-db +DB_BUILD_SKIP=0 +handle_options() { + while [ $# -gt 0 ]; do + case $1 in + -h | --help) + usage + exit 3 + ;; + --db-build-skip) + DB_BUILD_SKIP=1 + ;; + *) + echo "Invalid option: $1" >&2 + usage + exit 1 + ;; + esac + shift + done +} -# Build and run the R API -R_API_ADDRESS='mrcide/daedalus.api:latest' -docker pull $R_API_ADDRESS # There will be a 'latest' tag: https://github.com/jameel-institute/daedalus.api/pull/2#issuecomment-2252491603 -docker run -d --name daedalus-api --rm -p 8001:8001 $R_API_ADDRESS +handle_options "$@" +# (Conditionally build and) run the database +if [ $DB_BUILD_SKIP -eq 0 ]; then + "$HERE"/../db/scripts/build +else + echo "Skipping db build" +fi +"$HERE"/../db/scripts/run + +docker exec daedalus-web-app-db wait-for-db + +# Pull and run the R API image +R_API_IMAGE='mrcide/daedalus.api:latest' +docker pull $R_API_IMAGE # There will be a 'latest' tag: https://github.com/jameel-institute/daedalus.api/pull/2#issuecomment-2252491603 +docker run -d --name daedalus-api --rm -p 8001:8001 $R_API_IMAGE diff --git a/scripts/run-dev-dependencies b/scripts/run-dev-dependencies new file mode 100755 index 00000000..ce319c31 --- /dev/null +++ b/scripts/run-dev-dependencies @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +set -ex + +HERE=$(realpath "$(dirname $0)") + +"$HERE"/run-dependencies "$@" + +# From now on, if the user presses Ctrl+C we should teardown gracefully +function cleanup() { + set +x + docker kill daedalus-web-app-db + docker kill daedalus-api +} +trap cleanup EXIT + +# Wait for Ctrl+C +echo "Ready to use. Press Ctrl+C to teardown." +sleep infinity From 3c98f7c590d82d9ef53bbbdf306c4d02616dae0c Mon Sep 17 00:00:00 2001 From: David Mears Date: Mon, 29 Jul 2024 17:50:56 +0100 Subject: [PATCH 04/49] Add db:dev:migrate npm command --- README.md | 4 ++-- package.json | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index af79e637..49c3572b 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ npm install If you're using a fresh database, then you'll need to run the migrations: ```bash -npx prisma migrate dev +npm run db:dev:migrate ``` Prisma ORM can only query the database once you 'generate' the Prisma Client, which generates into `node_modules/.prisma/client`. This should happen when you install the JS dependencies and whenever you run a migration, but if the Prisma client gets out of sync or doesn't generate, you can manually generate it: @@ -90,7 +90,7 @@ To create migrations to the database, first update the Prisma schema at ./prisma npx prisma migrate dev ``` -The same command is also used to apply migrations that already exist in ./prisma/migrations but which have not been applied to the database. +The same command is also used to apply migrations that already exist in ./prisma/migrations but which have not been applied to the database. It has been aliased for this purpose in package.json as `npm run db:dev:migrate`. Prisma ORM can only query the database once you 'generate' the Prisma Client, which generates into `node_modules/.prisma/client` based on the file `prisma/schema.prisma`. This should happen when you install the JS dependencies and whenever you run a migration, but if the Prisma client gets out of sync or doesn't generate, you can manually generate it: diff --git a/package.json b/package.json index 04506cb1..2bb8a0e5 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "scripts": { "build": "nuxt build", "dev": "nuxt dev", + "db:dev:migrate": "prisma migrate dev", "generate": "nuxt generate", "lint": "eslint .", "lint:fix": "eslint . --fix", From ee643a03fc0436cdebe8defe796c5ccf678e20d1 Mon Sep 17 00:00:00 2001 From: David Mears Date: Tue, 30 Jul 2024 09:52:09 +0100 Subject: [PATCH 05/49] Use utility instead of proxy api for R API; display version numbers --- components/SideBar.vue | 7 ++++++- components/utils/rApi.ts | 30 ++++++++++++++++++++++++++++++ db/bin/wait-for-db | 37 +++++++++++++++++++++++++++++++++++++ package.json | 3 ++- pages/rApi.vue | 21 --------------------- server/api/r.ts | 26 -------------------------- 6 files changed, 75 insertions(+), 49 deletions(-) create mode 100644 components/utils/rApi.ts create mode 100755 db/bin/wait-for-db delete mode 100644 pages/rApi.vue delete mode 100644 server/api/r.ts diff --git a/components/SideBar.vue b/components/SideBar.vue index daa4834f..6a455a5c 100644 --- a/components/SideBar.vue +++ b/components/SideBar.vue @@ -42,7 +42,7 @@ @@ -51,6 +51,8 @@ - - diff --git a/server/api/r.ts b/server/api/r.ts deleted file mode 100644 index 297230ba..00000000 --- a/server/api/r.ts +++ /dev/null @@ -1,26 +0,0 @@ -const rApiAddress = "http://localhost:8001"; - -export default defineEventHandler(async (event) => { - // const body = await readBody(event); - // console.log(body); - // console.log(event); - - // const rApiQueryParams = { test: 'test' } - - // TODO forward the method too - - const response = await $fetch(rApiAddress, { - // query: rApiQueryParams, - async onRequestError({ request, _options, error }) { - console.log("[fetch request error]", request, error); - }, - }) - .catch((error) => { - console.log('got here innit') - - - console.error(error.data); - }); - - return response; -}) From 18cb9e4178b4284c6d49164c671fae5c407a3c0f Mon Sep 17 00:00:00 2001 From: David Mears Date: Tue, 30 Jul 2024 12:22:57 +0100 Subject: [PATCH 06/49] Streamline setup instructions --- README.md | 42 +++++++++++++++++++++--------------------- package-lock.json | 6 ++++-- package.json | 1 + 3 files changed, 26 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 49c3572b..c7c073f5 100644 --- a/README.md +++ b/README.md @@ -29,11 +29,11 @@ The tests under e2e, which are run by playwright, are for testing the full-stack ## Local development -### Setup +### If it's the first time setting up Use Node 20. -Have Docker installed. -Copy `.env.example` to `.env`. + +Make sure Docker is installed. Build and run the database container and R API container using this script: @@ -41,37 +41,29 @@ Build and run the database container and R API container using this script: scripts/run-dev-dependencies ``` -Or skip the 'build' step for the db, and try to run an existing image: -```bash -scripts/run-dev-dependencies --db-build-skip -``` +If you have trouble with the R API image, there might be helpful information in [its own README](https://github.com/jameel-institute/daedalus.api). -Install the JS dependencies: +Copy `.env.example` to `.env` and then run the `dev:init` command, which installs the JS dependencies, runs any pending database migrations, and starts up the server in development mode on `http://localhost:3000`: ```bash -npm install +cp .env.example .env +npm run dev:init ``` -If you're using a fresh database, then you'll need to run the migrations: - -```bash -npm run db:dev:migrate -``` +### Other ways of serving the app and dependencies -Prisma ORM can only query the database once you 'generate' the Prisma Client, which generates into `node_modules/.prisma/client`. This should happen when you install the JS dependencies and whenever you run a migration, but if the Prisma client gets out of sync or doesn't generate, you can manually generate it: +You can skip the build step for the **database** container (not the R API), and try to run an existing image, using this option: ```bash -npx prisma generate +scripts/run-dev-dependencies --db-build-skip ``` -Start the development server on `http://localhost:3000`: +If there is no need to install any npm packages or to run database migrations, you can serve the app in development mode with: ```bash npm run dev ``` -(Or see the 'production' section of this README for how to run the app in production mode.) - You can also expose it to your local network, so that you can try it out on a mobile device, using: ```bash @@ -80,6 +72,8 @@ npm run dev -- --host The QR code shown will allow you to quickly access the app. +See the 'production' section of this README for how to run the app in production mode. + ### DB Our ORM is [Prisma](https://www.prisma.io/). @@ -87,10 +81,16 @@ Our ORM is [Prisma](https://www.prisma.io/). To create migrations to the database, first update the Prisma schema at ./prisma/schema.prisma as required, then run the below command to generate the corresponding SQL migration and to apply it to the database. [You should commit both](https://www.prisma.io/docs/orm/prisma-migrate/workflows/team-development#source-control) the Prisma schema and the migration file to Git. ```bash -npx prisma migrate dev +npm run db:dev:migrate ``` -The same command is also used to apply migrations that already exist in ./prisma/migrations but which have not been applied to the database. It has been aliased for this purpose in package.json as `npm run db:dev:migrate`. +The same command is also used to apply migrations that already exist in ./prisma/migrations but which have not been applied to the database. + +Prisma ORM can only query the database once you 'generate' the Prisma Client, which generates into `node_modules/.prisma/client` based on the file `prisma/schema.prisma`. This should happen when you install the JS dependencies and whenever you run a migration, but if the Prisma client gets out of sync or doesn't generate, you can manually generate it: + +```bash +npx prisma generate +``` Prisma ORM can only query the database once you 'generate' the Prisma Client, which generates into `node_modules/.prisma/client` based on the file `prisma/schema.prisma`. This should happen when you install the JS dependencies and whenever you run a migration, but if the Prisma client gets out of sync or doesn't generate, you can manually generate it: diff --git a/package-lock.json b/package-lock.json index 8f911a68..a4097d54 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,10 +1,12 @@ { - "name": "nuxt-app", + "name": "daedalus-web-app", + "version": "0.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "nuxt-app", + "name": "daedalus-web-app", + "version": "0.0.1", "hasInstallScript": true, "dependencies": { "@amcharts/amcharts5": "^5.9.12", diff --git a/package.json b/package.json index 46fa6e24..8a886615 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "scripts": { "build": "nuxt build", "dev": "nuxt dev", + "dev:init": "npm install && npm run db:dev:migrate && npm run dev", "db:dev:migrate": "prisma migrate dev", "generate": "nuxt generate", "lint": "eslint .", From d4c216e782d5957b8847e6c126db2dd9787f960d Mon Sep 17 00:00:00 2001 From: David Mears Date: Tue, 30 Jul 2024 18:02:57 +0100 Subject: [PATCH 07/49] Use composable instead of 'util' for R API consumption --- components/SideBar.vue | 33 +++++++++++++++++++++++++-------- components/utils/rApi.ts | 30 ------------------------------ composables/useVersionData.ts | 22 ++++++++++++++++++++++ composables/utils/useRApi.ts | 29 +++++++++++++++++++++++++++++ 4 files changed, 76 insertions(+), 38 deletions(-) delete mode 100644 components/utils/rApi.ts create mode 100644 composables/useVersionData.ts create mode 100644 composables/utils/useRApi.ts diff --git a/components/SideBar.vue b/components/SideBar.vue index 6a455a5c..d92fe988 100644 --- a/components/SideBar.vue +++ b/components/SideBar.vue @@ -51,9 +51,31 @@