{"id":19847292,"url":"https://github.com/cds-snc/notification-admin","last_synced_at":"2025-05-01T21:32:18.526Z","repository":{"id":37462208,"uuid":"194916028","full_name":"cds-snc/notification-admin","owner":"cds-snc","description":"Notification Admin","archived":false,"fork":false,"pushed_at":"2024-10-29T15:01:26.000Z","size":56500,"stargazers_count":19,"open_issues_count":27,"forks_count":12,"subscribers_count":21,"default_branch":"main","last_synced_at":"2024-10-29T15:56:46.542Z","etag":null,"topics":["alpha","notification-canada-ca","notify-core"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cds-snc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-07-02T18:33:19.000Z","updated_at":"2024-10-29T13:37:55.000Z","dependencies_parsed_at":"2024-03-14T14:48:34.983Z","dependency_job_id":"daaad2d7-fa6c-40d9-be7c-c62db9963e4d","html_url":"https://github.com/cds-snc/notification-admin","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cds-snc%2Fnotification-admin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cds-snc%2Fnotification-admin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cds-snc%2Fnotification-admin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cds-snc%2Fnotification-admin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cds-snc","download_url":"https://codeload.github.com/cds-snc/notification-admin/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224278368,"owners_count":17285080,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["alpha","notification-canada-ca","notify-core"],"created_at":"2024-11-12T13:13:57.970Z","updated_at":"2025-05-01T21:32:18.518Z","avatar_url":"https://github.com/cds-snc.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Notifications-admin\n\nNotifications admin application.\n\n\n## Upstream\n\nThis repo is a clone / modifed version of:\nhttps://github.com/alphagov/notifications-admin\n\n\n## Features of this application\n\n - Register and manage users\n - Create and manage services\n - Send batch emails and SMS by uploading a CSV\n - Show history of notifications\n\n\n## Functional constraints\n\n- We currently do not support sending of letters\n- We currently do not receive a response if text messages were delivered or not\n\n\n## First-time setup\n\n[Brew is a package manager](https://brew.sh/) for OSX. The following command installs brew:\n```shell\n    /bin/bash -c \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\"\n```\n\nLanguages needed\n- Python 3.12\n- [Node](https://nodejs.org/) 10.15.3 or greater\n- [npm](https://www.npmjs.com/) 6.4.1 or greater\n\n```shell\n    brew install node\n```\n\n[NPM](npmjs.org) is Node's package management tool. `n` is a tool for managing\ndifferent versions of Node. The following installs `n` and uses the long term support (LTS)\nversion of Node.\n\n```shell\n    npm install -g n\n    n lts\n    npm rebuild node-sass\n```\n\n\n### Local installation instruction\n\nOn OS X:\n\n1. Install PyEnv with Homebrew. This will preserve your sanity.\n\n`brew install pyenv`\n\n2. Install Python 3.12.7 or whatever is the latest\n\n`pyenv install 3.12.7`\n\n3. If you expect no conflicts, set `3.12.7` as you default\n\n`pyenv global 3.12.7`\n\n4. Ensure that version `3.12.7` is now the default by running\n\n`python --version`\n\nIf it did not, add to your shell rc file. ex: `.bashrc` or `.zshrc`\n```\neval \"$(pyenv init --path)\"\neval \"$(pyenv init -)\"\n```\nand open a new terminal.\n\nIf you are still not running Python 3.12.7 take a look here: https://github.com/pyenv/pyenv/issues/660\n\n5. Install `poetry`:\n\n`pip install poetry==1.3.2`\n\n6. Restart your terminal and make your virtual environtment:\n\n`mkvirtualenv -p ~/.pyenv/versions/3.12.7/bin/python notifications-admin`\n\n7. You can now return to your environment any time by entering\n\n`workon notifications-admin`\n\n8. Find the appropriate env variables and copy them into the .env file. A sane set of defaults exists in `.env.example` in the root folder. If you are working for CDS you should use the ones in the LastPass folder. If using from lastPass and running the API locally, change API_HOST_NAME to point to your local machine\n\n9. Install all dependencies\n\n`pip3 install -r requirements.txt`\n\n10. Generate the version file ?!?\n\n`make generate-version-file`\n\n11. Generate the translations\n\n`make babel`\n\n12. Install npm and build the assets\n\n`npm install` followed by `npm run build`\n\n13.  Run the service\n\n`flask run -p 6012 --host=localhost`\n\n14. To test\n\n`pip3 install -r requirements_for_test.txt`\n\n`make test`\n\n\n## Rebuilding the frontend assets\n\nIf you want the front end assets to re-compile on changes, leave this running\nin a separate terminal from the app\n\n```shell\n    npm run watch\n```\n\n\n## Updating application dependencies\n\n`poetry.lock` file is generated from the `pyproject.toml` in order to pin\nversions of all nested dependencies. If `pyproject.toml` has been changed (or\nwe want to update the unpinned nested dependencies) `poetry.lock` should be\nregenerated with\n\n```\npoetry lock --no-update\n```\n\n`poetry.lock` should be committed alongside `pyproject.toml` changes.\n\n\n## Working with static assets\n\nWhen running locally static assets are served by Flask at http://localhost:6012/static/…\n\nWhen running on preview, staging and production there’s a bit more to it:\n\n![notify-static-after](https://user-images.githubusercontent.com/355079/50343595-6ea5de80-051f-11e9-85cf-2c20eb3cdefa.png)\n\n\n## Translations\n\n- Wrap your template text\n\n```\n\u003ch1\u003e{{ _('Hello') }}\u003c/h1\u003e\n```\n\n- For form hints\n\nSet a variable\n\n```\n \u003cdiv class=\"extra-tracking\"\u003e\n  {% set hint_txt = _('We’ll send you a security code by text message') %}\n  {{textbox(form.mobile_number, width='3-4', hint=hint_txt) }}\n \u003c/div\u003e\n```\n\nFor forms\n\n```\nfrom flask_babel import _\n```\n\nWrap your text\n\n```\n_('Your text here')\n```\n\nFor JavaScript\n\n```\n// add your text to main_template\nwindow.APP_PHRASES = {\n  now: \"{{ _('Now') }}\",\n}\n```\n\n```\n// in your JS file\nlet now_txt = window.polyglot.t(\"now\");\n```\n\n- Extract\n\nCurrently this is a manual step. Add a row to `fr.csv` in `app/translations/csv/` for each new string you have wrapped. The format is: `\"wrapped string\",\"translation\"`. Make sure the wrapped string you are adding is unique.\n\n- Compile\n\n```bash\nmake babel\n```\n\n- Testing\n\nSome typos in the `fr.csv` file might not be caught by `babel` but will lead to incorrect or missing French text in the app. To test for the kinds of typos we’ve encountered before, run:\n```bash\nmake test-translations\n```\nNote that this make target is always run during our CI process and will fail if any problems are detected when pushing changes.\n\n## Using Local Jinja for testing template changes\n\nSee the [notification-api](https://github.com/cds-snc/notification-api) README for detailed instructions.\n\nTemplate files used in this repo: `sms_preview_template.jinja2, email_preview_template.jinja2`\n\nNote: Tests may break if `USE_LOCAL_JINJA_TEMPLATES` is set to `True` in your .env\n\n\n## Redis\n\nYou need a [redis](https://redis.io/) server running to use certain parts of Notify, such as the \"go live\" flow. To use redis, add `REDIS_ENABLED=1` to your .env file and run the following command:\n\n```bash\nredis-server\n```\n\n## Testing\n\nThere are testing utilities available through the project.\n\n### Trigger an exception on purpose\n\nIt is sometimes useful to trigger an exception for testing purposes (logger format,\nmultiline log behavior, etc.). To do so, you can hit the `_debug?key=DEBUG_KEY` endpoint.\nThe `DEBUG_KEY` should be defined in the environment's configuration, sourced at the\napplication' startup. When that endpoint is reached with the proper `DEBUG_KEY` secret,\na `500` HTTP error will be generated. When an incorrect or empty secret is provided, a classic '404'\nnot found error will get returned.\n\n## Static resource build pipeline\n```mermaid\ngraph LR\n    subgraph tw[Tailwind]\n        direction TB\n        TW1[Compile CSS @imports]\n        TW1 --\u003e TW2[Remove unused CSS]\n        TW2 --\u003e TW3[Minify CSS]\n    end\n\n    subgraph js[Webpack / JS Pipeline]\n        direction TB\n        J0[style-loader: extract CSS from JS]\n        J0 --\u003e J1[babel-loader: Convert ES6+ to ES5]\n        J1 --\u003e J2[minification: Compress JS]\n    end\n\n    subgraph Gulp[Gulp]\n        \n        \n        subgraph Assets\n            direction TB\n            E1[Copy Images] --\u003e E2\n            E2[Copy Fonts] --\u003e E3\n            E3[Copy Gov Assets]\n        end\n        \n        subgraph JavaScript - all.min.js\n            direction TB\n            D1[Concatenate most internal js files] --\u003e D2\n            D2[Babel plugin] --\u003e D3\n            D3[Concatenate js from libs we depend on] --\u003e D4\n            D4[Minify] --\u003e D5\n            D5[Output to /static/javascripts/all.min.js]\n        end\n        \n        subgraph JavaScript - indiviual components\n            direction TB\n            JS2[Babel plugin] --\u003e JS4\n            JS4[Minify using Uglify] --\u003e JS5\n            JS5[Output invidual files to /static/javascripts]\n        end\n        \n        subgraph CSS\n            direction TB\n            C1[Minify using cleanCSS] --\u003e C3\n            C3[Output to /static/stylesheets/index.css]\n        end\n    end\n    tw --\u003e js --\u003e Gulp\n```\n\n=======\n\n\n# Notifications-admin\n\nApplication d'administration des notifications.\n\n## Branche amont (_upstream_)\n\nCe dépôt Git est une version modifiée de :\nhttps://github.com/alphagov/notifications-admin\n\n## Caractéristiques de cette application\n\n- Enregistrer et gérer les utilisateurs\n- Créer et gérer des services\n- Envoyer des courriels et des SMS par lots en téléversant un CSV\n- Afficher l'historique des notifications\n\n## Contraintes fonctionnelles\n\n- Nous ne pouvons pas actuellement envoyer des lettres\n- Nous ne pouvons pas savoir si les SMS ont été délivrés ou non\n\n## Première mise en place\n\n[Brew est un gestionnaire de paquets]((https://brew.sh/)) pour OSX. La commande suivante permet d'installer brew :\n```shell\n/bin/bash -c \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\"\n```\n\nLangages nécessaires\n- Python 3.12\n- [Node](https://nodejs.org/) 10.15.3 ou supérieur\n- [npm](https://www.npmjs.com/) 6.4.1 ou plus\n```shell\nbrew install node\n```\n\n[NPM](npmjs.org) est l'outil de gestion des paquets de Node. `n` est un outil de gestion des\ndifférentes versions de Node. Ce qui suit installe `n` et utilise le support à long terme (LTS)\nversion de Node.\n```shell\nnpm install -g n\nn lts\nnpm rebuild node-sass\n```\n\n### Instruction d'installation locale\n\nSur macOS :\n\n1. Installer PyEnv avec Homebrew. Cela vous permettra de préserver votre santé mentale.\n\n`brew install pyenv`\n\n1. Installez Python 3.12.7 ou la dernière version\n\n`pyenv install 3.12.7`\n\n3. Si vous n'attendez aucun conflit, mettez `3.12.7` comme valeur par défaut\n\n`pyenv global 3.12.7`\n\n4. Assurez-vous que la version 3.12.7 est maintenant la version par défaut en exécutant\n\n`python --version`\n\nSi ce n’est pas le cas, ajoutez les lignes suivantes à votre fichier shell rc. ex : `.bashrc` ou `.zshrc`\n```\neval \"$(pyenv init --path)\"\neval \"$(pyenv init -)\"\n```\net ouvrez un nouveau terminal.\nSi vous n’utilisez toujours pas Python 3.12.7, jetez un coup d’œil ici : https://github.com/pyenv/pyenv/issues/660\n\n5. Installez `virtualenv` :\n\n`pip install virtualenvwrapper`\n\n6. Ajoutez ce qui suit à votre `.bashrc` ou `.zshrc`\n\n```\nexport WORKON_HOME=$HOME/.virtualenvs\nexport PROJECT_HOME=$HOME/Devel\nsource ~/.pyenv/versions/3.12.7/bin/virtualenvwrapper.sh\n```\n\n7. Redémarrez votre terminal et créez votre environnement virtuel :\n\n`mkvirtualenv -p ~/.pyenv/versions/3.12.7/bin/python notifications-admin`\n\n8. Vous pouvez maintenant retourner dans votre environnement à tout moment en entrant\n\n`workon notifications-admin`\n\n9. Trouvez les variables env appropriées et copiez-les dans le fichier .env. Un ensemble de valeurs par défaut existe dans le fichier `.env.example` à la racine ou vous pouvez utiliser celles du dossier LastPass. Si vous utilisez celles de LastPass et que vous exécutez l'API localement, modifiez `API_HOST_NAME` pour qu'elle pointe vers votre machine locale\n\n10. Installer toutes les dépendances\n\n`pip3 install -r requirements.txt`\n\n11. Générer le fichier de version\n\n`make generate-version-file`\n\n12. Générer les traductions\n\n`make babel`\n\n13. Installer les dépendances npm et construire les actifs\n\n`npm install` suivi de `npm run build`.\n\n14.  Démarrer le service\n\n`flask run -p 6012 --host=localhost`.\n\n15. Pour tester\n\n`pip3 install -r requirements_for_test.txt`\n\n`make test`\n\n## Reconstruire les fichiers CSS et JS du frontend\n\nSi vous souhaitez que les fichier JS et CSS soient recompilés en fonction des changements, laissez tourner cette fonction dans un terminal séparé de l'application\n```shell\nnpm run watch\n```\n\n## Mise à jour des dépendances des applications\n\nLe fichier `requirements.txt` est généré à partir du fichier `requirements-app.txt` afin d'épingler des versions de toutes les dépendances imbriquées. Si `requirements-app.txt` a été modifié (ou nous voulons mettre à jour les dépendances imbriquées non épinglées) `requirements.txt` devrait être régénérée avec\n\n```\nmake freeze-requirements\n```\n\nLe fichier `requirements.txt` doit être ajouté en même temps que les modifications du fichier `requirements-app.txt`.\n\n\n## Travailler avec des fichier statiques\n\nLorsque utilisé localement, les fichiers statiques sont servis par Flask à http://localhost:6012/static/...\n\nLorsque en production ou sur staging, c'est un peu plus compliqué:\n\n![notify-static-after](https://user-images.githubusercontent.com/355079/50343595-6ea5de80-051f-11e9-85cf-2c20eb3cdefa.png)\n\n\n## Traductions\n\n- Le texte dans le code est en anglais\n- Enveloppez votre texte avec `{{ }}`\n- Les traductions sont dans `app/translations/csv/fr.csv`\n\n```\n\u003ch1\u003e{{ _('Hello') }}\u003c/h1\u003e\n```\n\n- Pour des conseils sur les formulaires\n\nCrée une variable\n\n```\n \u003cdiv class=\"extra-tracking\"\u003e\n  {% set hint_txt = _('We’ll send you a security code by text message') %}\n  {{textbox(form.mobile_number, width='3-4', hint=hint_txt) }}\n \u003c/div\u003e\n```\n\nPour les formulaires\n\n```\nfrom flask_babel import _\n```\n\nEnveloppez votre texte\n```\n_(\"Votre texte ici\")\n```\n\nPour JavaScript\n\n```\n// ajoutez votre texte au main_template\nwindow.APP_PHRASES = {\n  now: \"{{ _('Now') }}\",\n}\n```\n\n```\n// dans vos fichier JS\nlet now_txt = window.polyglot.t(\"now\") ;\n```\n\n- Extrait\n\nActuellement, il s'agit d'une étape manuelle. Ajoutez une ligne à `fr.csv` dans `app/translations/csv/` pour chaque nouvelle  de charactère que vous avez enveloppée. Le format est le suivant : `\"Texte Anglais\", \"traduction\"`. Assurez-vous que la chaîne enveloppée que vous ajoutez est unique.\n\n- Compiler\n\n```Bash\nmake babel\n```\n\n- Tester\n\nCertaines erreurs de frappe dans le fichier `fr.csv` pourraient ne pas être détectées par `babel` mais entraîneraient des changements incorrects ou du texte manquant en français dans l’application. Pour tester contre ces types d’erreurs de frappe qu’on a vu dans le passé, exécutez :\n```bash\nmake test-translations\n```\nCette cible make est toujours exécutée pendant le processus d’intégration continue et échouera si des problèmes sont détectés lorsqu’on pousse le code.\n\n## Utiliser Jinja localement pour tester les changements de modèles\n\nVoir le dépôt [notification-api](https://github.com/cds-snc/notification-api) README pour des instructions détaillées.\n\nFichiers de modèles utilisés dans ce dépôt : `sms_preview_template.jinja2, email_preview_template.jinja2`\n\nNote : les tests peuvent échouer si `USE_LOCAL_JINJA_TEMPLATES` est réglé sur `True` dans votre `.env`\n\n## Tests\n\nIl y a quelques utilitaires de tests qui sont disponibles dans le projet.\n\n### Déclencher une erreur de façon intentionnelle\n\nIl est quelques fois pratique de déclencher une erreur pour des buts de tests (format\ndu log, comportement multiligne du log, etc.). Pour se faire, vous pouvez accéder à l'URL\n`_debug?key=DEBUG_KEY`. Le secret `DEBUG_KEY` devrait être défini dans la configuration\nde l'environnement lors du démarrage de l'application. Quand cet URL sera accédé avec\nle bon secret `DEBUG_KEY`, une erreur HTTP `500` sera générée. Sans ce secret ou avec\nune valeur invalide, une erreur `404` de page non-trouvée sera alors produite.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcds-snc%2Fnotification-admin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcds-snc%2Fnotification-admin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcds-snc%2Fnotification-admin/lists"}