Skip to content

dropsintheocean/dih-api

Repository files navigation

dih-api

Build status:

dev master
CircleCI Coverage Status Documentation Coverage Status CircleCI Coverage Status Documentation Coverage Status

Contribute

Dråpen i Havet/A Drop in the Ocean is a volunteer organization. If you want to contribute, take a look at the issues or contact the head of the organization Trude, at trude [@] drapenihavet [dot] no.

Workflow

  1. Get a task on JIRA by talking to you teammates and looking at the sprint backlog.
  2. Create a new branch from the dev-branch, naming it using our branch naming strategy described below.
  3. Code away and commit often. Try to follow good commit practice. Remember to write tests (and run them).
  4. When you're done (see definition of done on GitHub), create a pull request with reference to the JIRA-issue (preferably a link) and an overview of what the pull request is about. Await code review (you can tag people or yell for them on Slack to get your review faster).
  5. When you've reworked your code after the code review, the pull request will be merged.

Branch naming strategy

The project has a strategy for what to name our branches, so that changes in them are easily traceable to user stories and issues in our issue tracking system JIRA. Another reason for having a naming strategy is that it makes it easy to find distinct types of proposed changes, as well as what's being worked on.

Name your branches in the following way, where DIH-num is a task ID on JIRA:

  • If it's a feature (new functionality) name the branch feature/DIH-num.
  • If it's a bugfix name the branch bugfix/DIH-num.
  • If it's a technical task, name the branch tech/DIH-num

Setup

Database

To setup the project locally install Postgres and set PG_URL to your database. The format should postgres://USERNAME:PASSWORD@localhost/DB. The capitalized words should be replaced with your own values.

To export your variable on a Unix-system, simply use the export command, i.e. export PG_URL=your value.

SES for e-mails

The system uses AWS SES for e-mails and sms notifications. You'll need to have the correct role installed on the instance running the application.

You can also set your AWS region with REGION.

Contact one of the contributors to get more information on how to be added to the AWS teams, or take a look at Confluence for some standard values you can use for testing.

Local production environment

Run yarn build to get a transpiled version of the API, then start with yarn start.

Local development environment

If you're gonna develop:

  1. Install nodemon npm install -g nodemon & yarn npm install -g yarn
  2. Spin up docker-compose to run services like db and emails locally.
  3. Run yarn start:dev Remember that you can run it with environment variables in before the command, i.e. PG_URL=value yarn start:dev.

This will watch for changes and keep the application open for you.

Test data

To enter some test data into your database, run yarn load. It will give you some test users

Role Username
User test-user@dih.capra.me
Moderator test-moderator@dih.capra.me
Administrator test-admin@dih.capra.me

All these users have the password password.

To enter some test data into your database, run npm run load.

How to test data model migrations

When you've added your migration, do the following:

  1. Delete the old dataabase, and restart the app from a branch that does not have your changed data model. This creates the previous data model for you.
  2. Switch to the branch with the new data model and migration.
  3. Build with npm run build
  4. Run the build with PG_URL set to your database, and NODE_ENV=production. You run the built code with npm start
  5. Check for errors, and see if the data model was updated in the database. If not, you'll have to fix issues and start from step number 1 again.

I.e. you create the old database, run your migration as it would run in production, and see that the migrations works.

Tests

Single run

  • Run unit tests & code lint with yarn test. This will use your local database.
  • Run just unit tests with yarn tests with NODE_ENV=test. This will use your local database.

Watch

Run the unit tests continuously with yarn test:watch, only the tests currently worked on will run when updated. All tests will run when a server file is updated. This will use your local database.

Deployment

We have continuous deployment with Circle CI, which builds Docker-images and pushes to AWS EC2.

  • The dev-branch is the main branch, and has CI to our staging environment.
  • The master-branch is the stable branch, and has CI to our production environment.

Inline documentation

We use jsdoc to document modules and methods. You can find the generated documentation here, http://docs.dih.capra.me/, and of course also in the code.

Det betyr at du i koden vår finner et minimum av dokumentasjon for metoder på følgende format:

That means that you'll find a minimum of the following as documnetation for methods:

/**
 * methodName - method description
 * 
 * @function methodName
 * @memberOf moduleType/moduleName
 * @param {Type} paramName1 - paramName1 description
 * @param {Type} paramName2 - paramName2 description
 * @return {Type} - Description of return value
 */

For modules we document in the following way:

/**
 * Module description
 * @module type/name
 */

moduleTypeis e.g. model, controller or component.

When submitting pull requests or doing changes, please make sure you maintain the documentation format and quality - or rather increase it.

API and data model

/trips

Property Value
AUTH No
Header json/application

 

Data format:

