Skip to content

Instantly share code, notes, and snippets.

@Maxondria
Created April 28, 2021 07:17
Show Gist options
  • Save Maxondria/c79d6fb312208aa380897899f91c1e5c to your computer and use it in GitHub Desktop.
Save Maxondria/c79d6fb312208aa380897899f91c1e5c to your computer and use it in GitHub Desktop.
README.md Sample

FynixtechBackend API Documentation -v2.0.0

The purpose of this documentation is to detail principles, objects, behaviours and error handling for the AkaboxiBackend API.

This API has been developed to enable as a backend interface for all Akaboxi management systems / applications.

Important!

All endpoints must come after this URI: # /api/v2/admin. Forexample, https://server.com/api/v2/admin/ENDPOINT .All other requests hitting the endpoint directly will be rejected with a 404 (Not Found)

Installation

The API has been built using NodeJS and you will be required to install Yarn or NPM inorder to access the required dependencies.

curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https: //dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list

Test that Yarn is installed by running: yarn --version

Start The Server

You need to head cd into the home directory and run:

yarn start

Running Tests

To run tests, you need to have a test database installed and running on the machine you intend to install this API. This is because, before tests run, the test database is brought down and migrations and seeds are re-run.

To run tests:

yarn test

Sample AJAX Request Format

For all requests made to any of the endpoint herein, you're advised to wrap them in try/catch blocks taking advantage of the awesome ES6 async/await syntax. This reduces on the .then(), .catch() chain length.

AJAX Libraries such as axios is a very good promise based HTTP client for the browser and node.js.

Eg:

// Send a POST request
axios({
  method: 'post',
  url: '/user/12345',
  data: {
    firstName: 'Fred',
    lastName: 'Flintstone'
  }
});
  • Configuring Axios

You need to configure axios as a separate module. This could be named http-common.js

   import axios from 'axios';
   import $store from './vuex-store';

   const token = $store.state.token;

   export const HTTP = axios.create({
   baseURL: `https://example.com/system/`,
   timeout: 1000,
   headers: {
     Authorization: 'Bearer {token}'
   }
   });
  • Sample Axios Request

In your component (Used Vue) for this example. We are making a GET request to the /savings endpoint.

<script>
import {HTTP} from './http-common';

export default {
  data() {
    return {
      data: [],
      errors: []
    }
  },

  async created() {
	try{
	  const response = await HTTP.get(`savings`);
	  this.data = response.data;

    //  HTTP.post('https://site.com/', {
    //    name: 'Any Name'
    //  })

	} catch(error) {
          this.errors.push(error);
	}
  }
}
</script>

Important to note:

All POST methods expect valid body objects as described below. Should you send an incomplete body, malformed json or a missing body request, the server will reject all these with an Invalid Input! error.

Error Responses:

  • Code: 403 | 500

  • Content:

Various errors might come back from the server. They will be wrapped in the response body object like below. Please be keen on catching these errors.

{
"error" : "--message--",
}

Authentication

Super Admin Login

  • Who Is A Super Admin?

A super admin is a user at the topmost level of the whole akaboxi web and mobile management systems / applications. By logging in, he is authenticated to access the Main Administration system including but not limited to, registering organisations and groups, members(* secretaries *), managing these organisations.

POST Method to Login.

  • Endpoint

/super-login

  • Method: POST

  • Body:

{
"email" : "[email protected]",
"password" : "some-random-password"
} 

Upon successful request, the server responds with a 200 OK status code.

  • Success Reponse:

    • Code: 200 OK

    • Content:

