324 lines
8.4 KiB
Markdown
324 lines
8.4 KiB
Markdown
# 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 and Environments
|
||
|
||
### Prod Environment on Azure
|
||
|
||
Bitbucket Pipelines name: prod-azure
|
||
https://my.vbv-afa.ch/
|
||
|
||
Deployment step on Bitbucket Pipelines will build the Docker container for Azure.
|
||
It seems that right now, you have to make a manual step on Azure to use this new
|
||
Docker container and update it on Azure.
|
||
Please ask Lorenz for more information.
|
||
|
||
#### Prod Monitoring on New Relic
|
||
|
||
See docs/new-relic.md
|
||
|
||
### CapRover vbv-develop
|
||
|
||
Bitbucket Pipelines name: develop
|
||
https://vbv-develop.control.iterativ.ch/
|
||
|
||
Deployment happens automatically on every push to develop branch.
|
||
|
||
### CapRover vbv-master
|
||
|
||
Bitbucket Pipelines name: master
|
||
https://vbv-master.control.iterativ.ch/
|
||
Deployment happens automatically on every push to master branch.
|
||
|
||
### CapRover myvbv-stage
|
||
|
||
Bitbucket Pipelines name: stage
|
||
https://myvbv-stage.control.iterativ.ch/
|
||
https://myvbv-stage.iterativ.ch/
|
||
|
||
Deployment happens manually via Bitbucket Pipelines
|
||
|
||
### CapRover myvbv (old prod)
|
||
|
||
Bitbucket Pipelines name: myvbv
|
||
https://myvbv.control.iterativ.ch/
|
||
https://myvbv.iterativ.ch/
|
||
|
||
Deployment happens manually via Bitbucket Pipelines
|
||
|
||
|
||
### 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
|
||
|
||

|
||
|
||
#### 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
|
||
|
||
```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
|
||
|
||
# `npm run dev` includes `npm run codegen` as step...
|
||
npm run dev
|
||
```
|
||
|
||
If you run `npm run dev`, the codegen command will be run automatically in watch mode.
|
||
|
||
For the `ObjectTypes` on the server, please use the postfix `ObjectType` for types,
|
||
like `LearningContentAttendanceCourseObjectType`.
|
||
|
||
This will prevent problems with the hand written types on the client side,
|
||
when `npm run codegen` will create the types automatically.
|
||
|
||
When you change something on the server side run the following command to update the
|
||
graphql schema.
|
||
|
||
### Open Questions
|
||
|
||
- The `id` field has to be a string?
|
||
- What about the generated types from `codegen`? Hand written types seem to be better.
|
||
- The functions in `cacheExchange` should be nearer the concrete implementation...
|
||
|
||
## Load prod data for testing
|
||
|
||
1. Checkout the [vbv-devops](https://bitbucket.org/iterativ/iterativ-devops/src/master/) repository
|
||
2. Change into the `backups` directory
|
||
3. Run `python3 check_vbv_backup.py`. This downloads the latest backup from S3 and restores it to the `vbv-lernwelt` database.
|
||
4. Reset all user passwords. Open `shell_plus` in the `server` directory of the `vbv_lernwelt` repository and run
|
||
|
||
```python
|
||
for csu in CourseSessionUser.objects.all():
|
||
csu.user.set_password("test")
|
||
```
|