Skip to main content

Back end

Database

RMT shares a database with our parent app, DB Manager. Please look there for full documentation. From the DB Manager database, RMT uses these tables: database schema showing 4 connected database tables: countries, disease_status, mitigation_measures, and risk_scores

Testing

If you'd like to test routes in Postman, you will first need to "log in". To do this:

  1. POST localhost:5800/api/auth/login with req. body in this format (ask the team for the admin login info):
{
"email": "string",
"password": "string"
}

  1. Copy the token
  2. Open the headers tab and write at the key cell x-access-token and paste the token at the value cell.
  3. Now you can use other endpoints that require authorisation.

Architecture

RMT shares a codebase with our parent app, DB Manager. Please look there for full documentation on back-end architecture. Within this environment, RMT uses:

/src
├── controllers
├── models
├── routes
├── services
├── middleware
├── utils
├── config
├── tests
└── app.js

Controllers

Logic that handles requests and responses. Each file should focus on a specific resource or functionality.

// controllers/userController.js
const getUser = (req, res) => {
// Logic to fetch user data
};

module.exports = {
getUser,
};

Models

Database schemas, models and helpers.

Routes

API endpoints and their associated controller methods.

// routes/userRoutes.js
const express = require("express");
const userController = require("../controllers/userController");

const router = express.Router();

router.get("/users", userController.getUser);

module.exports = router;

Services

Complex business logic that isn’t directly tied to a specific endpoint.

// services/authService.js
const generateToken = (user) => {
// Logic to generate a JWT token
};

module.exports = {
generateToken,
};

Middleware

Authentication, validation and error handling.

Utils

Utility functions that can be reused across the application (p.e. formatDate).

Config

Environment variables, database configurations…

Tests

Unit and integration tests.

API

DescriptionEndpointMethodParamsBodyReturn
check connection/rmtGET--{title: "Connected!"}
GET list of all regions/rmt/regionsGET--array of strings: ["Region1", ...]
GET list of all countries/rmt/countriesGET--array of country objects: [{ "id": int, "iso3": string, "name_un": string, "subregion": string}, ...]
GET all disease status scores/rmt/disease-statusGET--array of disease status objects: [{ "id": int, "country_id": int, "FMD": int, "PPR": int, "LSD": int, "RVF": int, "SGP": int, "date": datetime }, ...]
GET disease status scores by country/rmt/disease-status/:countryIdGETint countryId-country info + disease status scores: { "country": [ { "id": int, "iso3": string, "name_un": string } ], "scores": [ { "id": int, "country_id": int, "FMD": int, "PPR": int, "LSD": int, "RVF": int, "SGP": int, "date": datetime } ]}
POST new disease status score/rmt/disease-statusPOST-{ "country_id": int, , "FMD": int, "PPR": int, "LSD": int, "RVF": int, "SGP": int, "date": string }updated array of disease status objects: [{ "id": int, "country_id": int, "FMD": int, "PPR": int, "LSD": int, "RVF": int, "SGP": int, "date": datetime }, ...]
DELETE disease status by id/rmt/disease-status/:idDELETEint id-updated array of disease status objects: [{ "id": int, "country_id": int, "FMD": int, "PPR": int, "LSD": int, "RVF": int, "SGP": int, "date": datetime }, ...]
GET all mitigation measures/rmt/mitigation-measuresGET--array of mitigation measures: [{ "id": int, "country_id": int, "FMD": int, "PPR": int, "LSD": int, "RVF": int, "SGP": int, "date": datetime }, ...]
GET mitigation measures by country/rmt/mitigation-measures/:countryIdGETint countryId-country info + mitigation measures scores: { "country": [ { "id": int, "iso3": string, "name_un": string } ], "scores": [ { "id": int, "country_id": int, "FMD": int, "PPR": int, "LSD": int, "RVF": int, "SGP": int, "date": datetime } ]}
POST new mitigation measures score set/rmt/mitigation-measuresPOST-{ "country_id": int, , "FMD": int, "PPR": int, "LSD": int, "RVF": int, "SGP": int, "date": string }updated array of mitigation measures objects: [{ "id": int, "country_id": int, "FMD": int, "PPR": int, "LSD": int, "RVF": int, "SGP": int, "date": datetime }, ...]
DELETE mitigation measures record by id/rmt/mitigation-measures/:idDELETEint id-updated array of mitigation measures objects: [{ "id": int, "country_id": int, "FMD": int, "PPR": int, "LSD": int, "RVF": int, "SGP": int, "date": datetime }, ...]
GET all risk scores for one target country/rmt/risk-scores/:receiverCountryIdGETint receiverCountryId-object containing data array of risk scores objects: { "data": [ { "id": int, "receiver_country_id": int, "source_country_id": int, "FMD": int, "PPR": int, "LSD": int, "RVF": int, "SGP": int, "date": datetime, "iso3": string, "name_un": string }, ...], "error": null }
POST new risk score between two countries/rmt/risk-scores/:receiverCountryId/:sourceCountryIdPOSTint receiverCountryId, int sourceCountryId{connections}, {diseaseStatus}, {mitigationMeasures}**-

** connections object format:

{
liveAnimalContact: int,
legalImport: int,
proximity: int,
illegalImport: int,
connection: int,
livestockDensity: int,}

** diseaseStatus & mitigationMeasures object format:

{
FMD: int, PPR: int, LSD: int, RVF: int
}

Style guide

Follow EUFMD's Engineering Guidelines. In addition to those, we do the following:

Endpoints

  • Simple and self-describing endpoints
    • /api?type=user&id=1234
    • /api/users/1234
  • Plural Nouns. Never use the CRUD names in URIs.
    • /api/user/1234 : singular
    • /api/getUsers/1234 : verb
    • /api/users/1234
  • Stick to standard HTTP methods
POST / users; // Create a new user
GET / users; // Get all users
GET / users / { id }; // Get a specific user
PUT / users / { id }; // Update a specific user
DELETE / users / { id }; // Delete a specific user
  • Use hyphens (-) to improve readability of long names. Important to avoid underscores (_) because they might be completely hidden in some browsers.
    • /api/riskScores/
    • /api/risk_scores/
    • /api/risk-scores/

Architecture

Follow the architecture documented above when creating new routes, functions, files etc.