Property Type Description Restrictions Default value Required Can be null
status String ENUM Status of trip Must be in ['PENDING', 'ACCEPTED', 'REJECTED', 'ACTIVE' 'CLOSED, 'PRESENT', 'LEFT']  PENDING No No
userId Integer Id of user taking the trip Must be a valid userId None Yes No
destinationId Integer Destination for trip Must be a valid destinationId None Yes No
wishStartDate Date When the user wants this trip to start   None Yes No
wishEndDate Date When the user wnats this trip to end   None Yes No
startDate Date When the trip starts   None Yes Yes
endDate Date When the trip ends   None Yes Yes
travelMethod String ENUM Method of travel for trip Must be in ['PLANE', 'OTHER'] None No Yes
departureAirport String Departure airport when plane is travel method   None No Yes
flightNumber String Flight number when plane is travel method   None No Yes
arrivalDate Date Arrival date for travel   None No Yes
departureDate Date Departure date for travel   None No Yes
otherTravelInformation Text Free text field when other travel methos is used   None No Yes

On GET-requests the elements also holds destination and user as objects.

 

Request Endpoint Description Request body Query params Sucessful response code Sucessful response body
GET   Get all elements None destinationId, userId, status 200 Array of elements
POST   Create an new element Element   201 The new element
PUT /:id Update an element Changed element   204 None
DELETE /:id Delete an element None   204 None

/messages

Property Value
AUTH Yes
Header json/application

 

Data format:

Property Type Description Restrictions Default value Required Can be null
travelMethod String ENUM Method of travel for trip Must be in ['SMS', 'EMAIL'] None Yes No
messages String Email or sms message, (Email can be in html format)   None Yes No
sender String string for sender id in sms  MAX 11 characters None No Yes
subject String Subject of the email to be sent   None No Yes
recipients Array Array of recipients (users)   None Yes No
Request Endpoint Description Request body Query params Sucessful response code Sucessful response body
POST  / Sends the speciefied message to each recipient Element   200 report regarding the sended entities

/destinations

Property Value
AUTH No
Header json/application

Data format:

Property Type Description Restrictions Default value Required Can be null
name String Name of destination Letters only None Yes No
acceptedStatusMailTemplateId Integer Reference to mailTemplate for status accepted Reference to element in malTemplates New standard element No Yes
rejectedStatusMailTemplateId Integer Reference to mailTemplate for status rejected Reference to element in malTemplates New standard element No Yes
pendingStatusMailTemplateId Integer Reference to mailTemplate for status pending Reference to element in malTemplates New standard element No Yes
miminmumTripDurationInDays Integer Minimum number of days a volunteer has to be available for
to get accepted at the destination 
  10 No No
startDate Date When the destination becomes active   Now No No
endDate Date When the destinations ends   null No Yes

GET-requests includes the calculated field countOfActiveVolunteers and isActive

Request Endpoint Description Request body Sucessful response code Sucessful response body
GET   Get all elements None 200 Array of elements
GET  /:id Get all elements None 200 Single element of given id
POST   Create an new element Element 201 The new element
PUT /:id Update an element Changed element 204 None
DELETE /:id Delete an element None 204 None

/mailtemplates

Property Value
AUTH No
Header json/application

Data format:

Property Type Description Restrictions Default value Required Can be null
html String HTML-template for an e-mail   None Yes No
Request Endpoint Description Request body Sucessful response code Sucessful response body
GET   Get all elements None 200 Array of elements
POST   Create an new element Element 201 The new element
PUT /:id Update an element Changed element 204 None
DELETE /:id Delete an element None 204 None

/account

Property Value
AUTH Yes
Header

Authorization - Bearer jwt

Header

Content-Type - json/application

Data format:

Property Type Description Restrictions Default value Required Can be null
email String (valid email) the users email must be a valid email None Yes No
firstname String the users firstname   None Yes No
lastname String the users lastname   None Yes No
birth Date Birth date of the user   None Yes No
role String ENUM The user role  Must be in ['USER', 'MODERATOR', 'ADMIN']  USER No No
password String (valid password) The password in plain text Must be set before the user can use the system. (login flow) None No Yes
volunteerInfo Text Occupatio and experience   Empty string No No
phoneNumber String User's phoneNumber       Yes
languages Text Languages the user masters   Empty string   No
medicalDegree String User's medical degree - type       Yes
medicalDegreeLicenseNumber String License number of medical degree       Yes

Also virtual field fullName

Request Endpoint Description Request body Sucessful response code Sucessful response body
GET  / Get the current user based on jwt None 200 User object with id encoded in the jwt
PUT / Update the current user based on jwt Changes on the user object 204 None

/authenticate

Property Value
AUTH No
Header

Authorization - Bearer jwt

Header

Content-Type - json/application

Request Endpoint Description AUTH Request body Sucessful response code Sucessful response body
POST  / user login NO email + password 200 object containing jwt
POST /password update password given the jwt used has right premissions YES ( jwt needs field setPassword = true ) password 200 object containing jwt

/users

Property Value
AUTH No
Header

Content-Type - json/application

** **

Data format:

Property Type Description Restrictions Default value Required Can be null
email String (valid email) the users email must be a valid email None Yes No
firstname String the users firstname   None Yes No
lastname String the users lastname   None Yes No
birth Date Birth date of the user   None Yes No
role String ENUM The user role  Must be in ['USER', 'MODERATOR', 'ADMIN']  USER No No
phoneNumber String User's phoneNumber       Yes
languages Text Languages the user masters   Empty string   No
medicalDegree String User's medical degree - type       Yes
medicalDegreeLicenseNumber String License number of medical degree       Yes
volunteerInfo Text Occupation and experience   None No Yes
notes String Admins notes about the user   None No Yes

Also virtual field fullName

 

Request Endpoint Description Request body Sucessful response code Sucessful response body
POST / Create a new user The user to be created 201 The created user
PUT /:id Update a user by ID The fields to be updated 204 N/A

Error handling

General error status codes and descriptions

If there's no error body, then use the HTTP status code for handling:

HTTP status code Description
404 Not found
400 Bad request, i.e. something wrong with your request
500 Intenral server error

Errors thrown by system

The format of the errors is:

{

name: String,

message: String describing the error

}

The following errors can be thrown:

Error name HTTP status code Description
ValidationError 400 Thrown when you're trying to POST or PUT data that has data that isn't accepted. Check your request.
ResourceNotFoundError 404 Thrown when a resource you're requesting isn't found.
AuthenticationError 401 Thrown when you're not logged in and trying to access a resource that's available only to logged in users