Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/f-lsq/parcel-bustle-backend

Courier service arrangement platform that facilitates the collection and delivery of parcels, with real-time updates of the status of each parcel.
https://github.com/f-lsq/parcel-bustle-backend

courier-service gin-gonic golang gorm mysql postgresql

Last synced: 22 days ago
JSON representation

Courier service arrangement platform that facilitates the collection and delivery of parcels, with real-time updates of the status of each parcel.

Awesome Lists containing this project

README

        

# Parcel Bustle (Backend)
[Parcel Bustle](#) is a cutting-edge courier service app designed to streamline your courier and logistic needs. With this app, you can manage parcel deliveries and track shipments in real-time with no hassle.




This app is targeted for last-mile delivery services providers, specialising in transporting good from a distribution center to the end customer's doorstep. It allows workers to save parcel details into the system either using an Optical Character Recognition (OCR) tool, or by manual input. Customers will be contactable via WhatsApp with the click of a button, while the host can manage the parcels and workers' permission through the frontend interface.

* [Frontend Repository](https://github.com/f-lsq/parcel-bustle) (React Native with Redux, Expo)
* [Backend Repository](https://github.com/f-lsq/parcel-bustle-backend) (Golang - Gin, GORM, MySQL)

## Table of Contents
1. [System Design](#system-design)
2. [Functionalities](#functionalities)
3. [Technologies Used](#technologies-used)
4. [Deployment](#deployment)
5. [References](#references)

## System Design
### Entity Relationship Diagram
![Entity Relationship Diagram](assets/images/readme/erd.png#gh-light-mode-only)
![Entity Relationship Diagram](assets/images/readme/erd-dark.png#gh-dark-mode-only)
### SQL Schema Diagram
Given the relationship between entities, a relational DB (in this case MySQL) would be more ideal to store the data. The schema is as shown below.
![SQL Schema](assets/images/readme/schema.png#gh-light-mode-only)
![SQL Schema](assets/images/readme/schema-dark.png#gh-dark-mode-only)

Do note that the *password* field will be hashed using [bcrypt](https://en.wikipedia.org/wiki/Bcrypt) before it is stored in the DB.

### System Architecture
![System Architecture](assets/images/readme/system-architecture.png#gh-light-mode-only)
![System Architecture](assets/images/readme/system-architecture-dark.png#gh-dark-mode-only)

An Object Relational Mapper (ORM) is used due to its
1. **Flexibility**: Isolates the code from the database queries, making it easier to amend the codes if the database technology were to be changed (e.g. from MySQL to PostgresSQL)
2. **Simplicity**: Performs data queries and manipulation using Golang rather than SQL language
3. **Security**: Prevents injection attack by using the [`database/sql`](https://gorm.io/docs/security.html) argument placeholders to contruct the SQL statements

### API Routes Overview
![API Routes](assets/images/readme/api-routes.png#gh-light-mode-only)
![API Routes](assets/images/readme/api-routes-dark.png#gh-dark-mode-only)

The detailed information of each API routes can be found below.
* [Workers](#api-routes-for-workers)
* [Parcels](#api-routes-for-parcels)
* [Customers](#api-routes-for-customers)
* [Hosts](#api-routes-for-hosts)
* [Authentication](#api-routes-for-authentication)

### API Routes for Workers
Base URL for workers `http://{domain-name}.com/api/workers`.
| Endpoint | Method | Description | Request Body | Response | Authentication Response |
|----------|--------|-------------|--------------|----------|-------------------------|
| `/` | POST | Creates a new worker from request data sent as JSON | {
 "username": string,
 "email": string,
 "password": string,
 "first_name": string,
 "last_name": string,
 "contact": string,
 "profile_image": string
} | Status 200 - returns a success message
Status 400 - returns an error message
Status 500 - returns an error message | |
| `/` | GET | Get a list of all workers, returned as JSON | | Status 200 - returns data of all workers
Status 500 - returns an error message | |
| `/:workerId` | GET | Get a worker by their ID, returning worker data as JSON | | Status 200 - returns data of the specific worker
Status 404 - returns an error message indicating that the worker is not found
Status 500 - returns an error message | |
| `/:workerId` | PUT | Update data of a specific worker | {
 "username": string,
 "email": string,
 "password": string,
 "first_name": string,
 "last_name": string,
 "contact": string,
 "profile_image": string
} | Status 200 - returns data of the updated worker
Status 400 - returns an error message
Status 404 - returns an error message indicating that the worker is not found
Status 500 - returns an error message | Status 401 - returns an error message requiring login
Status 403 - returns an error message for invalid access token |
| `/:workerId` | DELETE | Delete a specific worker | | Status 200 - returns data of the deleted worker
Status 404 - returns an error message indicating that the worker is not found
Status 500 - returns an error message | Status 401 - returns an error message requiring login
Status 403 - returns an error message for invalid access token |

### API Routes for Parcels
Base URL for parcels `http://{domain-name}.com/api/parcels`.
| Endpoint | Method | Description | Request Body | Response | Authentication Response |
|----------|--------|-------------|--------------|----------|-------------------------|
| `/` | POST | Creates a new parcel from request data sent as JSON | {
 "status": string,
 "delivery_address": string,
 "return_address": string,
 "deliver_by": datetime,
 "delivered_image": string,
 "payment_type": string,
 "payment_mode": boolean
} | Status 200 - returns a success message
Status 400 - returns an error message
Status 500 - returns an error message | Status 401 - returns an error message requiring login
Status 403 - returns an error message for invalid access token |
| `/` | GET | Get a list of all parcels, returned as JSON | | Status 200 - returns data of all parcels
Status 500 - returns an error message | |
| `/:parcelId` | GET | Get a parcel by its ID, returning parcel data as JSON | | Status 200 - returns data of the specific parcel
Status 404 - returns an error message indicating that the parcel is not found
Status 500 - returns an error message | |
| `/:parcelId` | PUT | Update data of a specific parcel | {
 "status": string,
 "delivery_address": string,
 "return_address": string,
 "deliver_by": datetime,
 "delivered_image": string,
 "payment_type": string,
 "payment_mode": boolean
} | Status 200 - returns data of the updated parcel
Status 400 - returns an error message
Status 404 - returns an error message indicating that the parcel is not found
Status 500 - returns an error message | Status 401 - returns an error message requiring login
Status 403 - returns an error message for invalid access token |
| `/:parcelId` | DELETE | Delete a specific parcel | | Status 200 - returns data of the deleted parcel
Status 404 - returns an error message indicating that the parcel is not found
Status 500 - returns an error message | Status 401 - returns an error message requiring login
Status 403 - returns an error message for invalid access token |
| `/worker/:workerId` | GET | Get a parcel by worker ID, returning parcel data as JSON | | Status 200 - returns data of the specific worker
Status 404 - returns an error message indicating that the worker is not found
Status 500 - returns an error message | |
| `/customer/:customerId` | GET | Get a parcel by customer ID, returning parcel data as JSON | | Status 200 - returns data of the specific customer
Status 404 - returns an error message indicating that the customer is not found
Status 500 - returns an error message | |

### API Routes for Customers
Base URL for customers `http://{domain-name}.com/api/customers`.
| Endpoint | Method | Description | Request Body | Response | Authentication Response |
|----------|--------|-------------|--------------|----------|-------------------------|
| `/` | POST | Creates a new customer from request data sent as JSON | {
 "first_name": string,
 "last_name": string,
 "contact": string
} | Status 200 - returns a success message
Status 400 - returns an error message
Status 500 - returns an error message | |
| `/` | GET | Get a list of all customers, returned as JSON | | Status 200 - returns data of all customers
Status 500 - returns an error message | |
| `/:customerId` | GET | Get a customer by their ID, returning customer data as JSON | | Status 200 - returns data of the specific customer
Status 404 - returns an error message indicating that the customer is not found
Status 500 - returns an error message | |
| `/:customerId` | PUT | Update data of a specific customer | {
 "first_name": string,
 "last_name": string,
 "contact": string
} | Status 200 - returns data of the updated customer
Status 400 - returns an error message
Status 404 - returns an error message indicating that the customer is not found
Status 500 - returns an error message | Status 401 - returns an error message requiring login
Status 403 - returns an error message for invalid access token |
| `/:customerId` | DELETE | Delete a specific customer | | Status 200 - returns data of the deleted customer
Status 404 - returns an error message indicating that the customer is not found
Status 500 - returns an error message | Status 401 - returns an error message requiring login
Status 403 - returns an error message for invalid access token |

### API Routes for Hosts
Base URL for hosts `http://{domain-name}.com/api/hosts`.
| Endpoint | Method | Description | Request Body | Response | Authentication Response |
|----------|--------|-------------|--------------|----------|-------------------------|
| `/` | POST | Creates a new host from request data sent as JSON | {
 "username": string,
 "email": string,
 "password": string,
 "first_name": string,
 "last_name": string,
} | Status 200 - returns a success message
Status 400 - returns an error message
Status 500 - returns an error message | |
| `/` | GET | Get a list of all hosts, returned as JSON | | Status 200 - returns data of all hosts
Status 500 - returns an error message | |
| `/:hostId` | GET | Get a host by their ID, returning host data as JSON | | Status 200 - returns data of the specific host
Status 404 - returns an error message indicating that the host is not found
Status 500 - returns an error message | |
| `/:hostId` | PUT | Update data of a specific host | {
 "username": string,
 "email": string,
 "password": string,
 "first_name": string,
 "last_name": string,
} | Status 200 - returns data of the updated host
Status 400 - returns an error message
Status 404 - returns an error message indicating that the host is not found
Status 500 - returns an error message | Status 401 - returns an error message requiring login
Status 403 - returns an error message for invalid access token |
| `/:hostId` | DELETE | Delete a specific host | | Status 200 - returns data of the deleted host
Status 404 - returns an error message indicating that the host is not found
Status 500 - returns an error message | Status 401 - returns an error message requiring login
Status 403 - returns an error message for invalid access token |

### API Routes for Authentication
Base URL for hosts `http://{domain-name}.com/api/auth`.
| Endpoint | Method | Description | Request Body | Response | Authentication Response |
|----------|--------|-------------|--------------|----------|-------------------------|
| `/login` | POST | Validate credentials and generate authorisation cookies | {
 "username": string,
 "email": string,
 "password": string
} | Status 200 - returns a success message
Status 400 - returns an error message
Status 401 - returns an error message for wrong credentials
Status 500 - returns an error message | |
| `/refresh` | POST | Refresh expired access token with a refresh token | | Status 200 - returns a new access token
Status 500 - returns an error message | Status 401 - returns an error message requiring login
Status 403 - returns an error message for invalid access token |
| `/refresh` | POST | Refresh expired access token with a refresh token | | Status 204 - no response returned
Status 500 - returns an error message | Status 401 - returns an error message requiring login
Status 403 - returns an error message for invalid access token |

## Functionalities

## Technologies Used
### Frontend
* [React Native](https://reactnative.dev/)
* [Expo](https://expo.dev/)

### Backend
* [Gin](https://gin-gonic.com/docs/) - Server environment. [GORM](https://gorm.io/), [CompileDaemon](https://github.com/githubnemo/CompileDaemon), [godotenv](https://github.com/joho/godotenv), [bcrypt](golang.org/x/crypto/bcrypt), [jwt](github.com/golang-jwt/jwt), [uuid](github.com/google/uuid)
* [MySQL](https://www.mysql.com/)/[PostgresSQL](https://www.postgresql.org/) - Database management

## Deployment
### Live Links
* [React Native Frontend](#)
* [Gin Backend](#)

### Test Accounts
| Account Type | Name | Email | Password |
|--------------|------|-------|----------|
| Worker | [Mulan Hua](https://disney.fandom.com/wiki/Fa_Mulan) | [email protected] | mulanhua123@ |
| Worker | [Shang Li](https://disney.fandom.com/wiki/Li_Shang) | [email protected] | shangli123@ |
| Worker | [Chi Fu](https://disney.fandom.com/wiki/Chi-Fu) | [email protected] | shangli123@ |
| Host | Host 1 | [email protected] | *Not provided* |
| Host | Host 2 | [email protected] | *Not provided* |
| Host | Host 3 | [email protected] | *Not provided* |

## References
1. [Marcus, K. (2024 January 18). Go ORMs in 2024.](https://encore.dev/resources/go-orms)