diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..acb35f4 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,9 @@ +repos: + + # Next hooks are Code Quality hooks. + - repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks + rev: v2.14.0 + hooks: + - id: pretty-format-golang + args: + - --autofix \ No newline at end of file diff --git a/cmd/http/main.go b/cmd/http/main.go index 458d267..2a4799c 100644 --- a/cmd/http/main.go +++ b/cmd/http/main.go @@ -9,15 +9,12 @@ import ( _ "github.com/pangolin-do-golang/tech-challenge/docs" dbAdapter "github.com/pangolin-do-golang/tech-challenge/internal/adapters/db" "github.com/pangolin-do-golang/tech-challenge/internal/adapters/rest/server" - "github.com/pangolin-do-golang/tech-challenge/internal/core/cart" "github.com/pangolin-do-golang/tech-challenge/internal/core/customer" - "github.com/pangolin-do-golang/tech-challenge/internal/core/order" - "github.com/pangolin-do-golang/tech-challenge/internal/core/product" "gorm.io/driver/postgres" "gorm.io/gorm" ) -// @title Tech Challenge Food API +// @title Tech Challenge Customer Food API // @version 0.1.0 // @description Fast Food API for FIAP Tech course @@ -32,21 +29,7 @@ func main() { customerRepository := dbAdapter.NewPostgresCustomerRepository(db) customerService := customer.NewService(customerRepository) - productRepository := dbAdapter.NewPostgresProductRepository(db) - productService := product.NewProductService(productRepository) - - cartRepository := dbAdapter.NewPostgresCartRepository(db) - cartProductsRepository := dbAdapter.NewPostgresCartProductsRepository(db) - cartService := cart.NewService(cartRepository, cartProductsRepository) - - orderRepository := dbAdapter.NewPostgresOrderRepository(db) - orderProductRepository := dbAdapter.NewPostgresOrderProductsRepository(db) - orderService := order.NewOrderService(orderRepository, orderProductRepository, cartService, productService) - restServer := server.NewRestServer(&server.RestServerOptions{ - OrderService: orderService, - ProductService: productService, - CartService: cartService, CustomerService: customerService, }) @@ -69,12 +52,6 @@ func initDb() (*gorm.DB, error) { err = db.AutoMigrate( &dbAdapter.CustomerPostgres{}, - &dbAdapter.ProductPostgres{}, - &dbAdapter.OrderPostgres{}, - &dbAdapter.CartPostgres{}, - &dbAdapter.CartProductsPostgres{}, - &dbAdapter.OrderPostgres{}, - &dbAdapter.OrderProductPostgres{}, ) if err != nil { log.Fatalln(err) diff --git a/docs/docs.go b/docs/docs.go index 1eac24a..7fcd2e9 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -15,145 +15,6 @@ const docTemplate = `{ "host": "{{.Host}}", "basePath": "{{.BasePath}}", "paths": { - "/cart/add-product": { - "post": { - "description": "Adds a Product to Customer's Cart", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Cart" - ], - "parameters": [ - { - "description": "AddProductPayload", - "name": "payload", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/controller.AddProductPayload" - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "500": { - "description": "{\\\"error\\\": \\\"Internal Server Error\\\"}", - "schema": { - "type": "object", - "additionalProperties": true - } - } - } - } - }, - "/cart/edit-product": { - "post": { - "description": "Edits a Product from Customer's Cart", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Cart" - ], - "parameters": [ - { - "description": "EditProductPayload", - "name": "payload", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/controller.EditProductPayload" - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "500": { - "description": "{\\\"error\\\": \\\"Internal Server Error\\\"}", - "schema": { - "type": "object", - "additionalProperties": true - } - } - } - } - }, - "/cart/overview": { - "post": { - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Cart" - ], - "parameters": [ - { - "description": "GetCartPayload", - "name": "payload", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/controller.GetCartPayload" - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "500": { - "description": "Internal Server Error" - } - } - } - }, - "/cart/remove-product": { - "post": { - "description": "Removes a Product from Customer's Cart", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Cart" - ], - "parameters": [ - { - "description": "RemoveProductPayload", - "name": "payload", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/controller.RemoveProductPayload" - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "500": { - "description": "Internal Server Error" - } - } - } - }, "/customer": { "get": { "description": "Overview all customer's list", @@ -331,314 +192,9 @@ const docTemplate = `{ } } } - }, - "/orders": { - "get": { - "description": "Get all order's list", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Order" - ], - "summary": "Get order list", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/order.Order" - } - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/controller.HTTPError" - } - } - } - }, - "post": { - "description": "Create order from Cart", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Order" - ], - "summary": "Create order from Cart", - "parameters": [ - { - "description": "CreateOrderPayload", - "name": "payload", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/controller.CreateOrderPayload" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/order.Order" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/controller.HTTPError" - } - }, - "422": { - "description": "Unprocessable Entity", - "schema": { - "$ref": "#/definitions/controller.HTTPError" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/controller.HTTPError" - } - } - } - } - }, - "/orders/{id}": { - "get": { - "description": "Get an order by ID", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Order" - ], - "summary": "Get order by ID", - "parameters": [ - { - "type": "string", - "description": "ID of the order", - "name": "id", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/order.Order" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/controller.HTTPError" - } - }, - "422": { - "description": "Unprocessable Entity", - "schema": { - "$ref": "#/definitions/controller.HTTPError" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/controller.HTTPError" - } - } - } - }, - "patch": { - "description": "Update by json an Order", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Order" - ], - "summary": "Update an Order", - "parameters": [ - { - "type": "string", - "description": "ID of the Order", - "name": "id", - "in": "path", - "required": true - }, - { - "description": "UpdateOrderPayload", - "name": "payload", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/controller.UpdateOrderPayload" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/order.Order" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/controller.HTTPError" - } - }, - "422": { - "description": "Unprocessable Entity", - "schema": { - "$ref": "#/definitions/controller.HTTPError" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/controller.HTTPError" - } - } - } - } - }, - "/product": { - "get": { - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Product" - ], - "summary": "Search products with given criteria", - "parameters": [ - { - "type": "string", - "description": "Name of Product", - "name": "search", - "in": "path" - }, - { - "type": "string", - "description": "Category of Product", - "name": "category", - "in": "path" - } - ], - "responses": { - "200": { - "description": "product.Product", - "schema": { - "$ref": "#/definitions/product.Product" - } - }, - "500": { - "description": "{\\\"error\\\": \\\"something went bad :(\\\"}", - "schema": { - "type": "object", - "additionalProperties": true - } - } - } - } - }, - "/product/{id}": { - "delete": { - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Product" - ], - "summary": "Delete a Product with given ID", - "parameters": [ - { - "type": "string", - "description": "ID of Product", - "name": "id", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "500": { - "description": "{\\\"error\\\": \\\"something went bad :(\\\"}", - "schema": { - "type": "object", - "additionalProperties": true - } - } - } - } } }, "definitions": { - "controller.AddProductPayload": { - "type": "object", - "required": [ - "client_id", - "product_id", - "quantity" - ], - "properties": { - "client_id": { - "type": "string", - "format": "uuid" - }, - "comments": { - "type": "string" - }, - "product_id": { - "type": "string", - "format": "uuid" - }, - "quantity": { - "type": "integer", - "minimum": 1, - "example": 1 - } - } - }, - "controller.CreateOrderPayload": { - "type": "object", - "required": [ - "client_id" - ], - "properties": { - "client_id": { - "type": "string", - "format": "uuid" - } - } - }, "controller.CustomerPayload": { "type": "object", "required": [ @@ -665,80 +221,6 @@ const docTemplate = `{ } } }, - "controller.EditProductPayload": { - "type": "object", - "required": [ - "client_id", - "product_id", - "quantity" - ], - "properties": { - "client_id": { - "type": "string", - "format": "uuid" - }, - "comments": { - "type": "string" - }, - "product_id": { - "type": "string", - "format": "uuid" - }, - "quantity": { - "type": "integer", - "example": 2 - } - } - }, - "controller.GetCartPayload": { - "type": "object", - "required": [ - "client_id" - ], - "properties": { - "client_id": { - "type": "string", - "format": "uuid" - } - } - }, - "controller.HTTPError": { - "type": "object", - "properties": { - "error": { - "type": "string" - } - } - }, - "controller.RemoveProductPayload": { - "type": "object", - "required": [ - "client_id", - "product_id" - ], - "properties": { - "client_id": { - "type": "string", - "format": "uuid" - }, - "product_id": { - "type": "string", - "format": "uuid" - } - } - }, - "controller.UpdateOrderPayload": { - "type": "object", - "required": [ - "status" - ], - "properties": { - "status": { - "type": "string", - "example": "paid" - } - } - }, "customer.Customer": { "type": "object", "properties": { @@ -758,49 +240,6 @@ const docTemplate = `{ "type": "string" } } - }, - "order.Order": { - "type": "object", - "properties": { - "client_id": { - "type": "string" - }, - "created_at": { - "type": "string" - }, - "id": { - "type": "string" - }, - "status": { - "type": "string" - }, - "total_amount": { - "type": "number" - } - } - }, - "product.Product": { - "type": "object", - "properties": { - "category": { - "type": "string" - }, - "created_at": { - "type": "string" - }, - "description": { - "type": "string" - }, - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "price": { - "type": "number" - } - } } } }` @@ -811,7 +250,7 @@ var SwaggerInfo = &swag.Spec{ Host: "localhost:8080", BasePath: "/", Schemes: []string{}, - Title: "Tech Challenge Food API", + Title: "Tech Challenge Customer Food API", Description: "Fast Food API for FIAP Tech course", InfoInstanceName: "swagger", SwaggerTemplate: docTemplate, diff --git a/docs/swagger.json b/docs/swagger.json index 41203ab..ef1c287 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -2,152 +2,13 @@ "swagger": "2.0", "info": { "description": "Fast Food API for FIAP Tech course", - "title": "Tech Challenge Food API", + "title": "Tech Challenge Customer Food API", "contact": {}, "version": "0.1.0" }, "host": "localhost:8080", "basePath": "/", "paths": { - "/cart/add-product": { - "post": { - "description": "Adds a Product to Customer's Cart", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Cart" - ], - "parameters": [ - { - "description": "AddProductPayload", - "name": "payload", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/controller.AddProductPayload" - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "500": { - "description": "{\\\"error\\\": \\\"Internal Server Error\\\"}", - "schema": { - "type": "object", - "additionalProperties": true - } - } - } - } - }, - "/cart/edit-product": { - "post": { - "description": "Edits a Product from Customer's Cart", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Cart" - ], - "parameters": [ - { - "description": "EditProductPayload", - "name": "payload", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/controller.EditProductPayload" - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "500": { - "description": "{\\\"error\\\": \\\"Internal Server Error\\\"}", - "schema": { - "type": "object", - "additionalProperties": true - } - } - } - } - }, - "/cart/overview": { - "post": { - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Cart" - ], - "parameters": [ - { - "description": "GetCartPayload", - "name": "payload", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/controller.GetCartPayload" - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "500": { - "description": "Internal Server Error" - } - } - } - }, - "/cart/remove-product": { - "post": { - "description": "Removes a Product from Customer's Cart", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Cart" - ], - "parameters": [ - { - "description": "RemoveProductPayload", - "name": "payload", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/controller.RemoveProductPayload" - } - } - ], - "responses": { - "200": { - "description": "OK" - }, - "500": { - "description": "Internal Server Error" - } - } - } - }, "/customer": { "get": { "description": "Overview all customer's list", @@ -325,314 +186,9 @@ } } } - }, - "/orders": { - "get": { - "description": "Get all order's list", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Order" - ], - "summary": "Get order list", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/order.Order" - } - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/controller.HTTPError" - } - } - } - }, - "post": { - "description": "Create order from Cart", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Order" - ], - "summary": "Create order from Cart", - "parameters": [ - { - "description": "CreateOrderPayload", - "name": "payload", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/controller.CreateOrderPayload" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/order.Order" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/controller.HTTPError" - } - }, - "422": { - "description": "Unprocessable Entity", - "schema": { - "$ref": "#/definitions/controller.HTTPError" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/controller.HTTPError" - } - } - } - } - }, - "/orders/{id}": { - "get": { - "description": "Get an order by ID", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Order" - ], - "summary": "Get order by ID", - "parameters": [ - { - "type": "string", - "description": "ID of the order", - "name": "id", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/order.Order" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/controller.HTTPError" - } - }, - "422": { - "description": "Unprocessable Entity", - "schema": { - "$ref": "#/definitions/controller.HTTPError" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/controller.HTTPError" - } - } - } - }, - "patch": { - "description": "Update by json an Order", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Order" - ], - "summary": "Update an Order", - "parameters": [ - { - "type": "string", - "description": "ID of the Order", - "name": "id", - "in": "path", - "required": true - }, - { - "description": "UpdateOrderPayload", - "name": "payload", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/controller.UpdateOrderPayload" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/order.Order" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/controller.HTTPError" - } - }, - "422": { - "description": "Unprocessable Entity", - "schema": { - "$ref": "#/definitions/controller.HTTPError" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/controller.HTTPError" - } - } - } - } - }, - "/product": { - "get": { - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Product" - ], - "summary": "Search products with given criteria", - "parameters": [ - { - "type": "string", - "description": "Name of Product", - "name": "search", - "in": "path" - }, - { - "type": "string", - "description": "Category of Product", - "name": "category", - "in": "path" - } - ], - "responses": { - "200": { - "description": "product.Product", - "schema": { - "$ref": "#/definitions/product.Product" - } - }, - "500": { - "description": "{\\\"error\\\": \\\"something went bad :(\\\"}", - "schema": { - "type": "object", - "additionalProperties": true - } - } - } - } - }, - "/product/{id}": { - "delete": { - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Product" - ], - "summary": "Delete a Product with given ID", - "parameters": [ - { - "type": "string", - "description": "ID of Product", - "name": "id", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "500": { - "description": "{\\\"error\\\": \\\"something went bad :(\\\"}", - "schema": { - "type": "object", - "additionalProperties": true - } - } - } - } } }, "definitions": { - "controller.AddProductPayload": { - "type": "object", - "required": [ - "client_id", - "product_id", - "quantity" - ], - "properties": { - "client_id": { - "type": "string", - "format": "uuid" - }, - "comments": { - "type": "string" - }, - "product_id": { - "type": "string", - "format": "uuid" - }, - "quantity": { - "type": "integer", - "minimum": 1, - "example": 1 - } - } - }, - "controller.CreateOrderPayload": { - "type": "object", - "required": [ - "client_id" - ], - "properties": { - "client_id": { - "type": "string", - "format": "uuid" - } - } - }, "controller.CustomerPayload": { "type": "object", "required": [ @@ -659,80 +215,6 @@ } } }, - "controller.EditProductPayload": { - "type": "object", - "required": [ - "client_id", - "product_id", - "quantity" - ], - "properties": { - "client_id": { - "type": "string", - "format": "uuid" - }, - "comments": { - "type": "string" - }, - "product_id": { - "type": "string", - "format": "uuid" - }, - "quantity": { - "type": "integer", - "example": 2 - } - } - }, - "controller.GetCartPayload": { - "type": "object", - "required": [ - "client_id" - ], - "properties": { - "client_id": { - "type": "string", - "format": "uuid" - } - } - }, - "controller.HTTPError": { - "type": "object", - "properties": { - "error": { - "type": "string" - } - } - }, - "controller.RemoveProductPayload": { - "type": "object", - "required": [ - "client_id", - "product_id" - ], - "properties": { - "client_id": { - "type": "string", - "format": "uuid" - }, - "product_id": { - "type": "string", - "format": "uuid" - } - } - }, - "controller.UpdateOrderPayload": { - "type": "object", - "required": [ - "status" - ], - "properties": { - "status": { - "type": "string", - "example": "paid" - } - } - }, "customer.Customer": { "type": "object", "properties": { @@ -752,49 +234,6 @@ "type": "string" } } - }, - "order.Order": { - "type": "object", - "properties": { - "client_id": { - "type": "string" - }, - "created_at": { - "type": "string" - }, - "id": { - "type": "string" - }, - "status": { - "type": "string" - }, - "total_amount": { - "type": "number" - } - } - }, - "product.Product": { - "type": "object", - "properties": { - "category": { - "type": "string" - }, - "created_at": { - "type": "string" - }, - "description": { - "type": "string" - }, - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "price": { - "type": "number" - } - } } } } \ No newline at end of file diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 96d2ea9..9434671 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -1,32 +1,5 @@ basePath: / definitions: - controller.AddProductPayload: - properties: - client_id: - format: uuid - type: string - comments: - type: string - product_id: - format: uuid - type: string - quantity: - example: 1 - minimum: 1 - type: integer - required: - - client_id - - product_id - - quantity - type: object - controller.CreateOrderPayload: - properties: - client_id: - format: uuid - type: string - required: - - client_id - type: object controller.CustomerPayload: properties: age: @@ -46,57 +19,6 @@ definitions: - email - name type: object - controller.EditProductPayload: - properties: - client_id: - format: uuid - type: string - comments: - type: string - product_id: - format: uuid - type: string - quantity: - example: 2 - type: integer - required: - - client_id - - product_id - - quantity - type: object - controller.GetCartPayload: - properties: - client_id: - format: uuid - type: string - required: - - client_id - type: object - controller.HTTPError: - properties: - error: - type: string - type: object - controller.RemoveProductPayload: - properties: - client_id: - format: uuid - type: string - product_id: - format: uuid - type: string - required: - - client_id - - product_id - type: object - controller.UpdateOrderPayload: - properties: - status: - example: paid - type: string - required: - - status - type: object customer.Customer: properties: age: @@ -110,130 +32,13 @@ definitions: name: type: string type: object - order.Order: - properties: - client_id: - type: string - created_at: - type: string - id: - type: string - status: - type: string - total_amount: - type: number - type: object - product.Product: - properties: - category: - type: string - created_at: - type: string - description: - type: string - id: - type: string - name: - type: string - price: - type: number - type: object host: localhost:8080 info: contact: {} description: Fast Food API for FIAP Tech course - title: Tech Challenge Food API + title: Tech Challenge Customer Food API version: 0.1.0 paths: - /cart/add-product: - post: - consumes: - - application/json - description: Adds a Product to Customer's Cart - parameters: - - description: AddProductPayload - in: body - name: payload - required: true - schema: - $ref: '#/definitions/controller.AddProductPayload' - produces: - - application/json - responses: - "200": - description: OK - "500": - description: '{\"error\": \"Internal Server Error\"}' - schema: - additionalProperties: true - type: object - tags: - - Cart - /cart/edit-product: - post: - consumes: - - application/json - description: Edits a Product from Customer's Cart - parameters: - - description: EditProductPayload - in: body - name: payload - required: true - schema: - $ref: '#/definitions/controller.EditProductPayload' - produces: - - application/json - responses: - "200": - description: OK - "500": - description: '{\"error\": \"Internal Server Error\"}' - schema: - additionalProperties: true - type: object - tags: - - Cart - /cart/overview: - post: - consumes: - - application/json - parameters: - - description: GetCartPayload - in: body - name: payload - required: true - schema: - $ref: '#/definitions/controller.GetCartPayload' - produces: - - application/json - responses: - "200": - description: OK - "500": - description: Internal Server Error - tags: - - Cart - /cart/remove-product: - post: - consumes: - - application/json - description: Removes a Product from Customer's Cart - parameters: - - description: RemoveProductPayload - in: body - name: payload - required: true - schema: - $ref: '#/definitions/controller.RemoveProductPayload' - produces: - - application/json - responses: - "200": - description: OK - "500": - description: Internal Server Error - tags: - - Cart /customer: get: consumes: @@ -352,180 +157,4 @@ paths: summary: Update customer tags: - Customer - /orders: - get: - consumes: - - application/json - description: Get all order's list - produces: - - application/json - responses: - "200": - description: OK - schema: - items: - $ref: '#/definitions/order.Order' - type: array - "500": - description: Internal Server Error - schema: - $ref: '#/definitions/controller.HTTPError' - summary: Get order list - tags: - - Order - post: - consumes: - - application/json - description: Create order from Cart - parameters: - - description: CreateOrderPayload - in: body - name: payload - required: true - schema: - $ref: '#/definitions/controller.CreateOrderPayload' - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/order.Order' - "400": - description: Bad Request - schema: - $ref: '#/definitions/controller.HTTPError' - "422": - description: Unprocessable Entity - schema: - $ref: '#/definitions/controller.HTTPError' - "500": - description: Internal Server Error - schema: - $ref: '#/definitions/controller.HTTPError' - summary: Create order from Cart - tags: - - Order - /orders/{id}: - get: - consumes: - - application/json - description: Get an order by ID - parameters: - - description: ID of the order - in: path - name: id - required: true - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/order.Order' - "400": - description: Bad Request - schema: - $ref: '#/definitions/controller.HTTPError' - "422": - description: Unprocessable Entity - schema: - $ref: '#/definitions/controller.HTTPError' - "500": - description: Internal Server Error - schema: - $ref: '#/definitions/controller.HTTPError' - summary: Get order by ID - tags: - - Order - patch: - consumes: - - application/json - description: Update by json an Order - parameters: - - description: ID of the Order - in: path - name: id - required: true - type: string - - description: UpdateOrderPayload - in: body - name: payload - required: true - schema: - $ref: '#/definitions/controller.UpdateOrderPayload' - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/order.Order' - "400": - description: Bad Request - schema: - $ref: '#/definitions/controller.HTTPError' - "422": - description: Unprocessable Entity - schema: - $ref: '#/definitions/controller.HTTPError' - "500": - description: Internal Server Error - schema: - $ref: '#/definitions/controller.HTTPError' - summary: Update an Order - tags: - - Order - /product: - get: - consumes: - - application/json - parameters: - - description: Name of Product - in: path - name: search - type: string - - description: Category of Product - in: path - name: category - type: string - produces: - - application/json - responses: - "200": - description: product.Product - schema: - $ref: '#/definitions/product.Product' - "500": - description: '{\"error\": \"something went bad :(\"}' - schema: - additionalProperties: true - type: object - summary: Search products with given criteria - tags: - - Product - /product/{id}: - delete: - consumes: - - application/json - parameters: - - description: ID of Product - in: path - name: id - required: true - type: string - produces: - - application/json - responses: - "204": - description: No Content - "500": - description: '{\"error\": \"something went bad :(\"}' - schema: - additionalProperties: true - type: object - summary: Delete a Product with given ID - tags: - - Product swagger: "2.0" diff --git a/internal/adapters/rest/controller/cart_controller.go b/internal/adapters/rest/controller/cart_controller.go deleted file mode 100644 index 8946bd0..0000000 --- a/internal/adapters/rest/controller/cart_controller.go +++ /dev/null @@ -1,156 +0,0 @@ -package controller - -import ( - "github.com/pangolin-do-golang/tech-challenge/internal/core/cart" - "github.com/pangolin-do-golang/tech-challenge/internal/errutil" - "net/http" - - "github.com/gin-gonic/gin" - "github.com/google/uuid" -) - -type CartController struct { - AbstractController - service cart.IService -} - -func NewCartController(cart cart.IService) *CartController { - return &CartController{ - service: cart, - } -} - -type AddProductPayload struct { - ClientID uuid.UUID `json:"client_id" binding:"required" format:"uuid"` - ProductID uuid.UUID `json:"product_id" binding:"required" format:"uuid"` - Quantity int `json:"quantity" binding:"required,min=1" example:"1"` - Comments string `json:"comments"` -} - -// AddProduct adds a Product to Customer's Cart -// @Description Adds a Product to Customer's Cart -// @Tags Cart -// @Param payload body controller.AddProductPayload true "AddProductPayload" -// @Accept json -// @Produce json -// @Success 200 -// @Failure 500 {object} map[string]any "{\"error\": \"Internal Server Error\"}" -// @Router /cart/add-product [post] -func (ctrl CartController) AddProduct(c *gin.Context) { - payload := &AddProductPayload{} - err := c.BindJSON(payload) - if err != nil { - ctrl.Error(c, errutil.NewInputError(err)) - return - } - - err = ctrl.service.AddProduct(c.Request.Context(), payload.ClientID, &cart.Product{ - ProductID: payload.ProductID, - Quantity: payload.Quantity, - Comments: payload.Comments, - }) - - if err != nil { - ctrl.Error(c, err) - return - } - - c.Status(http.StatusOK) -} - -type EditProductPayload struct { - ClientID uuid.UUID `json:"client_id" binding:"required" format:"uuid"` - ProductID uuid.UUID `json:"product_id" binding:"required" format:"uuid"` - Quantity int `json:"quantity" binding:"required" example:"2"` - Comments string `json:"comments"` -} - -// EditProduct edits a Product from Cart by ID -// @Description Edits a Product from Customer's Cart -// @Tags Cart -// @Param payload body controller.EditProductPayload true "EditProductPayload" -// @Accept json -// @Produce json -// @Success 200 -// @Failure 500 {object} map[string]any "{\"error\": \"Internal Server Error\"}" -// @Router /cart/edit-product [post] -func (ctrl CartController) EditProduct(c *gin.Context) { - payload := &EditProductPayload{} - err := c.BindJSON(payload) - if err != nil { - ctrl.Error(c, errutil.NewInputError(err)) - return - } - - err = ctrl.service.EditProduct(c.Request.Context(), payload.ClientID, &cart.Product{ - ProductID: payload.ProductID, - Quantity: payload.Quantity, - Comments: payload.Comments, - }) - if err != nil { - ctrl.Error(c, err) - return - } - - c.Status(http.StatusOK) -} - -type RemoveProductPayload struct { - ClientID uuid.UUID `json:"client_id" binding:"required" format:"uuid"` - ProductID uuid.UUID `json:"product_id" binding:"required" format:"uuid"` -} - -// RemoveProduct removes a Product from Customer's Cart -// @Description Removes a Product from Customer's Cart -// @Tags Cart -// @Param payload body controller.RemoveProductPayload true "RemoveProductPayload" -// @Accept json -// @Produce json -// @Success 200 -// @Failure 500 "Internal Server Error" -// @Router /cart/remove-product [post] -func (ctrl CartController) RemoveProduct(c *gin.Context) { - payload := &RemoveProductPayload{} - err := c.BindJSON(payload) - if err != nil { - ctrl.Error(c, errutil.NewInputError(err)) - return - } - - err = ctrl.service.RemoveProduct(c.Request.Context(), payload.ClientID, payload.ProductID) - if err != nil { - ctrl.Error(c, err) - return - } - - c.Status(http.StatusOK) -} - -type GetCartPayload struct { - ClientID uuid.UUID `json:"client_id" binding:"required" format:"uuid"` -} - -// Overview get the full cart and its products -// @Tags Cart -// @Param payload body controller.GetCartPayload true "GetCartPayload" -// @Accept json -// @Produce json -// @Success 200 -// @Failure 500 "Internal Server Error" -// @Router /cart/overview [post] -func (ctrl CartController) Overview(c *gin.Context) { - payload := &GetCartPayload{} - err := c.BindJSON(payload) - if err != nil { - ctrl.Error(c, errutil.NewInputError(err)) - return - } - - fullcart, err := ctrl.service.GetFullCart(payload.ClientID) - if err != nil { - ctrl.Error(c, err) - return - } - - c.JSON(http.StatusOK, fullcart) -} diff --git a/internal/adapters/rest/controller/order_controller.go b/internal/adapters/rest/controller/order_controller.go deleted file mode 100644 index 4ba9aad..0000000 --- a/internal/adapters/rest/controller/order_controller.go +++ /dev/null @@ -1,145 +0,0 @@ -package controller - -import ( - "github.com/pangolin-do-golang/tech-challenge/internal/errutil" - "net/http" - "strings" - - "github.com/gin-gonic/gin" - "github.com/google/uuid" - "github.com/pangolin-do-golang/tech-challenge/internal/core/order" -) - -type OrderController struct { - AbstractController - service order.IOrderService -} - -func NewOrderController(service order.IOrderService) *OrderController { - return &OrderController{ - service: service, - } -} - -// GetAll Get all order's list -// @Summary Get order list -// @Description Get all order's list -// @Tags Order -// @Accept json -// @Produce json -// @Success 200 {object} []order.Order{} -// @Success 500 {object} HTTPError -// @Router /orders [get] -func (ctrl *OrderController) GetAll(c *gin.Context) { - orderSlice, err := ctrl.service.GetAll() - - if err != nil { - ctrl.Error(c, err) - return - } - - c.JSON(http.StatusOK, orderSlice) -} - -type CreateOrderPayload struct { - ClientID uuid.UUID `json:"client_id" binding:"required" format:"uuid"` -} - -// Create Order godoc -// @Summary Create order from Cart -// @Description Create order from Cart -// @Param payload body controller.CreateOrderPayload true "CreateOrderPayload" -// @Tags Order -// @Accept json -// @Produce json -// @Success 200 {object} order.Order{} -// @Failure 400 {object} HTTPError -// @Failure 422 {object} HTTPError -// @Failure 500 {object} HTTPError -// @Router /orders [post] -func (ctrl *OrderController) Create(c *gin.Context) { - payload := &CreateOrderPayload{} - - if err := c.ShouldBindJSON(&payload); err != nil { - ctrl.Error(c, errutil.NewInputError(err)) - - return - } - - o, err := ctrl.service.Create(payload.ClientID) - if err != nil { - ctrl.Error(c, err) - - return - } - - c.JSON(http.StatusOK, o) -} - -// Get an order by ID -// @Summary Get order by ID -// @Description Get an order by ID -// @Tags Order -// @Param id path string true "ID of the order" -// @Accept json -// @Produce json -// @Success 200 {object} order.Order{} -// @Failure 400 {object} HTTPError -// @Failure 422 {object} HTTPError -// @Failure 500 {object} HTTPError -// @Router /orders/{id} [get] -func (ctrl *OrderController) Get(c *gin.Context) { - id, err := uuid.Parse(c.Param("id")) - - if err != nil { - ctrl.Error(c, errutil.NewInputError(err)) - return - } - - o, err := ctrl.service.Get(id) - if err != nil { - ctrl.Error(c, err) - - return - } - - c.JSON(http.StatusOK, o) -} - -type UpdateOrderPayload struct { - Status string `json:"status" binding:"required" example:"paid"` -} - -// Update Order godoc -// @Summary Update an Order -// @Description Update by json an Order -// @Param id path string true "ID of the Order" -// @Param payload body controller.UpdateOrderPayload true "UpdateOrderPayload" -// @Tags Order -// @Accept json -// @Produce json -// @Success 200 {object} order.Order{} -// @Failure 400 {object} HTTPError -// @Failure 422 {object} HTTPError -// @Failure 500 {object} HTTPError -// @Router /orders/{id} [patch] -func (ctrl *OrderController) Update(c *gin.Context) { - id, err := uuid.Parse(c.Param("id")) - payload := &UpdateOrderPayload{} - - if err := c.ShouldBindJSON(&payload); err != nil { - ctrl.Error(c, errutil.NewInputError(err)) - return - } - - o, err := ctrl.service.Update(&order.Order{ - ID: id, - Status: strings.ToUpper(payload.Status), - }) - if err != nil { - ctrl.Error(c, err) - return - } - - c.JSON(http.StatusOK, o) -} diff --git a/internal/adapters/rest/controller/product_controller.go b/internal/adapters/rest/controller/product_controller.go deleted file mode 100644 index dd9d0a5..0000000 --- a/internal/adapters/rest/controller/product_controller.go +++ /dev/null @@ -1,69 +0,0 @@ -package controller - -import ( - "github.com/gin-gonic/gin" - "github.com/google/uuid" - "github.com/pangolin-do-golang/tech-challenge/internal/core/product" - "github.com/pangolin-do-golang/tech-challenge/internal/errutil" - "net/http" -) - -type ProductController struct { - AbstractController - service *product.Service -} - -func NewProductController(service *product.Service) *ProductController { - return &ProductController{ - service: service, - } -} - -// Search for products -// @Summary Search products with given criteria -// @Tags Product -// @Param search path string false "Name of Product" -// @Param category path string false "Category of Product" -// @Accept json -// @Produce json -// @Success 200 {object} product.Product "product.Product" -// @Failure 500 {object} map[string]any "{\"error\": \"something went bad :(\"}" -// @Router /product [get] -func (ctrl *ProductController) Search(c *gin.Context) { - search := c.Query("search") - category := c.Query("category") - - products, err := ctrl.service.Search(search, category) - if err != nil { - ctrl.Error(c, err) - return - } - - c.JSON(http.StatusOK, products) -} - -// Delete a Product -// @Summary Delete a Product with given ID -// @Tags Product -// @Param id path string true "ID of Product" -// @Accept json -// @Produce json -// @Success 204 -// @Failure 500 {object} map[string]any "{\"error\": \"something went bad :(\"}" -// @Router /product/{id} [delete] -func (ctrl *ProductController) Delete(c *gin.Context) { - id, err := uuid.Parse(c.Param("id")) - - if err != nil { - ctrl.Error(c, errutil.NewInputError(err)) - return - } - - err = ctrl.service.Delete(id) - if err != nil { - ctrl.Error(c, err) - return - } - - c.JSON(http.StatusNoContent, gin.H{}) -} diff --git a/internal/adapters/rest/handler/cart.go b/internal/adapters/rest/handler/cart.go deleted file mode 100644 index 0d92231..0000000 --- a/internal/adapters/rest/handler/cart.go +++ /dev/null @@ -1,16 +0,0 @@ -package handler - -import ( - "github.com/gin-gonic/gin" - "github.com/pangolin-do-golang/tech-challenge/internal/adapters/rest/controller" - "github.com/pangolin-do-golang/tech-challenge/internal/core/cart" -) - -func RegisterCartHandlers(router *gin.Engine, service cart.IService) { - cartController := controller.NewCartController(service) - - router.POST("/cart/overview", cartController.Overview) - router.POST("/cart/add-product", cartController.AddProduct) - router.POST("/cart/remove-product", cartController.RemoveProduct) - router.POST("/cart/edit-product", cartController.EditProduct) -} diff --git a/internal/adapters/rest/handler/order.go b/internal/adapters/rest/handler/order.go deleted file mode 100644 index 8e25172..0000000 --- a/internal/adapters/rest/handler/order.go +++ /dev/null @@ -1,21 +0,0 @@ -package handler - -import ( - "github.com/gin-gonic/gin" - "github.com/pangolin-do-golang/tech-challenge/internal/adapters/rest/controller" - "github.com/pangolin-do-golang/tech-challenge/internal/core/cart" - "github.com/pangolin-do-golang/tech-challenge/internal/core/order" -) - -type OrderHandler struct { - service *cart.Service -} - -func RegisterOrderHandlers(router *gin.Engine, service order.IOrderService) { - orderController := controller.NewOrderController(service) - - router.POST("/orders", orderController.Create) - router.GET("/orders", orderController.GetAll) - router.GET("/orders/:id", orderController.Get) - router.PATCH("/orders/:id", orderController.Update) -} diff --git a/internal/adapters/rest/handler/product.go b/internal/adapters/rest/handler/product.go deleted file mode 100644 index e8dac05..0000000 --- a/internal/adapters/rest/handler/product.go +++ /dev/null @@ -1,15 +0,0 @@ -package handler - -import ( - "github.com/gin-gonic/gin" - "github.com/pangolin-do-golang/tech-challenge/internal/adapters/rest/controller" - "github.com/pangolin-do-golang/tech-challenge/internal/core/product" -) - -func RegisterProductHandlers(router *gin.Engine, service *product.Service) { - productController := controller.NewProductController(service) - - router.GET("/product", productController.Search) - - router.DELETE("/product/:id") -} diff --git a/internal/adapters/rest/server/server.go b/internal/adapters/rest/server/server.go index f11d322..2d7f75c 100644 --- a/internal/adapters/rest/server/server.go +++ b/internal/adapters/rest/server/server.go @@ -6,31 +6,19 @@ import ( "github.com/gin-gonic/gin" "github.com/pangolin-do-golang/tech-challenge/internal/adapters/rest/handler" "github.com/pangolin-do-golang/tech-challenge/internal/adapters/rest/middleware" - "github.com/pangolin-do-golang/tech-challenge/internal/core/cart" "github.com/pangolin-do-golang/tech-challenge/internal/core/customer" - "github.com/pangolin-do-golang/tech-challenge/internal/core/order" - "github.com/pangolin-do-golang/tech-challenge/internal/core/product" ) type RestServer struct { - orderService order.IOrderService - productService *product.Service - cartService cart.IService customerService customer.IService } type RestServerOptions struct { - OrderService order.IOrderService - ProductService *product.Service - CartService cart.IService CustomerService customer.IService } func NewRestServer(options *RestServerOptions) *RestServer { return &RestServer{ - orderService: options.OrderService, - productService: options.ProductService, - cartService: options.CartService, customerService: options.CustomerService, } } @@ -42,9 +30,6 @@ func (rs RestServer) Serve() { c.Status(http.StatusOK) }) - handler.RegisterOrderHandlers(r, rs.orderService) - handler.RegisterProductHandlers(r, rs.productService) - handler.RegisterCartHandlers(r, rs.cartService) handler.RegisterCustomerHandlers(r, rs.customerService) handler.RegisterSwaggerHandlers(r) err := r.Run("0.0.0.0:8080") diff --git a/internal/core/cart/cart.go b/internal/core/cart/cart.go deleted file mode 100644 index 8abc985..0000000 --- a/internal/core/cart/cart.go +++ /dev/null @@ -1,40 +0,0 @@ -package cart - -import ( - "context" - - "github.com/google/uuid" -) - -type Cart struct { - ID uuid.UUID `json:"id"` - ClientID uuid.UUID `json:"client_id"` - Products []*Product `json:"products"` -} - -type Product struct { - ProductID uuid.UUID `json:"product_id"` - Quantity int `json:"quantity"` - Comments string `json:"comments,omitempty"` -} - -type ICartRepository interface { - Create(clientID uuid.UUID) (*Cart, error) - Get(clientID uuid.UUID) (*Cart, error) -} - -type ICartProductRepository interface { - Create(ctx context.Context, cartID uuid.UUID, product *Product) error - GetByCartID(ctx context.Context, cartID uuid.UUID) ([]*Product, error) - DeleteByProductID(ctx context.Context, cartID, productID uuid.UUID) error - UpdateProductByProductID(ctx context.Context, cartID, productID uuid.UUID, product *Product) error -} - -type IService interface { - LoadCart(ctx context.Context, clientID uuid.UUID) (*Cart, error) - GetFullCart(clientID uuid.UUID) (*Cart, error) - AddProduct(ctx context.Context, clientID uuid.UUID, product *Product) error - RemoveProduct(ctx context.Context, clientID uuid.UUID, productID uuid.UUID) error - EditProduct(ctx context.Context, clientID uuid.UUID, product *Product) error - Cleanup(clientID uuid.UUID) error -} diff --git a/internal/core/cart/cart_service.go b/internal/core/cart/cart_service.go deleted file mode 100644 index 82df029..0000000 --- a/internal/core/cart/cart_service.go +++ /dev/null @@ -1,109 +0,0 @@ -package cart - -import ( - "context" - "errors" - "github.com/google/uuid" - "github.com/pangolin-do-golang/tech-challenge/internal/errutil" -) - -type Service struct { - CartRepository ICartRepository - CartProductsRepository ICartProductRepository -} - -func NewService(cartRepository ICartRepository, cartProductsRepository ICartProductRepository) IService { - return &Service{ - CartRepository: cartRepository, - CartProductsRepository: cartProductsRepository, - } -} - -func (s *Service) LoadCart(_ context.Context, clientID uuid.UUID) (*Cart, error) { - cart, err := s.CartRepository.Get(clientID) - if err != nil { - if !errors.Is(err, errutil.ErrRecordNotFound) { - return nil, err - } - - cart, err = s.CartRepository.Create(clientID) - if err != nil { - return nil, err - } - } - - return cart, nil - -} - -func (s *Service) GetFullCart(clientID uuid.UUID) (*Cart, error) { - cart, err := s.CartRepository.Get(clientID) - if err != nil { - return nil, err - } - - products, err := s.CartProductsRepository.GetByCartID(context.Background(), cart.ID) - if err != nil { - return nil, err - } - - cart.Products = products - - return cart, nil -} - -func (s *Service) Cleanup(clientID uuid.UUID) error { - cart, err := s.LoadCart(context.Background(), clientID) - if err != nil { - return err - } - - products, err := s.CartProductsRepository.GetByCartID(context.Background(), cart.ID) - for _, p := range products { - err = s.CartProductsRepository.DeleteByProductID(context.Background(), cart.ID, p.ProductID) - if err != nil { - return err - } - } - - return nil -} - -func (s *Service) AddProduct(ctx context.Context, clientID uuid.UUID, product *Product) error { - cart, err := s.LoadCart(ctx, clientID) - if err != nil { - return err - } - - // TODO verificar se produto já tá no carrinho/colocar índice de unicidade - return s.CartProductsRepository.Create(ctx, cart.ID, product) -} - -func (s *Service) RemoveProduct(ctx context.Context, clientID uuid.UUID, productID uuid.UUID) error { - cart, err := s.LoadCart(ctx, clientID) - if err != nil { - return err - } - - products, err := s.CartProductsRepository.GetByCartID(ctx, cart.ID) - if err != nil { - return err - } - - for _, product := range products { - if product.ProductID == productID { - return s.CartProductsRepository.DeleteByProductID(ctx, cart.ID, productID) - } - } - - return nil -} - -func (s *Service) EditProduct(ctx context.Context, clientID uuid.UUID, product *Product) error { - cart, err := s.LoadCart(ctx, clientID) - if err != nil { - return err - } - - return s.CartProductsRepository.UpdateProductByProductID(ctx, cart.ID, product.ProductID, product) -} diff --git a/internal/core/order/order.go b/internal/core/order/order.go deleted file mode 100644 index 34ac964..0000000 --- a/internal/core/order/order.go +++ /dev/null @@ -1,84 +0,0 @@ -package order - -import ( - "context" - "errors" - - "time" - - "github.com/google/uuid" -) - -const ( - StatusPending = "PENDING" - StatusCreated = "CREATED" - StatusPreparing = "PREPARING" - StatusReady = "READY" - StatusFinished = "FINISHED" - StatusPaid = "PAID" - StatusDeclined = "DECLINED" - StatusCanceled = "CANCELED" -) - -var ErrInvalidStatus = errors.New("invalid status transition") - -type Order struct { - ID uuid.UUID `json:"id"` - CreatedAt time.Time `json:"created_at"` - ClientID uuid.UUID `json:"client_id"` - TotalAmount float64 `json:"total_amount"` - Status string `json:"status"` -} - -func (o Order) ValidateStatusTransition(nextStatus string) error { - switch o.Status { - case StatusCreated: - if nextStatus != StatusPending { - return ErrInvalidStatus - } - case StatusPending: - if nextStatus != StatusPaid && nextStatus != StatusDeclined { - return ErrInvalidStatus - } - case StatusPaid: - if nextStatus != StatusPreparing { - return ErrInvalidStatus - } - case StatusPreparing: - if nextStatus != StatusFinished { - return ErrInvalidStatus - } - case StatusCanceled: - return ErrInvalidStatus - default: - return ErrInvalidStatus - } - return nil -} - -type Product struct { - ClientID uuid.UUID `json:"client_id"` - ProductID uuid.UUID `json:"product_id"` - Quantity int `json:"quantity"` - Comments string `json:"comments"` - Total float64 `json:"total"` -} - -type IOrderService interface { - Get(id uuid.UUID) (*Order, error) - Create(clientID uuid.UUID) (*Order, error) - GetAll() ([]Order, error) - Update(order *Order) (*Order, error) -} - -type IOrderProductRepository interface { - Create(ctx context.Context, orderID uuid.UUID, product *Product) error - GetByOrderID(ctx context.Context, orderID uuid.UUID) ([]*Product, error) -} - -type IOrderRepository interface { - Create(order *Order) (*Order, error) - Update(order *Order) error - Get(id uuid.UUID) (*Order, error) - GetAll() ([]Order, error) -} diff --git a/internal/core/order/order_service.go b/internal/core/order/order_service.go deleted file mode 100644 index 40b350b..0000000 --- a/internal/core/order/order_service.go +++ /dev/null @@ -1,133 +0,0 @@ -package order - -import ( - "context" - "errors" - "fmt" - "github.com/google/uuid" - "github.com/pangolin-do-golang/tech-challenge/internal/core/cart" - "github.com/pangolin-do-golang/tech-challenge/internal/core/product" - "github.com/pangolin-do-golang/tech-challenge/internal/errutil" -) - -type Service struct { - OrderRepository IOrderRepository - OrderProductRepository IOrderProductRepository - CartService cart.IService - ProductService *product.Service -} - -func NewOrderService(repo IOrderRepository, orderProductRepository IOrderProductRepository, cartService cart.IService, productService *product.Service) IOrderService { - return &Service{ - OrderRepository: repo, - OrderProductRepository: orderProductRepository, - CartService: cartService, - ProductService: productService, - } -} - -func (s *Service) Get(id uuid.UUID) (*Order, error) { - o, err := s.OrderRepository.Get(id) - if err != nil { - if errors.Is(err, errutil.ErrRecordNotFound) { - return nil, errutil.NewBusinessError(err, "order not found") - } - - return nil, err - } - - return o, nil -} - -func (s *Service) GetAll() ([]Order, error) { - return s.OrderRepository.GetAll() -} - -func (s *Service) Update(order *Order) (*Order, error) { - o, err := s.OrderRepository.Get(order.ID) - if err != nil { - return nil, errutil.NewBusinessError(err, "order not found") - } - - if err := o.ValidateStatusTransition(order.Status); err != nil { - return nil, errutil.NewBusinessError(err, err.Error()) - } - - o.Status = order.Status - err = s.OrderRepository.Update(o) - if err != nil { - return nil, err - } - oldOrder := *o - - // "simula" o período de uma tarefa async/em segundo plano pegar o - // pedido "pago" e mudar o status para "preparando"1 - // dessa forma o usuário recebe o status "PAID" - if o.Status == StatusPaid { - o.Status = StatusPreparing - if err := s.OrderRepository.Update(o); err != nil { - return nil, err - } - } - - return &oldOrder, nil -} - -func (s *Service) Create(clientID uuid.UUID) (*Order, error) { - c, err := s.CartService.GetFullCart(clientID) - if err != nil { - return nil, err - } - - if len(c.Products) == 0 { - return nil, fmt.Errorf("empty cart") - } - - order := &Order{ - ClientID: clientID, - Status: StatusCreated, - } - - o, err := s.OrderRepository.Create(order) - if err != nil { - return nil, err - } - - var total float64 - for _, p := range c.Products { - stockProduct, err := s.ProductService.GetByID(p.ProductID) - if err != nil { - return nil, err - } - - productTotal := stockProduct.Price * float64(p.Quantity) - - orderProduct := &Product{ - ClientID: clientID, - ProductID: p.ProductID, - Quantity: p.Quantity, - Comments: p.Comments, - Total: productTotal, - } - - err = s.OrderProductRepository.Create(context.Background(), o.ID, orderProduct) - if err != nil { - return nil, err - } - - total += productTotal - } - - o.TotalAmount = total - o.Status = StatusPending - err = s.OrderRepository.Update(o) - if err != nil { - return nil, err - } - - if err = s.CartService.Cleanup(clientID); err != nil { - return nil, err - } - - return o, nil -} diff --git a/internal/core/product/product.go b/internal/core/product/product.go deleted file mode 100644 index 2f9fc21..0000000 --- a/internal/core/product/product.go +++ /dev/null @@ -1,22 +0,0 @@ -package product - -import ( - "time" - - "github.com/google/uuid" -) - -type Product struct { - Id uuid.UUID `json:"id"` - Name string `json:"name"` - Description string `json:"description"` - Category string `json:"category"` - Price float64 `json:"price"` - CreatedAt time.Time `json:"created_at"` -} - -type Repository interface { - Search(search string, category string) (*[]Product, error) - Delete(id uuid.UUID) error - GetByID(id uuid.UUID) (*Product, error) -} diff --git a/internal/core/product/product_service.go b/internal/core/product/product_service.go deleted file mode 100644 index 0676a97..0000000 --- a/internal/core/product/product_service.go +++ /dev/null @@ -1,27 +0,0 @@ -package product - -import ( - "github.com/google/uuid" -) - -type Service struct { - repo Repository -} - -func NewProductService(repo Repository) *Service { - return &Service{ - repo: repo, - } -} - -func (s *Service) Search(search string, category string) (*[]Product, error) { - return s.repo.Search(search, category) -} - -func (s *Service) Delete(id uuid.UUID) error { - return s.repo.Delete(id) -} - -func (s *Service) GetByID(id uuid.UUID) (*Product, error) { - return s.repo.GetByID(id) -}