{
  "user": {
    "id": 1,
    "fname": "John",
    "sname": "Doe",
    "gender": "Male",
    "usertype": "sadmin",
    "createdAt": "2019-04-26T12:27:27.000Z",
    "updatedAt": "2019-04-26T12:27:27.000Z",
    "email": "[email protected]"
  },
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwiZm5hbWUiOiJKb2huIiwic25hbWUiOiJEb2UiLCJnZW5kZXIiOiJNYWxlIiwidXNlcnR5cGUiOiJzYWRtaW4iLCJjcmVhdGVkQXQiOiIyMDE5LTA0LTI2VDEyOjI3OjI3LjAwMFoiLCJ1cGRhdGVkQXQiOiIyMDE5LTA0LTI2VDEyOjI3OjI3LjAwMFoiLCJlbWFpbCI6ImFrYWJveGlAYWthYm94aS5jb20iLCJpYXQiOjE1NTY5MDc3MzgsImV4cCI6MTU1NjkxMTMzOH0.d91lHqW0rugHeszRns6pd3kgPPO4_of0KRGPP_ygK3g",
  "roles": {
    "id": 1,
    "role_name": "SuperAdmin",
    "createdAt": "2019-04-26T12:27:27.000Z",
    "updatedAt": "2019-04-26T12:27:27.000Z"
  }
}
  • You are advised to save this token to some flux stores eg. Vuex, Redux or other webstorage resources like LocalStorage and always set this a Bearer token in authorization headers on any other subsequent requests made to the server. This is the only way to authenticate whether information coming from the server is being seen received, viewed and used by the person intended.

  • This authentication token is generated to be valid for a session period of 1 hour, users will be requested to re-authenticate themselves thereafter. You are therfore advised to try and catch any Authentication Failed error responses to provide meaningful error messages to the user and help them redirect to the Login page.

  • This server generated token is always going to be unique on every other authentication request. Remember to clear it from where it is stored after Logging the User Out.

Organization

Here we deal with being able to create an Organization, quering for one or more than one Organization and Edit the Organizations profile.

An organization owns groups

Create Organization

To create a new Organization.

  • Endpoint /add-organization

  • Method: POST

  • Body:

{
	"name" : "akaboxi Fund",
	"address" : "Semawata Rd.",
	"email" : "<[email protected]>",
	"website" : "WWW.AKABOXI.COM",
	"telephone" : "0789776655",
	"description" : "Kiryandongo Saving Groups",
	"org_role_id" : 1
} 

The organization role id org_role_id is automatically asigned based on payment plan an organization belongs to either Basic or Premium.

  • Success Reponse:
    • Code: 200 Success
    • Content:
{
	"id": 1,
	"name" : "Akaboxi Fund",
	"address" : "Semawata rd.",
	"email" : "<[email protected]",
	"website" : "www.akaboxi.com",
	"telephone" : "0789776655",
	"description" : "Kiryandongo saving groups",
	"org_role_id" : 1,
	"updateAt" : "2019-04-25T15:47:07.648Z",
	"createAt" : "2019-04-25T15:47:07.648Z"
}

Get One Organization

To fetch one Organization.

  • Endpoint /organization/:id

  • Method: GET

  • URL Params ..* Required: id = [interger]

  • Success Response:

    • Code: 200 Success
    • Content:
{
  "id": 1,
  "name": "Max Children Fund",
  "address": "Najjera St.",
  "email": "[email protected]",
  "website": "www.maxchil.com",
  "telephone": "0789776655",
  "description": "Najjera Saving Groups",
  "org_role_id": 1,
  "createdAt": "2019-04-26T12:27:28.000Z",
  "updatedAt": "2019-04-26T12:27:28.000Z"
}

Get all Organization

GET Method to fetch all Organizations.

  • Endpoint /organizations-list/:page

where:

[page] - current page (default 0) and will return the first 25 records.

  • Method: GET

  • Success Response:

    • Code: 200 Success
    • Content:
{
  "totalOrganizations": 2,
  "organizations": [
    {
      "id": 2,
      "name": "Testing Children Fund Updated",
      "address": "Najjera, Bulabira",
      "email": "[email protected]",
      "website": "www.maxchil.com",
      "telephone": "0789776655",
      "description": "Najjera Saving Groups",
      "org_role_id": 2,
      "createdAt": "2019-04-26T12:27:28.000Z",
      "updatedAt": "2019-04-26T12:27:28.000Z",
      "role_name": "Premium-Plan"
    },
    {
      "id": 2,
      "name": "Max Children Up",
      "address": "Updated Address",
      "email": "[email protected]",
      "website": "www.maxchil.com",
      "telephone": "0789776655",
      "description": "Najjera Saving Groups",
      "org_role_id": 2,
      "createdAt": "2019-04-26T12:27:28.000Z",
      "updatedAt": "2019-04-26T12:27:28.000Z",
      "role_name": "Premium-Plan"
    }
  ]
}

