COVID Alert is now retired: For more information, visit the Government of Canada COVID Alert home page.
The COVID Alert Portal provides authenticated healthcare providers unique temporary codes which can be shared with COVID-diagnosed individuals. The code enables individuals to upload their random IDs via the mobile app if they choose. No personal information is collected by the app and there is no association between the codes and specific tests. The Portal complements the Government of Canada COVID Alert app.
A healthcare portal is one of the three pieces of the COVID Shield open-source reference implementation built by Shopify volunteers. For a high-level view on how the components work together, read through the COVID Shield Rationale.
The COVID Alert Business Registration Site is part of the Outbreaks feature of COVID Alert Portal. Outbreaks is a new feature developed to help public health and businesses in their contact tracing efforts. Business owners can register and print a poster that includes a QR Code. Visitors to their location that have COVID Alert installed on their device can scan the QR Code to record their visit. Subsequently, if public health authorites identify an Outbreak at that location, they can send alerts to people who may have been exposed through COVID Alert.
This project includes the code for both the COVID Alert Portal and the COVID Alert Business Registration Site, but the two websites are deployed separately, and this project can only be run in one mode or the other.
The mode of the project is determined by an Environment variable:
APP_SWITCH=QRCODE
will run the registration siteAPP_SWITCH=PORTAL
will run the portalThe COVID Alert Portal is a Django application: it can be run as a python process or using docker-compose
.
docker-compose
, you’ll need Docker installed.Environment variables are used to control app settings, and configuration for utilities and third-party services. Defaults are ''
or None
unless otherwise specified.
Before running the project, you will need to copy ./portal/.env.example
to ./portal/.env
and provide the appropriate values for your configuration.
This section describes how to get the project running on your local device. You can alternatively run using docker-compose which will include all required dependencies and services and may be a simpler setup depending on your preference and experience.
If you are running the app using Docker Compose, this dependency is already included. If you are running in a local virtual environment, you'll need to install cairo for PDF poster generation.
Using Homebrew on MacOS:
brew install cairo
Install pipenv
.
# cd into project folder
pipenv --three # create a new virtualenv
pipenv shell # activate virtualenv
pipenv install --dev # install dev dependencies
You will need to have a PostgreSQL database running. You can install one using Homebrew on MacOS:
brew install postgresql
NOTE: Earlier versions of this project would default to using a SQLite database if none is configured. Some features have been introduced in the Outbreaks feature that depend on features of PostgreSQL, so SQLite is no longer recommended.
Ensure that you have configured the DATABASE_URL
environment variable according to your PostgreSQL config, using the following format:
postgres://USER:PASSWORD@HOST:PORT/NAME
Migrate the database by running:
python manage.py migrate
When creating or modifying existing models, you will need to generate migrations to keep your database in sync:
python manage.py makemigrations
For more information, see Django Migrations.
To compile the SCSS files to CSS once:
pipenv run css
If you are developing the app and want your styling changes applied as you make changes, you can use the csswatch command:
pipenv run csswatch
This app allows you to use the Django admininstration panel (/admin
) to manage users.
In order to access the /admin
route, you will need to create a super user account to access the admin.
Run python manage.py createsuperuser
to create a super user.
Then, run python manage.py runserver
to run the app. Go to http://127.0.0.1:8000/
to see the login page.
Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration.
You can use Docker Compose to build an application container along with a Postgres database. It will map your local files into a Docker container, spin up a PostgreSQL database, and do CSS compilation and a DB migration. The app runs on port 8000
, the database at port 5432
(u: user
, p: password
) and will be served at http://0.0.0.0:8000
.
Read the step-by-step process at Django, Docker, and PostgreSQL Tutorial.
docker-compose up
Command + c
or docker-compose down
We're using the default Django translation library to add content in French and English.
When you have updated or added a new localized string, for example in a template file:
# profiles/templates/profiles/start.html
<h1>{% trans "Generate code for Exposure Notification app" %}</h1>
You will need to run the following command which will scan the the application for localized strings and add them to the locale files:
python manage.py makemessages -l fr --add-location=file --no-wrap
This command will collect all localized strings to the locale/django.po
file. For example:
# locale/fr/LC_MESSAGES/django.po
#: profiles/templates/profiles/start.html:7
msgid "Generate code for Exposure Notification app"
msgstr "Générer du code pour l'application de notification d'exposition"
Once the string has been translated in the .po file, you will need to compile the translations to the django.mo
file by running the following command:
python manage.py compilemessages
For more complete documentation refer to the Django Translation docs.
Feature development on the Portal follows a trunk-based development workflow. The main
branch has the most up-to-date code and is always production-ready. When starting a new feature (or a bugfix, etc.), a new branch is created from the tip of the main
branch. Once the work is complete, the feature is merged back into main
via a Pull Request (PR). PRs must pass a series of automated tests (unit tests, linting, etc), as well as a manual review by another developer. After the automated tests pass and the PR is approved, the code is merged into main
and the feature branch is deleted. The main
branch is protected from direct pushes or force pushes — pull requests are mandatory.
We keep the version number in a root-level VERSION
file and the list of changes between versions in the root CHANGELOG.md
file. We follow semantic versioning conventions and for the Changelog file we follow the format suggested by keepachangelog.com.
Not all PRs will update the app version — in fact, most of them don’t. PRs with new features or bug fixes require an update to the Changelog file, under “Unreleased”. When the version is next incremented, all of the unreleased changes are included as part of the version bump. It’s okay if something doesn’t make it into the Changelog when it is merged — CHANGELOG.md
is a file like any other and can be corrected retroactively.
Note that releasing a change to production requires incrementing the VERSION
file. The Changelog is kept up-to-date by convention, but it is not formally required to be in sync with the version in the VERSION file.
We are using GitHub Actions as our CI platform: it runs our automated tests for us and automates our deployments.
Our automated tests include:
pipenv run test
: Runs our suite of unit tests (on CI we run them in Python versions 3.6, 3.7, 3.8)pipenv run format --check
: uses the black
Python formatter to ensure consistency of our codepipenv run lint
: uses flake8
to ensure Python style guide complianceterraform plan
: if the terraform config has been modified, terraform plan
will return a diff of changes between the current infrastructure and the files in the PR.terraform security-scan
: will flag any unsafe configuration changesWe also have an automated test for code coverage, which will fail if code coverage falls below 80%. We are using the coverage
library, as recommended by the Django docs. Configuration for coverage
is found in pyproject.toml
.
pipenv run coverage_test
: run the unit tests to generate the reportpipenv run coverage_report
: display the reportAlerte COVID a été mis hors service. Pour en savoir davantage, visitez la: page d'accueil d’Alerte COVID du gouvernement du Canada.
Le portail Alerte COVID produit des codes uniques temporaires que les fournisseurs de soins de santé peuvent transmettre aux personnes ayant reçu un diagnostic positif de COVID-19. Le code permet à ces personnes de téléverser leurs identifiants anonymes à l’aide de l’application mobile. Aucune information personnelle n’est recueillie, et aucun lien n’est établi entre les codes et les tests Le portail complète l’application Alerte COVID du gouvernement du Canada.
Le portail des soins de santé est l’un des trois éléments du référentiel source ouvert COVID Shield développé par des bénévoles de Shopify. Pour une vue d’ensemble des interactions entre les composantes, lisez la justification de COVID Shield.
Le site d’inscription des entreprises d’Alerte COVID fait partie de la fonction éclosions du portail Alerte COVID. La nouvelle fonction éclosions a été développée pour aider les autorités de santé publique et les entreprises dans leurs efforts de recherche des contacts. Les propriétaires d’entreprise peuvent s’inscrire et imprimer une affiche qui comprend un code QR. Les gens qui ont installé Alerte COVID sur leur appareil et qui visitent un de ces lieux peuvent scanner le code QR pour enregistrer leur visite. Par la suite, si les autorités de santé publique déterminent qu’une éclosion s’est produite dans ce lieu, elles peuvent envoyer des alertes (à l’aide d’Alerte COVID) aux personnes qui pourraient avoir été exposées.
Ce projet comprend le code du portail Alerte COVID et du site d’inscription des entreprises d’Alerte COVID, mais les deux sites Web sont déployés séparément et ce projet ne peut être exécuté que dans un mode ou dans l’autre.
Le mode du projet est déterminé par une variable d’environnement :
APP_SWITCH=QRCODE
exécute le site d’inscriptionAPP_SWITCH=PORTAL
exécute le portailLe portail Alerte COVID est une application Django : elle peut être exécutée comme processus python ou à l’aide de docker-compose
.
docker-compose
, il faut d’abord installer Docker.Les variables d’environnement sont utilisées pour contrôler les paramètres de l’application et la configuration d’utilitaires et de services tiers. Les valeurs par défaut sont ''
ou None
, sauf indication contraire.
Avant d’exécuter le projet, vous devrez copier ./portal/.env.example
dans ./portal/.env
et fournir les valeurs appropriées pour votre configuration.
Cette section décrit comment exécuter le projet sur votre appareil local. Vous pouvez également exécuter l’application à l’aide de docker-compose qui comprend toutes les dépendances et tous les services requis. Cette configuration peut être plus simple, selon vos préférences et votre expérience.
Si vous exécutez l’application à l’aide de docker-compose, cette dépendance est déjà comprise. Si toutefois, vous exécutez l’application dans un environnement virtuel local, vous devez installer cairo pour générer les affiches PDF.
Utiliser Homebrew sur MacOS :
brew install cairo
Installez pipenv
.
# changez de répertoire (cd) pour accéder au répertoire de projet
pipenv --three # créez un nouveau virtualenv
pipenv shell # activez le virtualenv
pipenv install --dev # installez les dépendances dev
Vous devez exécuter une base de données PostgreSQL. Vous pouvez en installer une en utilisant Homebrew sur MacOS :
brew install postgresql
NOTE : Les versions antérieures de ce projet utilisaient une base de données SQLite par défaut si aucune base de données n’était configurée. Certaines fonctionnalités comprises dans la fonction éclosions dépendent des fonctionnalités de PostgreSQL. Les bases de données SQLite ne sont donc plus recommandées.
Assurez-vous d’avoir configuré la variable d’environnement DATABASE_URL
en fonction de votre configuration PostgreSQL, en utilisant le format suivant :
postgres://USER:PASSWORD@HOST:PORT/NAME
Migrez la base de données en exécutant :
python manage.py migrate
Lors de la création ou de la modification de modèles existants, vous devrez générer des migrations pour synchroniser votre base de données :
python manage.py makemigrations
Pour en savoir plus, consultez ce document d’aide sur les migrations Django (en anglais).
Pour compiler les fichiers SCSS en CSS une fois :
pipenv run css
Si vous développez l’application et souhaitez que vos modifications de style soient appliquées en effectuant des modifications, vous pouvez utiliser la commande csswatch :
pipenv run csswatch
Cette application vous permet d’utiliser le panneau d’administration Django (/admin
) pour gérer les utilisateurs.
Pour accéder au chemin d’accès /admin
, vous devez créer un compte super utilisateur.
Exécutez python manage.py createsuperuser
pour créer un super utilisateur.
Exécutez ensuite python manage.py runserver
pour lancer l’application. Accédez à http://127.0.0.1:8000/
pour afficher la page d’ouverture de session.
Compose est un outil permettant de définir et d’exécuter des applications Docker multiconteneurs. Avec Compose, un fichier YAML est utilisé pour configurer les services de votre application. Puis, avec une seule commande, tous les services sont créés et exécutés à partir de votre configuration.
Vous pouvez utiliser Docker Compose pour créer un conteneur d’applications avec une base de données Postgres. Docker Compose établira un lien entre vos fichiers locaux et un conteneur Docker; créera une base de données PostgreSQL, et effectuera une compilation CSS et une migration de base de données. L’application s’exécute sur le port 8000
, la base de données sur le port 5432
(u : utilisateur
, p : mot de passe
), et est traitée à l’adresse http://0.0.0.0:8000.
Lisez le processus étape par étape dans le tutoriel Django, Docker et PostgreSQL (en anglais).
docker-compose up
Command + c
ou docker-compose down
Nous utilisons la bibliothèque de traduction par défaut de Django pour ajouter du contenu en français et en anglais.
Lorsque vous mettez à jour ou ajoutez une nouvelle chaîne localisée, par exemple dans un fichier modèle :
# profiles/templates/profiles/start.html
<h1>{% trans "Generate code for Exposure Notification app" %}</h1>
Vous devez exécuter la commande suivante pour repérer les chaînes localisées et les ajouter aux fichiers de paramètres régionaux :
python manage.py makemessages -l fr --add-location=file --no-wrap
Cette commande collectera toutes les chaînes localisées dans le fichier locale/django.po
. Par exemple :
# locale/fr/LC\_MESSAGES/django.po
#: profiles/templates/profiles/start.html:7 msgid "Generate code for Exposure Notification app" msgstr "Générer du code pour l’application de notification d’exposition"
Une fois la chaîne traduite dans le fichier .po, vous devez compiler les traductions dans le fichier django.mo
en exécutant la commande suivante :
python manage.py compilemessages
Pour plus de détails, consultez la documentation de Django sur la traduction (en anglais).
Le développement des fonctionnalités sur le portail suit un flux de travail de développement basé sur un tronc commun (en anglais). La branche main
contient le code le plus à jour et est toujours prête pour la production. Lors de la création d’une nouvelle fonctionnalité (ou d’un correctif, etc.), une nouvelle branche est créée à partir de la pointe de la branche main
. Une fois le travail terminé, la fonctionnalité est fusionnée dans la branche main
au moyen d’une demande de tirage (pull request). Les demandes de tirage doivent subir une série de tests automatisés (tests unitaires, analyse statique, etc.), ainsi qu’une révision manuelle par un autre développeur. Une fois les tests automatisés terminés et la demande de tirage approuvée, le code est fusionné dans la branche main
et la branche de fonctionnalité est supprimée. La branche main
est protégée contre le fusionnement direct ou forcé — les demandes de tirage sont obligatoires.
Nous conservons le numéro de version dans un fichier racine VERSION
et le journal des modifications dans le fichier racine CHANGELOG.md
. Nous suivons les conventions de la gestion sémantique des versions pour l’application et le fichier Changelog suit le format suggéré par keepachangelog.com.
Les demandes de tirage ne mettent pas forcément à jour la version de l’application — en fait, la plupart d’entre eux ne le font pas. Les demandes de tirage avec de nouvelles fonctionnalités ou des correctifs nécessitent une mise à jour du fichier Changelog, sous « Unreleased ». Lors de la publication d’une nouvelle version, toutes les modifications non publiées sont incluses. Ne vous en faites pas si quelque chose ne figure pas dans le journal des modifications lorsqu’une branche est fusionnée - CHANGELOG.md
est un fichier tout à fait normal et peut être corrigé rétroactivement.
Notez que la publication d’une modification à l’environnement de production exige une nouvelle version du fichier VERSION
. Le journal des modifications est tenu à jour par convention, mais ne doit pas forcément être synchronisé avec la version du fichier VERSION.
Nous utilisons GitHub Actions comme plateforme d’intégration continue : elle nous permet d’exécuter nos tests automatisés et d’automatiser nos déploiements.
Nos tests automatisés comprennent :
pipenv run test
: Exécute notre suite de tests unitaires (pour l’intégration continue, nous les exécutons dans les versions Python 3.6, 3.7, 3.8)pipenv run format --check
: fait appel à l’outil de formatage Python black
pour assurer l’uniformité de notre codepipenv run lint
: fait appel à flake8
pour assurer la conformité au guide de style Pythonterraform plan
: si la configuration terraform a été modifiée, terraform plan
affichera les changements entre l’infrastructure actuelle et les fichiers dans la demande de tirage.terraform security-scan
: signalera tout changement de configuration dangereuxNous avons également un test automatisé pour la couverture du code, qui échoue si la couverture du code est inférieure à 80 %. Nous utilisons la bibliothèque coverage
, selon les recommandations dans la documentation de Django. La configuration de coverage
se trouve dans pyproject.toml
.
pipenv run coverage_test
: lance les tests unitaires pour générer le rapportpipenv run coverage_report
: affiche le rapport