# VBV Lernwelt Project setup is based on [cookiecutter-django](https://github.com/cookiecutter/cookiecutter-django) project template. ## Run for development ```bash # run vue vite dev server cd client && npm run dev # reset db and run django dev server ./prepare_server.sh # if you only want to create some specific courses to speed up the script, # you can use the '--courses' parameter # see consts.py for available course ids # ./prepare_server.sh --courses -3 -5 ``` ## Installation See `.tool-versions` file for used django and node version You have to set up at least the following environment variables: ```bash export IT_APP_ENVIRONMENT=local ``` See `.env_secrets/local_daniel.env` for more possible environment variables. Especially set correct values for `POSTGRES_*` and `DATABASE_URL` Install git-lfs ```bash brew install git-lfs git lfs install ``` ### Server part Install python dependencies: ```bash pip install -r server/requirements/requirements-dev.txt ``` The "prepare_server.sh" script will create the database according to `POSTGRES_*` environment variables. It will also setup the tables for django and run the django development server. ```bash # will run `migrate` and `runserver` etc... ./prepare_server.sh # or async server # uvicorn config.asgi:application --host 0.0.0.0 --reload ``` ### Client part ```bash cd client npm install # run dev server npm run dev ``` ### General part Cypress is installed for client and server, so there is this package.json on the project root directory ```bash # in project root directory npm install ``` ### Git hooks ```bash # install pre-push git hook # add this line to the existing script in .git/hooks/pre-push ./git-pre-push.sh ``` ### Actions on Save You can enable some useful "Actions on Save" in your JetBrains IDE: Preferences -> Tools -> Actions on Save * Reformat Code * Optimize Imports * Run eslint --fix * Run prettier ## Translations We use (Locize)[https://locize.com] (see 1Password for credentials) together with (i18next)[https://www.i18next.com/] for translations on the Frontend. Please make sure that the required environment variables are set (see ./env_secrets/local_daniel.env for the values): * LOCIZE_PROJECT_ID * LOCIZE_API_KEY The master for translated files is on Locize! That means, that the app will take the translations/texts from Locize to show in the app. The files in ./client/locales are only used as reference and are not the master! There are multiple ways on how to add new translations to Locize: ### Process one: Let Locize add missing keys automatically When running the app, it will automatically add the missing translation keys to Locize. There you can translate them, and also add the German translation. ### Process two: Add keys manually You can add the new keys manually to the German locale file in ./client/locales/de/translation.json Then you can run the following command to add the keys to Locize: ### Helpers The following command could help find missing and/or unused keys. But manual review is still needed. ```bash npx vue-i18n-extract report --vueFiles './src/**/*.?(ts|vue)' --languageFiles './src/locales/**/*.?(json|yml|yaml)' ``` ```bash npm run locize:sync ``` The command will add the keys and the German translation to Locize. Bonus: Use the "i18n ally" plugin in VSCode or IntelliJ to get extract untranslated texts directly from the code to the translation.json file. ### "_many" plural form in French and Italian See https://github.com/i18next/i18next/issues/1691#issuecomment-968063348 for an explanation why this plural form is needed in French and Italian. But not in German and English. ## Deployment to CapRover ### CapRover Dev (vbv-lernwelt.control.iterativ.ch) ``` # run deploy script ./caprover_deploy.sh vbv-lernwelt # of vbv-lernwelt is default value ./caprover_deploy.sh ``` ### CapRover Stage (myvbv-stage.iterativ.ch) ``` ./caprover_deploy.sh myvbv-stage ``` ### CapRover Prod (myvbv.iterativ.ch) ``` ./caprover_deploy.sh myvbv ``` ### CapRover feature branch deployment You can deploy every feature branch to CapRover directly from Bitbucket Pipelines with a manual step. When you run caprover_deploy.sh without arguments, it will deploy the current branch ``` ./caprover_deploy.sh ``` ### Cleanup caprover feature branch deployments ```bash # by default it will delete all vbv-feature-* apps python caprover_cleanup.py # or specify a specific app regex and delete without confirmation python caprover_cleanup.py --automated -a 'vbv-bugfix*' ``` ## IntelliJ Configuration * In the .idea/vbv_lernwelt.iml file change the module type to "PYTHON_MODULE". * Add django facet in "Project Structure". * Run configuration with "Python -> server.py" to have async debugging support. ### Optional #### Install the EnvFile Plugin ![](docs/envfile_plugin_settings.png) #### Install the tailwind css Plugin from Jetbrains ## currents.dev This project uses [currents.dev](https://currents.dev) to run the Cypress tests concurrently. The following steps were taken to set it up: - Create a new project on currents.dev - Add the generated `projectId` to the cypress configuration file - Install `@currents/cli` as a dev dependency - Add the following script to the `package.json` file: ```json "cypress:ci": "currents run --parallel --record --key $CURRENTS_KEY", ``` - Create a new Bitbucket pipelines job that exports the `CURRENTS_KEY` and runs the `cypress:ci` script - Refactor the pipeline steps so that the dependencies are installed first and then the other steps are run in parallel. You can then run multiple instances of the previously created job in parallel. See `.bitbucket-pipelines.yml` for an example. > 💡 The number of cypress worker jobs depends on the number of cypress tests. > Too many workers for too few tests will result in a lot of idle workers. ## Frontend folder structure There are some rules when it comes to the folder structure of the frontend. - Every page should have its own folder in the `pages` folder. - A page component name must have the `Page` suffix. E.g. `MyPage.vue`. - A page is defined by being a routing target. - The components solely being used in a page should be in the same folder as the page. ``` 📦 client └─ pages    ├─ AbcPage.vue    ├─ AbcButton.vue    └─ AbcListTile.vue ``` ## GraphQL When you change something on the server side run the following command to update the graphql schema: ```bash python manage.py graphql_schema ``` On the client side you have to run the following command to update the generated code ```bash npm run codegen ``` 💡 If you run `npm run dev`, the codegen command will be run automatically in watch mode." ### Open Questions - The `id` field has to be a string? - Is running `codegen` a prerequisite so that it even works? - What about the generated types from `codegen`? Hand written types seem to be better. - The functions is `cacheExchange` should be nearer the concrete implementation