Edit Organization

To update an Organization's bio-information.

  • Endpoint /organization/:id

  • Method: PUT

  • Body

    {
	"name" : "Max Children Updated",
	"address" : "Updated Address Updated",
	"email" : "<[email protected]",
	"website" : "www.maxchil.com",
	"telephone" : "0789776655",
	"description" : "Najjera saving groups",
	"org_role_id" : 1
	}
  • Success Response:
    • Code: 200 success
    • Content:
{
  "id": 1,
  "name": "Testing Children Fund Updated",
  "address": "Najjera, Bulabira",
  "email": "[email protected]",
  "website": "www.maxchil.com",
  "telephone": "0789776655",
  "description": "Najjera Saving Groups",
  "org_role_id": 2,
  "createdAt": "2019-04-26T12:27:28.000Z",
  "updatedAt": "2019-05-10T13:04:13.000Z"
}

Group

Create a group, view one created, edit a group, view group members, and others as seen hereafter.

A group houses members

Create Group

To create a new group.

  • Endpoint /add-group

  • Method: POST

  • Body:

{ 
	"group_name": "Testing kirya-Group",
	"description": "Testing Kiryandongo group", 
	"organ_id": 1
}

where [organ_id] is the organization where this group belongs. This must exist or else the server will respond with an error.

  • Success Reponse:
    • Code: 200 Success
    • Content:
{
  "id": 9,
  "group_name": "Testing kirya-Group",
  "description": "Testing Kiryandongo group",
  "organ_id": 1,
  "updatedAt": "2019-05-10T14:25:18.523Z",
  "createdAt": "2019-05-10T14:25:18.523Z"
}

Update Group

To update a new group.

  • Endpoint /groups/:id

  • Method: PUT

  • Body:

{ 
	"group_name": "Testing kirya-Group Updated",
	"description": "Testing Kiryandongo group Three", 
	"organ_id": 1
}

where [organ_id] is the organization where this group belongs. This must exist or else the server will respond with an error.

  • Success Reponse:
    • Code: 200 Success
    • Content:
{
  "id": 9,
  "group_name": "Testing kirya-Group Updated",
  "description": "Testing Kiryandongo group Three",
  "organ_id": 1,
  "status": "active",
  "createdAt": "2019-05-10T14:25:18.000Z",
  "updatedAt": "2019-05-10T14:26:08.000Z"
}

Lisf all groups in an organization

Get all groups belonging to organization with id: 3.

  • Endpoint /groups-list/:organ_id/:page

where:

[organ_id] -id of the organization

[page] - current page (default 0) and will return the first 25 records.

  • Method: GET

  • Success Reponse:

    • Code: 200 Success
    • Content:
{
  "totalGroups": 3,
  "allgroups": [
    {
      "id": 1,
      "group_name": "kirya-Group No.3-updated",
      "description": "Kiryandongo group Three-updated",
      "organ_id": 2,
      "status": "active",
      "createdAt": "2019-04-26T12:27:28.000Z",
      "updatedAt": "2019-05-08T17:27:30.000Z"
    },
    {
      "id": 2,
      "group_name": "kirya-Group No.2",
      "description": "Kiryandongo group Two",
      "organ_id": 2,
      "status": "active",
      "createdAt": "2019-04-26T12:27:28.000Z",
      "updatedAt": "2019-04-26T12:27:28.000Z"
    },
    {
      "id": 7,
      "group_name": "kirya-Group No.3",
      "description": "Kiryandongo group Three",
      "organ_id": 2,
      "status": "active",
      "createdAt": "2019-04-26T12:37:55.000Z",
      "updatedAt": "2019-04-26T12:37:55.000Z"
    }
  ]
}

One group Information

Get one group's bio data.

  • Endpoint /groups/:id

where:

[id] -id of the group

  • Method: GET

  • Success Reponse:

    • Code: 200 Success
    • Content:
{
  "id": 9,
  "group_name": "Testing kirya-Group Updated",
  "description": "Testing Kiryandongo group Three",
  "organ_id": 1,
  "status": "active",
  "createdAt": "2019-05-10T14:25:18.000Z",
  "updatedAt": "2019-05-10T14:26:08.000Z"
}

