# README
FastFood API - Description
Table of Contents
- Table of Contents
- Description
- Architecture
- Design Patterns
- Unit Testing
- Docker build and run
- How to use
- AWS
- Kubernetes
- Section 1 - Restaurant owner
- Section 2 Customer order
- 1 User identification
- 2 List all the categories
- 3 List products by the chosen category
- 4 Pay the products amount
- 5 Create an order
- 6 List orders to follow
- 7 List orders to prepare
- 8 List orders waiting payment
- 9 Update order to preparing
- 10 Update order to done
- 11 Update order to delivered
- 12 Update order to not delivered
- Mercado Livre Webhook
- Documentation
- Opportunities
Description
The Tech Challenge 1 aims to do a solution for a Fast Food restaurant. With this software, the rastaurant can do a all the process of for a place that makes all steps of a fast food dish order, as:
- Products creation/manipulation by the restaurant owner
- Customer identification
- Order creation with given products
- Payment process
-
- With Mercado Livre QR Code payment option Webhook Payment
- Order tracking by the chef
- Order tracking by the waiter and the customer
This projects only fits the Backend side, which means that customer needs to choose the products or combo by a interface previously. This Backend will only receive the entire order with all chosen products or combos. This Backend will not do a step by step product selecion.
All the Endpoints can be called by accessing http://localhost:3210/api
API url.
To build and run this project. Follow the Docker section
Architecture
This project uses a mixin with two architectures to make it scalable and secure by protecting the domain layer. Those are DDD (Domain Driven Design)
and Clean Archtecture
DDD
To design this application was chosen DDD (Domain Drive Design)
architecture to follow the principle of protecting the model.
Clean Archtecture
The other one is Clean Archtecture
. With it, we add some extra layers to organize even more the project.
The folder project was created to follow this main principle:
-
data: Here we have all the implementations, such as Repositories, Remotes and Locals
-
domain: All the
application business logic
, such as UseCases -
handler: Also known as
presentation layer
resides all theControllers
handled by theWeb
interface given by the/cmd/api Framework & Driver
-
integrations: This is not part of
DDD
orClean Arch
, but is important separate some external packages or integrations, suchMercado Livre API
Design Patterns
To improve and make a good standard project pattern, some Design Patterns
were used in this application.
- Strategy: All the business logic must be protected by the external implementations. To do it, we use a combo with Interfaces and Dependency Inversion solid principle to inject only interfaces and not real implementations
- Dependency Injection: Is used in application bootstrap (main.go) to inject all the interfaces implementations.
- Decorator: To inject Services inside Driver Adapter handler. By doing this, we decorate the Handler with a Service
- Services or Use Cases: Centralize all the business logic of of the application
- Repository: Used to integrate with all Driven Adapter like Databases and External Endpoints
Unit Testing
To run all the Unit Testing for this project, just run:
go test ./...
This will run all the Services unit tests and Repository unit Database tests running Testcontainers database container mocks.
Docker build and run
This project was built using Docker and Docker Compose. So, to build and run the API, we need to run in the root of the project:
docker compose build
After the image build finish, run:
docker compose up -d
The command above may take a while.
After all the containers shows these below status:
✔ Container fastfood-database Started
✔ Container fastfood-app Started
we can access http://localhost:3210/api
endpoints.
How to use
To use all the endpoints in this API, we can follow these sequence to simulate a customer making an order in a restaurant. We can separate in three moments.
- Restaurant products manipulation. This is used by the
restaurant owner
to create all the product portfolio with its images and prices - Customer self service. This is used by the
customer
to choose the products, pay for it and create an order - Order preparing and deliver. This is used by the
chef
andwaiter
to check the order status
We will divide in 2 sections: Restaurant owner and Customer order
Check app status
After running Docker
commands, you can check the application status running:
docker compose logs app
We can see some database errors but at the end of the logs we can see:
fastfood-app | 2024/05/27 22:57:35 API Tech 1 has started
AWS
The Fast food project uses AWS Cloud
to host its software components. To know more about the AWS configuration, read: AWS Readme
Kubernetes
This application has all the K8S YAMLs to be applied in any cluster. To read the specific documentation, read: Kubernetes README
Section 1 Restaurant owner
This section will be used by the restaurant owner to manage the restaurant products
1 Product manipulation
(Owner view)
- Cal the POST
http://localhost:3210/api/products
to create a Product - Cal the PUT
http://localhost:3210/api/products/{id}
to update a Product - Cal the GET
http://localhost:3210/api/products/{id}
to get a Product - Cal the GET
http://localhost:3210/api/products/categories
to list all Product Categories - Cal the GET
http://localhost:3210/api/products/categories/{category}
to list all Products by a category - Cal the DELETE
http://localhost:3210/api/products/{id}
to delete a Product
With those endpoints we can follow to Section 2 to start the Order flow
Section 2 Customer order
This section will use all the Endpoints to make a entire order flow.
1 User identification
(Customer view)
[!IMPORTANT] These endpoints have a CPF validation. So be aware that it is needed to pass a correct CPF number.
[!NOTE]
The CPF does not need to be formatted.
-
Cal the POST
http://localhost:3210/api/customers
to create a Customer and retrieve the[Customer ID]
-
Call the POST
http://localhost:3210/api/customers/login
to login and get the Customer -
Call the GET
http://localhost:3210/api/customers/{id}
to get the Customer by this[Customer ID]
-
Call the PUT
http://localhost:3210/api/customers/{id}
to update Customer
We can use this site CPF generator to easly generate a new CPF whenever we need.
2 List all the categories
(Customer view)
- Call the GET
http://localhost:3210/api/products/categories
to get a string array with all created categories
3 List products by the chosen category
(Customer view)
- Call the GET
http://localhost:3210/api/products/categories/{category}
to get all products by a category
With this endpoints we can simulate a screen producst selection by chosing all products IDs we want to deal and create a Order
4 Pay the products amount
(Customer view)
- Call the GET
http://localhost:3210/api/payments/types
to show to customer which payment type to choose - Call the POST
http://localhost:3210/api/payments
to pay for the amount and receive the[Payment ID]
4_1 Generate Mercado Livre QR Code
(Customer view)
- Call the POST
http://localhost:3210/api/qrcode/generate
to get theQR Code Data
to transform in Image to pay withMercado Pago App
. Must send the same post body as 5 create an order needs.
[!WARNING] Sometimes the Mercado Livre server returns
500 Internal Server Error
for unknown reason. The error returned by the server is:{"error":"alias_obtainment_error","message":"Get aliases for user failed","status":500,"causes":[]}
. When this occurs, IS NOT possible to proceed with QR Code Payment. The main reason for this is onWeekend the Mercado Livre development environment does not work
When the server returns as expected, the response is like:
{
"data": "00020101021243650016COM.MERCADOLIBRE020130636b624f3f3-d289-453b-a620-a32198e16a235204000053039865802BR5909Test Test6009SAO PAULO62070503***63046773"
}
[!NOTE] This method will
CREATE AN ORDER
with the statusWAITING PAYMENT
.
5 Create an order
(Customer view)
- Call the POST
http://localhost:3210/api/orders
with: -
- All the
[Products IDs]
chosen [*required]
- All the
-
- The
[Payment ID]
[required]
- The
-
- The
[Customer ID]
[optional]
- The
-
- Total price for the all products sum
6 List orders to follow
(Customer and Waiter)
- Call the GET
http://localhost:3210/api/orders/follow
to show a list of Orders to be followed by Customer and Waiter. This will list only,CREATED
,PREPARING
andDONE
. This Endpoint will sort the orders wit these business rule: -
DONE
-
PREPARING
-
CREATED
Here is some response example:
[
{
"orderId": 2,
"orderDate": "2024-07-16T21:41:31.229299-03:00",
"preparingAt": "2024-07-16T21:53:25.156494-03:00",
"doneAt": "2024-07-16T22:05:01.067784-03:00",
"deliveredAt": null,
"notDeliveredAt": null,
"ticketNumber": 2,
"customerName": null,
"orderStatus": "Finalizado",
"orderProducts": [
{
"id": 9,
"name": "Combo pequeno",
"description": "Hamburguer, batata e bebida"
}
]
},
{
"orderId": 3,
"orderDate": "2024-07-16T21:47:20.122753-03:00",
"preparingAt": "2024-07-16T22:04:08.225152-03:00",
"doneAt": null,
"deliveredAt": null,
"notDeliveredAt": null,
"ticketNumber": 3,
"customerName": null,
"orderStatus": "Preparando",
"orderProducts": [
{
"id": 6,
"name": "Hamburguer 1",
"description": "Hamburguer com 1 carne de 100g e queijo"
},
{
"id": 5,
"name": "Batata frita 400g + cheddar",
"description": "Batata frita 400g no prato com cheddar"
}
]
},
{
"orderId": 4,
"orderDate": "2024-07-16T21:52:31.813815-03:00",
"preparingAt": null,
"doneAt": null,
"deliveredAt": null,
"notDeliveredAt": null,
"ticketNumber": 4,
"customerName": null,
"orderStatus": "Criado",
"orderProducts": [
{
"id": 4,
"name": "Batata frita 200g",
"description": "Batata frita 200g no cone"
}
]
},
{
"orderId": 1,
"orderDate": "2024-07-16T21:40:11.480459-03:00",
"preparingAt": null,
"doneAt": null,
"deliveredAt": null,
"notDeliveredAt": null,
"ticketNumber": 1,
"customerName": null,
"orderStatus": "Criado",
"orderProducts": [
{
"id": 9,
"name": "Combo pequeno",
"description": "Hamburguer, batata e bebida"
}
]
}
]
The order can also be followed by its ID:
- Call the GET
http://localhost:3210/api/orders/{id}
to show a an Orders to be followed by Customer and Waiter
7 List orders to prepare
(Chef view)
- Call the GET
http://localhost:3210/api/orders/to-prepare
to list the Orders with its [Order ID]. This endpoint will be used by the Chef. This will list onlyCREATED
8 List orders waiting payment
(Owner view)
- Call the GET
http://localhost:3210/api/orders/waiting-payment
to list the Orders with its [Order ID]. This endpoint will be used by the Owner. This will list onlyPAYING
.
This Endpoint can be used to see if the Mercado Livre QR Code payment
was paid successfully
9 Update order to preparing
(Chef view)
- Call the PUT
http://localhost:3210/api/orders/{id}/preparing
to set Preparing status
10 Update order to done
(Chef view)
- Call the PUT
http://localhost:3210/api/orders/{id}/done
to set Done status
11 Update order to delivered
(Waiter view)
- Call the PUT
http://localhost:3210/api/orders/{id}/delivered
to set Delivered status to indicate that customer receive the meal. This is used to 'finish' the order and can be used to track some convertion rate
12 Update order to not delivered
(Waiter view)
- Call the PUT
http://localhost:3210/api/orders/{id}/not-delivered
to set Not Delivered status to indicate that customer does not receive the meal. This is used to 'finish' the order and can be used to track some convertion rate
Mercado Livre Webhook
The Fast Food application can pay the order via QR Code. This is a separate flow and can be read in: Webhook Payment
Documentation
This project uses Swagger to show an site with all Endpoints used by this project to make an order in a Fast Food place.
To create/update all Endpoints documentation just run swag init -g cmd/api/main.go
. By doing this, we can see the documentation in
two different ways:
Event Storming
This project was guided by the DDD Event Storming. This document was made in Miro. The file event_storming.pdf
is in the root of this project.
We can algo see the Miro project by accessing the link:Event Storming
Postman collection
In the root of this project we can find the file postman_collection.json
. With this we can easly test all the Endpoints. It also be in this repo all the postman environments
to use in localhost
and with EKS LoadBalancer DNS
. Just import also these:
- eks_postman_environment.json
- localhost_postman_environment.json
- minikube_postman_environment.json
Swagger
http://localhost:3210/swagger/index.html
Redoc
Opportunities
Even though this project was made by following some Design Patterns like Use Case
and Repository
it does not separate the Data Source from the Repository. In the future it will be good to use Data Source
Pattern to separate Local and Remote from the Repository to make a better separation of concern principle.
It will also a good opportunity to increase the Unit Test
coverage.