Skip to content
IN EARLY DEVELOPMENT - Online form for Medical Report for Canada Pension Plan Disability (CPPD). Form ISP-2519. | Prototype en évolution - Formulaire en ligne du rapport médical pour une prestation d'invalidité du Régime de pensions du Canada (RPC). Formulaire ISP-2519.
JavaScript HTML CSS Vue Dockerfile
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.
api MA View Application (#94) Jan 15, 2020
assets MA View Application (#94) Jan 15, 2020
migrations Naming conventions and linting (#50) Jan 2, 2020
sessions Add declaration section (#31) Dec 27, 2019
tasks sails new app Dec 6, 2019
.editorconfig sails new app Dec 6, 2019
.env.example Adds Redis to Docker Compose (#56) Jan 7, 2020
.gitignore Adds Redis to Docker Compose (#56) Jan 7, 2020
Gruntfile.js sails new app Dec 6, 2019 todo Dec 11, 2019
app.js Add dotenv for env vars (#47) Dec 30, 2019
app.json Make Heroku stack 'container' (#40) Dec 30, 2019
heroku.yml Make Heroku stack 'container' (#40) Dec 30, 2019
package-lock.json Add dotenv for env vars (#47) Dec 30, 2019
postcss.config.js Supporting documents (#22) Dec 27, 2019

Canada Pension Plan Disability (CPPD) - Medical Report (Form ISP-2519)

ESDC and CDS are working together to make CPPD better. We're focused on finding ways to shrink end-to-end processing time without decreasing the quality of decisions. We're currently building a prototype of the CPPD Medical Report as a way to explore some hypotheses and potentially make more of this process online.

For more information, contact us at

ESDC et la CDS travaillent ensemble pour améliorer le PPIRPC (programme de prestations d'invalidité du Régime de pensions du Canada). Nous travaillons à trouver des moyens de réduire le temps de traitement de bout en bout sans nuire à la qualité des décisions. Nous mettons actuellement au point un prototype du rapport médical sur le PPPC afin d’explorer certaines hypothèses et d’optimiser davantage ce processus en ligne.

Pour plus d'informations, contactez-nous à l'adresse

Built with

We have reused the nunjucks templates, SASS and related files from Node Starter.

Local development

Quickest way to get started is:

  • npm install
  • npm run dev

Note that you can use sails lift which will also bring up the server, but npm run dev runs with nodemon, for better file change monitoring.

There are additional instructions below for getting started with Docker. See also sections on Session store and Database.


To support Node Starter-style bilingual routes, we had to modify the way that routing works in Sails. Luckily, Sails provides some really useful ways to modify the underlying framework. As such, we've created a custom hook for routes.

Routes are defined in config/routes.js. The route format is backwards-compatible with the Sails router, and follows this format:

  'GET /en/start': {
    name: 'start',
    controller: 'StartController',
    action: 'index',
    lang: 'en',
    i18n: {
      en: '/en/start',
      fr: '/fr/debut'

You can also use dynamic route parameters:

  'GET /en/conditions/:id/edit': {
    name: 'conditions.edit',
    controller: 'EditConditionController',
    action: 'edit',
    lang: 'en',
    i18n: {
      en: '/en/conditions/:id/edit',
      fr: '/fr/conditions/:id/modifier'

And, of course, all the HTTP verbs you know and love are availabe, such as: GET,POST,PUT,DELETE,PATCH.

It is also possible to target SailsJS Actions instead of Controllers, but we prefer using Controllers, as they are more portable.

Named routes

We have also added a route helper for use in views (or res.locals) or controllers (on the sails object) so you can reference a route by name and not worry about the user's selected language. For example, using the example routes above, if you wanted to link to the start route:

<a href="{{ route('start') }}">Start</a>

or in a controller:


This will generate a link using the user's current language, ie: /en/start or /fr/debut.

You can pass route parameters in an object as the second argument to the route helper:

<a href="{{ route('conditions.edit', { id: [CONDITION_ID] }) }}">Edit</a>

You can also force the language if you need to:

<a href="{{ route('start', { lang: 'fr' }) }}">Début</a>


To generate a new Controller, use the sails generator: sails generate controller test. This command will generate an empty controller called TestController.js in the api/controllers folder.

Controllers can be organized in any number of ways. Typically in MVC frameworks, method names follow general "resourceful" conventions:

module.exports = {
  index: function (req, res) { ... },
  create: function (req, res) { ... },
  store: function (req, res) { ... },
  show: function (req, res) { ... },
  edit: function (req, res) { ... },
  update: function (req, res) { ... },
  delete: function (req, res) { ... },

The avid reader will notice that we've further divided our controllers up - this is a completely optional way of working, but we find more controllers with less code more readable/manageable.

Request validation

In order to enable validation in the controllers, we have added the validate.js package, along with a custom hook. To validate a request, create a schema file in api/schemas. See the Validate.JS documentation for details, but the simplest example to validate the presence of a field is:

module.exports = {
  conditionName: {
    presence: {
      allowEmpty: false,
      message: '^errors.name_of_condition.length'

Then, in your controller on the POST method (save or update), you can pass the request through the validate helper along with the schema, and then do something based on the result:

let valid = req.validate(req, res, require('../schemas/condition.schema'));

if (valid) {
  // do something

If the request fails validation, the validator will redirect the user back to their previous location. In addition, all of the validation errors and the form data will be flashed to the session. Errors will then be made available to the view as local variable errors, and the data will be available to the view as data.

Redis session store

Currently, the application data is stored in the session, and the default session store is in memory which clears out every time the process restarts. It can get annoying pretty quickly in development when the session store gets cleared out every time you make a change to a file.

To mitigate this, you can configure Redis as a persistent session store. If you've already got it running locally, say with homebrew, it's pretty easy to configure by setting an environment variable:

  • cp .env.example .env
  • there is no step two (see note)

Note: If you're running Redis on a non-standard port, or somewhere other than localhost, then you can set SESSION_ADAPTER_URL in that .env file.


Detailed instructions to follow, but the database is Postgres, and we use Sequelize for Models and Migrations in the application.


These instructions are optimized for development at the moment, rather than production runs.

This App Only


  1. Navigate into a cloned copy of this repo
  2. docker build -t cdssnc/cppd-medical-report-sails .


  1. docker run -it --rm -p 1337:1337 cdssnc/cppd-medical-report-sails

Dev Container + Database (Docker Compose)

This maps your local files into a Docker container, spins up a PostgreSQL database, and uses Redis for session storage. The app runs on port 1337, the database at port 5432 and username postgres, session stores on port 6379, and all are accessible at localhost.


  1. Build/fetch containers: docker-compose build
  2. Launch the application docker-compose up
  3. Setup the database: npm run db:migrate

When you want to stop both, you can hit CTRL + D in the terminal that launched it.

Using with VSCode Remote Containers

This lets your development environment in the Docker image that resembles production. It'll run both the database and session storage too.

  1. Start Docker locally
  2. Install the Remote Development extension pack
  3. Restart VSCode, opening it into this code base
  4. Open the command prompt (macOS: CMD+SHIFT+P, Win: CTRL+SHIFT+P), and choose Remote-Containers: Reopen in Container
  5. Choose From docker-compose.yml, then web (this might take a little bit of time at first start)
  6. After it fully starts up, use the terminal embedded inside of VSCode to issue commands within the main container (such as npm run dev)
  • You'll likely need to run things like npm run db:migrate and npm run dev to start going
You can’t perform that action at this time.