Deactivate a group (Delete)

Delete a group.

  • Endpoint /groups/:id

where:

[id] -id of the group

  • Method: PATCH

  • Success Reponse:

    • Code: 200 Success
    • Content:
{
  "id": 1,
  "group_name": "kirya-Group No.3-updated",
  "description": "Kiryandongo group Three-updated",
  "organ_id": 2,
  "status": "inactive",
  "createdAt": "2019-04-26T12:27:28.000Z",
  "updatedAt": "2019-05-08T17:26:48.000Z"
}

Reactivate a group

Make a group active again

  • Endpoint /reactivate-group/:id

where:

[id] -id of the group

  • Method: PATCH

  • Success Reponse:

    • Code: 200 Success
    • Content:
{
  "id": 1,
  "group_name": "kirya-Group No.3-updated",
  "description": "Kiryandongo group Three-updated",
  "organ_id": 2,
  "status": "active",
  "createdAt": "2019-04-26T12:27:28.000Z",
  "updatedAt": "2019-05-08T17:27:30.000Z"
}

Group Settings (After Registration)

Set An Interest Rate for every group registered.

  • Endpoint /group-settings/:id

where:

[id] -group's id

  • Body:
{
	"rate": 5
}
  • Method: PUT

  • Success Reponse:

    • Code: 200 Success
    • Content:
{
  "id": 9,
  "group_name": "Testing kirya-Group Updated",
  "description": "Testing Kiryandongo group Three",
  "organ_id": 1,
  "status": "active",
  "settings": "5",
  "createdAt": "2019-05-10T14:25:18.000Z",
  "updatedAt": "2019-05-20T17:53:18.000Z"
}

Lisf all group members

Get all members belonging to a group in a certain organization.

  • Endpoint /group-members/:id/:page

where:

[organ_id] -id of the group

[page] - current page (default 0) and will return the first 25 records.

  • Method: GET

  • Success Reponse:

    • Code: 200 Success
    • Content:
{
  "totalMembers": 1,
  "members": [
    {
      "id": 1,
      "picture_id": "userImage-1556799101234.jpg",
      "occupation": "Peasant",
      "mem_role": "secretary",
      "address": "Metropolitan city, kampala",
      "status": "active",
      "user_details_id": 5,
      "groups_group_id": 1,
      "account_id": "34345SDBC",
      "date_of_birth": "1992-01-01",
      "createdAt": "2019-05-02T11:33:49.000Z",
      "updatedAt": "2019-05-02T12:11:41.000Z",
      "user_detail": {
        "id": 5,
        "fname": "Akampa",
        "sname": "Moses",
        "gender": "Male",
        "usertype": "secretary",
        "createdAt": "2019-05-02T11:33:49.000Z",
        "updatedAt": "2019-05-02T11:33:49.000Z"
      }
    }
  ]
}

Member

Create a member, view one created, edit a member's info, and others as seen hereafter.

A must be attached to a group

Create member

To create a new member.

  • Endpoint /add-member

  • Method: POST

  • Body:

{
	"user_detail": {
		"fname": "Businge",
		"sname": "Merimack",
		"gender": "Male",
		"usertype": "member"
	},
	"gen_info": {
		"occupation": "peasant",
		"mem_role": "secretary",
		"address": "Makombo, Kampala",
		"groups_group_id": 2,
		"account_id": "343GHDDDBC",
		"date_of_birth": "1993-01-01"
	},
	"next_of_kin": {
		"user_detail": {
		"fname": "Nuwasiima",
		"sname": "Gordon",
		"gender": "Male",
		"usertype": "nxt_kin"
	},
		"relationship": "Brother"
	}
}

