Architecture

Backend

Change ProjectName or to your desired name in the following instances:

django/
         manage.py
         ProjectName/   <--- RENAME
                 __init__.py
                 settings.py
                 urls.py
                 wsgi.py

settings.py

ROOT_URLCONF = 'NewProjectName.urls'
WSGI_APPLICATION = 'NewProjectName.wsgi.application'
SWAGGER_SETTINGS = { 'DEFAULT_INFO': 'NewProjectName.urls.api_info' }

wsgi.py

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "NewProjectName.settings")

manage.py

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "NewProjectName.settings")

celery.py

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "NewProjectName.settings")
app = Celery("NewProjectName", set_as_current=True)

pytest.ini

DJANGO_SETTINGS_MODULE=NewProjectName.settings

dotenv

We use .env settings for the private settings, there’s a template for it called .env.template

cp .env.template .env

Docker Compose

We use docker compose to orchestrate our architecture, issue the following commands to build and download all the containers needed.

docker-compose build
docker-compose up

creating a virtualenv

mkvirtualenv mkvirtualenv --python=`which python3` v-env-name
workon v-env-name

local scripts and remote execution with Fabric3

Use the fab command from the project root. Use a virtualenv, like specified above.

pip install -r ../requirements_local.txt

OpenAPI Schema generator and change reviewer

This will generate swagger.json and see if anything changed in your endpoints. Use this to inform the frontend team that something’s been changed, added, removed.

fab openapi

PR/Migrations strategy

  • IF your PR contains DATA migrations, COMMIT all the migrations in your branch

  • Data migrations MUST NOT containt the string # Generated by Django else CircleCI will fail

  • IF your PR contains autogenerated SCHEMA migrations (with makemigrations):

    1. DO NOT COMMIT any migrations to the PR, but push everything else

    2. If the PR is green, ask a reviewer for a review

  • IF you are reviewing a PR:

    • Decline any PRs that have migration files

    • If you want to try the code out:

      1. checkout branch

      2. run fab makemigrations

      3. run fab migrate

      4. review the code and data consistency

    • Merge PR then:

      1. run fab makemigrations

      2. run fab migrate

      3. commit and push migrations

  • IF you are the one whose PR got merged or you are the reviewer who checked out the code and migrations and want to keep data:

    • migrate --fake the migrations, because they already exist in your DB

SSL setup through Docker-Compose with certbot

Tutorial

Frontend

This is a project based on NuxtJS 2 and Element UI library.

Requirements

It is recommended to prepare the following tools and packages.

  • Node.js v15.8.0 (might work with newer versions too).

  • yarn as package manager.

  • Visual studio code, recommended, not an obligation. Recommended extensions:

  • nvm is a node version manager that will allow you to manage your node versions easily for projects with a .nvmrc attached to the projects. For a deeper integration and automated use of nvm use when you enter in the project folder, check this out. (this is not working on Windows machines though)

  • Docker, docker is used a lot.

  • On Windows machines further tools might be needed

    • Power Shell 7 because of proper UTF-8 handling (sql dumps and other scripts)

    • WSL 2 with Ubuntu 20

Data flow

Nuxt Directory Structure is used throughout the application. So far no custom directory was needed.

Store

We are using default Nuxt store management system (store folder). Further information can be found in the official documentation. Stores:

  • charts: used in displaying phases

  • countries: stores the country list and data that is used for the map

  • dashboard: contains data for the inventory list and search components

  • filters: used to manage saved filters in search component

  • landing: landing page map, search, news feed

  • layout: dialog states

  • matrixes: portfolio matrix

  • offices: office lists

  • portfolio: portfolio related data (lists, columns etc.)

  • project: current display or edited project

  • projects: project lists

  • search: search fields

  • system: system store

  • user: logged in user profile and account actions

Server calls

No central service or repository system is used in the project, calls to the servers are used where they’re needed via the nuxt/axios module.
In the axios.js plugin the token and language is set in the onRequest interceptor before initiating the call.

Middleware

There’s not many or complex middleware in the application. The order of the middlewares are defined in nuxt.config.js

middleware: ['auth', 'reset', 'tracking'],
  • auth: check if user is logged on

  • defaultOrg: set default organisation

  • importRestriction: route guard for the import page

  • isLoggedIn: if not authenticated, redirect to login page

  • languageCheck: try to set the application language to match the user’s profile

  • permissions: route guard for the portfolio pages

  • profile: redirect new users to profile page

  • reset: guest users (not logged in) are allowed to auth, login and reset password pages

  • tracking: set userid to matomo tracking service

Plugins

  • axios: axios interceptor

  • charts: provide the LineChart as global component

  • directives: click outside and paste directives used for TeamSelector component

  • element: register Element UI and some custom components globally

  • filters: vue filters (simpleDateFormat, formatNumber)

  • i18n: register global translate component

  • vee-validate: a special fix, see comment

  • vue-leaflet: register leaflet map components globally

  • vuex-geolocation: register vuex-geolocation globally

  • watchHead: fix for a strange issue (find more info in the code)