Kindly note that all this is required. You're supposed to tweek your frontend Ajax library to be able to generate this kind of object in the same format as seen above. As put before, malformed json objects will result in errors.

  • Success Reponse:
    • Code: 200 Success
    • Content:
{
  "member": {
    "id": 11,
    "fname": "Businge",
    "sname": "Merimack",
    "gender": "Male",
    "usertype": "secretary",
    "updatedAt": "2019-05-02T12:29:28.412Z",
    "createdAt": "2019-05-02T12:29:28.412Z"
  },
  "next_of_kin": {
    "id": 12,
    "fname": "Nuwasiima",
    "sname": "Gordon",
    "gender": "Male",
    "usertype": "nxt_kin",
    "updatedAt": "2019-05-02T12:29:28.437Z",
    "createdAt": "2019-05-02T12:29:28.437Z"
  }
}

Update member information

To update a new member.

  • Endpoint /members/:id

  • Method: PUT

  • Body:

{
	"user_detail": {
		"fname": "Businge Updated",
		"sname": "Merimack Updated",
		"gender": "Male"
	},
	"gen_info": {
		"occupation": "peasant",
		"mem_role": "secretary",
		"address": "Makombo, Kampala",
		"groups_group_id": 2,
		"account_id": "343GHDDDBC",
		"date_of_birth": "1993-01-01"
	},
	"next_of_kin": {
		"id": 12,
		"user_detail": {
		"fname": "Nuwasiima Updated",
		"sname": "Gordon",
		"gender": "Male"
	 },
		"relationship": "Boss"
	}
}
  • It is PARAMOUNT to note that in next_of_kin object, id, refers to user_detail id. and it must be separated from the user_detail as a separate property. Please refer to the example above. Please use it as a format to compose your request body object.

  • Success Reponse:

    • Code: 200 Success
    • Content:
{
  "member": {
    "id": 4,
    "picture_id": "userImage-1556907765246.jpg",
    "occupation": "peasant",
    "mem_role": "secretary",
    "address": "Makombo, Kampala",
    "status": "active",
    "user_details_id": 11,
    "groups_group_id": 2,
    "account_id": "343GHDDDBC",
    "date_of_birth": "1993-01-01",
    "createdAt": "2019-05-02T12:29:28.000Z",
    "updatedAt": "2019-05-12T19:17:40.000Z",
    "user_detail": {
      "id": 11,
      "fname": "Businge Updated",
      "sname": "Merimack Updated",
      "gender": "Male",
      "usertype": "secretary",
      "createdAt": "2019-05-02T12:29:28.000Z",
      "updatedAt": "2019-05-12T19:17:40.000Z"
    }
  },
  "nxtOfKin": {
    "id": 3,
    "relationship": "Boss",
    "member_id": 4,
    "user_details_id": 12,
    "createdAt": "2019-05-02T12:29:28.000Z",
    "updatedAt": "2019-05-12T19:17:40.000Z",
    "user_detail": {
      "id": 12,
      "fname": "Nuwasiima Updated",
      "sname": "Gordon",
      "gender": "Male",
      "usertype": "nxt_kin",
      "createdAt": "2019-05-02T12:29:28.000Z",
      "updatedAt": "2019-05-12T19:17:40.000Z"
    }
  }
}

One members information

Get one members's bio data.

  • Endpoint /members/:id

where:

[id] -member id (Not user_details id - IMPORTANT)

  • Method: GET

  • Success Reponse:

    • Code: 200 Success
    • Content:
{
  "id": 1,
  "picture_id": "userImage-1556799101234.jpg",
  "occupation": "Peasant",
  "mem_role": "secretary",
  "address": "Metropolitan city, kampala",
  "status": "active",
  "user_details_id": 5,
  "groups_group_id": 1,
  "account_id": "34345SDBC",
  "date_of_birth": "1992-01-01",
  "createdAt": "2019-05-02T11:33:49.000Z",
  "updatedAt": "2019-05-02T12:11:41.000Z",
  "user_detail": {
    "id": 5,
    "fname": "Akampa",
    "sname": "Moses",
    "gender": "Male",
    "usertype": "secretary",
    "createdAt": "2019-05-02T11:33:49.000Z",
    "updatedAt": "2019-05-02T11:33:49.000Z"
  },
  "next_of_kin": {
    "id": 1,
    "relationship": "Wife",
    "member_id": 1,
    "user_details_id": 6,
    "createdAt": "2019-05-02T11:33:49.000Z",
    "updatedAt": "2019-05-02T11:33:49.000Z"
  }
}

Add Member Image (Picture of ID)

Members are expected to have a picture associated with their accounts specifically to identify them. This could be a picture (Scanned/Fresh) of their recognised ID.

  • Endpoint /add-member-image

  • Method: POST

  • Body: The body must be a formdata object. There is a ton of tutorials online showing exactly how to use AJAX to post .jpg, and .png files. Kindly validate locally (from the client side) to make sure only these two types are sent to the server. - user_id is the user's user_details_id.

{
		"userImage": "SomeImage.png",
		"user_id": 11
}

Kindly note that all this is required. You're supposed to tweek your frontend Ajax library to be able to generate this kind of object in the same format as seen above. As put before, malformed json objects will result in errors.

  • Success Reponse:
    • Code: 200 Success
    • Content:
{
  "id": 11,
  "fname": "Businge",
  "sname": "Merimack",
  "gender": "Male",
  "usertype": "secretary",
  "createdAt": "2019-05-02T12:29:28.000Z",
  "updatedAt": "2019-05-03T11:45:15.000Z"
}

Deactivate a member (Delete)

Delete a member.

  • Endpoint /members/:id

where:

[id] -member's id , not user_details id

  • Method: PATCH

  • Success Reponse:

    • Code: 200 Success
    • Content:
{
  "id": 4,
  "picture_id": "userImage-1556907765246.jpg",
  "occupation": "peasant",
  "mem_role": "secretary",
  "address": "Makombo, Kampala",
  "status": "inactive",
  "user_details_id": 11,
  "groups_group_id": 2,
  "account_id": "343GHDDDBC",
  "date_of_birth": "1993-01-01",
  "createdAt": "2019-05-02T12:29:28.000Z",
  "updatedAt": "2019-05-08T17:10:54.000Z",
  "user_detail": {
    "id": 11,
    "fname": "Businge",
    "sname": "Merimack",
    "gender": "Male",
    "usertype": "secretary",
    "createdAt": "2019-05-02T12:29:28.000Z",
    "updatedAt": "2019-05-03T11:45:15.000Z"
  }
}

Reactivate a member (Delete)

Re-activate a member's status.

  • Endpoint /reactivate-member/:id

where:

[id] -member's id , not user_details id

  • Method: PATCH

  • Success Reponse:

    • Code: 200 Success
    • Content:
{
  "id": 4,
  "picture_id": "userImage-1556907765246.jpg",
  "occupation": "peasant",
  "mem_role": "secretary",
  "address": "Makombo, Kampala",
  "status": "active",
  "user_details_id": 11,
  "groups_group_id": 2,
  "account_id": "343GHDDDBC",
  "date_of_birth": "1993-01-01",
  "createdAt": "2019-05-02T12:29:28.000Z",
  "updatedAt": "2019-05-08T17:11:08.000Z",
  "user_detail": {
    "id": 11,
    "fname": "Businge",
    "sname": "Merimack",
    "gender": "Male",
    "usertype": "secretary",
    "createdAt": "2019-05-02T12:29:28.000Z",
    "updatedAt": "2019-05-03T11:45:15.000Z"
  }
}

Set Members PIN

Set An Access PIN for every member registered.

  • Endpoint /set-member-pin/:id'

where:

[id] -member's id , not user_details id

  • Body:
{
	"PIN": 1234
}
  • Method: PUT

  • Success Reponse:

    • Code: 200 Success
    • Content:
{
  "id": 1,
  "picture_id": "userImage-1556799101234.jpg",
  "occupation": "Peasant",
  "mem_role": "secretary",
  "address": "Metropolitan city, kampala",
  "status": "active",
  "PIN": "1234",
  "user_details_id": 5,
  "groups_group_id": 1,
  "account_id": "34345SDBC",
  "date_of_birth": "1992-01-01",
  "createdAt": "2019-05-02T11:33:49.000Z",
  "updatedAt": "2019-05-20T15:50:48.000Z",
  "user_detail": {
    "id": 5,
    "fname": "Akampa",
    "sname": "Moses",
    "gender": "Male",
    "usertype": "secretary",
    "createdAt": "2019-05-02T11:33:49.000Z",
    "updatedAt": "2019-05-02T11:33:49.000Z"
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment