From b5b9673e00c135dd3b5901355c799fa1bf64c091 Mon Sep 17 00:00:00 2001 From: Matheus <30qr4xnl@duck.com> Date: Tue, 3 Sep 2024 00:49:22 -0300 Subject: [PATCH 01/14] feature/lgpd-exclusion-api: criando dto, entity e model --- .../domain/dtos/lgpd_removal_request_dto.go | 8 ++++++ .../domain/entities/lgpd_removal_request.go | 10 +++++++ .../db/models/lgpd_request_removal_model.go | 26 +++++++++++++++++++ 3 files changed, 44 insertions(+) create mode 100644 src/core/domain/dtos/lgpd_removal_request_dto.go create mode 100644 src/core/domain/entities/lgpd_removal_request.go create mode 100644 src/infra/db/models/lgpd_request_removal_model.go diff --git a/src/core/domain/dtos/lgpd_removal_request_dto.go b/src/core/domain/dtos/lgpd_removal_request_dto.go new file mode 100644 index 0000000..694f3c4 --- /dev/null +++ b/src/core/domain/dtos/lgpd_removal_request_dto.go @@ -0,0 +1,8 @@ +package dtos + +type LGPDRemovalRequestDto struct { + Name string `json:"name" validate:"required, regexp=^[a-zA-ZÀ-ÿ'’\- ]{1,255}$"` + Address string `json:"address" validate:"required, regexp=^[a-zA-ZÀ-ÿ'’\- ]{1,255}$"` + PhoneNumber string `json:"phone_number" validate:"required, regexp=^\+?(\d{1,3})?[-.\s]?(\(?\d{2}\)?)?[-.\s]?\d{4,5}[-.\s]?\d{4}$"` + PaymentHistory bool `json:"payment_history" validate:"required,oneof=true false"` +} diff --git a/src/core/domain/entities/lgpd_removal_request.go b/src/core/domain/entities/lgpd_removal_request.go new file mode 100644 index 0000000..8c13124 --- /dev/null +++ b/src/core/domain/entities/lgpd_removal_request.go @@ -0,0 +1,10 @@ +package entities + +type LgpdRemovalRequest struct { + ID uint `json:"id"` + Name string `json:"name"` + Address string `json:"address"` + PhoneNumber string `json:"phone_number"` + PaymentHistory bool `json:"payment_history"` + CreatedAt string `json:"createdAt"` +} diff --git a/src/infra/db/models/lgpd_request_removal_model.go b/src/infra/db/models/lgpd_request_removal_model.go new file mode 100644 index 0000000..4553134 --- /dev/null +++ b/src/infra/db/models/lgpd_request_removal_model.go @@ -0,0 +1,26 @@ +package models + +import ( + "github.com/CAVAh/api-tech-challenge/src/core/domain/entities" + "github.com/CAVAh/api-tech-challenge/src/utils" + "gorm.io/gorm" +) + +type LgpdRemovalRequest struct { + gorm.Model + Name string + Address string + PhoneNumber string + PaymentHistory bool +} + +func (c LgpdRemovalRequest) ToDomain() entities.LgpdRemovalRequest { + return entities.LgpdRemovalRequest{ + ID: c.ID, + Name: c.Name, + Address: c.Address, + PhoneNumber: c.PhoneNumber, + PaymentHistory: c.PaymentHistory, + CreatedAt: c.CreatedAt.Format(utils.CompleteEnglishDateFormat), + } +} From e4a2ab37d91277886b4007f2eb0a7af07406dbe8 Mon Sep 17 00:00:00 2001 From: Matheus <30qr4xnl@duck.com> Date: Tue, 3 Sep 2024 00:49:47 -0300 Subject: [PATCH 02/14] feature/lgpd-exclusion-api: criando migration novo model --- src/infra/db/database/database.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/infra/db/database/database.go b/src/infra/db/database/database.go index 8f53f6c..606cd3b 100644 --- a/src/infra/db/database/database.go +++ b/src/infra/db/database/database.go @@ -50,7 +50,7 @@ func ConnectDB() { db: db, } - err = db.AutoMigrate(&models.Customer{}) + err = db.AutoMigrate(&models.Customer{}, &models.LgpdRemovalRequest{}) if err != nil { log.Panic("Erro ao fazer auto migrate") } From a0dcba3a65db3e898d04ff0a5e6120787ba5f40f Mon Sep 17 00:00:00 2001 From: Matheus <30qr4xnl@duck.com> Date: Tue, 3 Sep 2024 00:50:19 -0300 Subject: [PATCH 03/14] feature/lgpd-exclusion-api: criando repository --- .../lgpd_removal_request_repository.go | 7 ++++ .../lgpd_removal_request_repository.go | 35 +++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 src/adapters/gateways/lgpd_removal_request_repository.go create mode 100644 src/infra/db/repositories/lgpd_removal_request_repository.go diff --git a/src/adapters/gateways/lgpd_removal_request_repository.go b/src/adapters/gateways/lgpd_removal_request_repository.go new file mode 100644 index 0000000..60d8bd5 --- /dev/null +++ b/src/adapters/gateways/lgpd_removal_request_repository.go @@ -0,0 +1,7 @@ +package gateways + +import "github.com/CAVAh/api-tech-challenge/src/core/domain/entities" + +type LgpdRemovalRequestRepository interface { + Create(removalRequest *entities.LgpdRemovalRequest) (*entities.LgpdRemovalRequest, error) +} diff --git a/src/infra/db/repositories/lgpd_removal_request_repository.go b/src/infra/db/repositories/lgpd_removal_request_repository.go new file mode 100644 index 0000000..9c4fa34 --- /dev/null +++ b/src/infra/db/repositories/lgpd_removal_request_repository.go @@ -0,0 +1,35 @@ +package repositories + +import ( + "errors" + "github.com/CAVAh/api-tech-challenge/src/core/domain/entities" + "github.com/CAVAh/api-tech-challenge/src/infra/db/database" + "github.com/CAVAh/api-tech-challenge/src/infra/db/models" + "strings" +) + +type LgpdRemovalRequestRepository struct { + DB database.Database +} + +func (r LgpdRemovalRequestRepository) Create(removalRequest *entities.LgpdRemovalRequest) (*entities.LgpdRemovalRequest, error) { + + removalRequestModel := models.LgpdRemovalRequest{ + Name: removalRequest.Name, + Address: removalRequest.Address, + PhoneNumber: removalRequest.PhoneNumber, + PaymentHistory: removalRequest.PaymentHistory, + } + + if err := r.DB.Create(&removalRequestModel); err != nil { + if strings.Contains(err.Error(), "duplicate key value violates unique constraint") { + return nil, errors.New("cliente já existe no sistema") + } else { + return nil, errors.New("ocorreu um erro desconhecido ao criar o cliente") + } + } + + result := removalRequestModel.ToDomain() + + return &result, nil +} From c2082a6dc01109aa3755b54bf7c896f3e6a4f556 Mon Sep 17 00:00:00 2001 From: Matheus <30qr4xnl@duck.com> Date: Tue, 3 Sep 2024 00:50:54 -0300 Subject: [PATCH 04/14] feature/lgpd-exclusion-api: implementacao inicial usecase removal request --- .../customer/create_lgpd_removal_request.go | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 src/core/domain/usecases/customer/create_lgpd_removal_request.go diff --git a/src/core/domain/usecases/customer/create_lgpd_removal_request.go b/src/core/domain/usecases/customer/create_lgpd_removal_request.go new file mode 100644 index 0000000..1baf04b --- /dev/null +++ b/src/core/domain/usecases/customer/create_lgpd_removal_request.go @@ -0,0 +1,22 @@ +package usecases + +import ( + "github.com/CAVAh/api-tech-challenge/src/adapters/gateways" + "github.com/CAVAh/api-tech-challenge/src/core/domain/dtos" + "github.com/CAVAh/api-tech-challenge/src/core/domain/entities" +) + +type CreateLgpdRemovalRequestUsecase struct { + LgpdRemovalRequestRepository gateways.LgpdRemovalRequestRepository +} + +func (r *CreateLgpdRemovalRequestUsecase) Execute(inputDto dtos.LGPDRemovalRequestDto) (*entities.LgpdRemovalRequest, error) { + removalRequest := entities.LgpdRemovalRequest{ + Name: inputDto.Name, + Address: inputDto.Address, + PhoneNumber: inputDto.PhoneNumber, + PaymentHistory: inputDto.PaymentHistory, + } + + return r.LgpdRemovalRequestRepository.Create(&removalRequest) +} From ccf1ba04cd8acc1e03baa67410e0f10818fc81a0 Mon Sep 17 00:00:00 2001 From: Matheus <30qr4xnl@duck.com> Date: Tue, 3 Sep 2024 00:51:08 -0300 Subject: [PATCH 05/14] feature/lgpd-exclusion-api: implementacao inicial controller removal request --- .../customer/customer_controller.go | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/adapters/controllers/customer/customer_controller.go b/src/adapters/controllers/customer/customer_controller.go index 5a11517..6b902bf 100644 --- a/src/adapters/controllers/customer/customer_controller.go +++ b/src/adapters/controllers/customer/customer_controller.go @@ -61,3 +61,32 @@ func CreateCustomer(c *gin.Context, usecase *usecases.CreateCustomerUsecase) { c.JSON(http.StatusCreated, result) } + +func CreateLgpdRemovalRequestCustomer(c *gin.Context, usecase *usecases.CreateLgpdRemovalRequestUsecase) { + var inputDto dtos.LGPDRemovalRequestDto + + if err := c.ShouldBindJSON(&inputDto); err != nil { + c.JSON(http.StatusBadRequest, gin.H{ + "error": err.Error(), + }) + return + } + + if err := validator.Validate(inputDto); err != nil { + c.JSON(http.StatusBadRequest, gin.H{ + "error": err, + }) + return + } + + result, err := usecase.Execute(inputDto) + + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{ + "error": err.Error(), + }) + return + } + + c.JSON(http.StatusCreated, result) +} From f5ec858b1d276ca8940e1735f31157d1f252e712 Mon Sep 17 00:00:00 2001 From: Matheus <30qr4xnl@duck.com> Date: Tue, 3 Sep 2024 00:51:29 -0300 Subject: [PATCH 06/14] feature/lgpd-exclusion-api: adicionando nova rota para removal request --- src/infra/web/routes/routes.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/infra/web/routes/routes.go b/src/infra/web/routes/routes.go index 4590a7e..303345e 100644 --- a/src/infra/web/routes/routes.go +++ b/src/infra/web/routes/routes.go @@ -15,8 +15,14 @@ func HandleRequests() { customerRepository := &repositories.CustomerRepository{ DB: database.DB, } + + lgpdRemovalRequestRepository := &repositories.LgpdRemovalRequestRepository{ + DB: database.DB, + } + listUsecase := &usecases.ListCustomerUsecase{CustomerRepository: customerRepository} createUsecase := &usecases.CreateCustomerUsecase{CustomerRepository: customerRepository} + createLgpdRemovalRequest := &usecases.CreateLgpdRemovalRequestUsecase{LgpdRemovalRequestRepository: lgpdRemovalRequestRepository} router.GET("/customers", func(c *gin.Context) { controllers.ListCustomers(c, listUsecase) @@ -26,6 +32,10 @@ func HandleRequests() { controllers.CreateCustomer(c, createUsecase) }) + router.POST("/customers/lgpd-exclusion", func(c *gin.Context) { + controllers.CreateLgpdRemovalRequestCustomer(c, createLgpdRemovalRequest) + }) + err := router.Run() if err != nil { From 9fd4c2b0a279e2ec4d6b22076148c2a0a8a70f4b Mon Sep 17 00:00:00 2001 From: Matheus <30qr4xnl@duck.com> Date: Tue, 3 Sep 2024 20:45:51 -0300 Subject: [PATCH 07/14] feature/lgpd-exclusion-api: ajustando log error --- src/infra/db/repositories/lgpd_removal_request_repository.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/infra/db/repositories/lgpd_removal_request_repository.go b/src/infra/db/repositories/lgpd_removal_request_repository.go index 9c4fa34..afa89c0 100644 --- a/src/infra/db/repositories/lgpd_removal_request_repository.go +++ b/src/infra/db/repositories/lgpd_removal_request_repository.go @@ -23,9 +23,9 @@ func (r LgpdRemovalRequestRepository) Create(removalRequest *entities.LgpdRemova if err := r.DB.Create(&removalRequestModel); err != nil { if strings.Contains(err.Error(), "duplicate key value violates unique constraint") { - return nil, errors.New("cliente já existe no sistema") + return nil, errors.New("solicitação de exclusão já existe no sistema") } else { - return nil, errors.New("ocorreu um erro desconhecido ao criar o cliente") + return nil, errors.New("ocorreu um erro desconhecido ao criar a solicitação") } } From 0300748de7a8ec709b18360c23079667f4167a46 Mon Sep 17 00:00:00 2001 From: Matheus <30qr4xnl@duck.com> Date: Tue, 3 Sep 2024 23:46:18 -0300 Subject: [PATCH 08/14] feature/lgpd-exclusion-api: melhorando nome da rota --- src/infra/web/routes/routes.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/infra/web/routes/routes.go b/src/infra/web/routes/routes.go index 303345e..be64f52 100644 --- a/src/infra/web/routes/routes.go +++ b/src/infra/web/routes/routes.go @@ -32,7 +32,7 @@ func HandleRequests() { controllers.CreateCustomer(c, createUsecase) }) - router.POST("/customers/lgpd-exclusion", func(c *gin.Context) { + router.POST("/customers/lgpd-removal", func(c *gin.Context) { controllers.CreateLgpdRemovalRequestCustomer(c, createLgpdRemovalRequest) }) From 2a265235c5c4e9ced835bf0ab8e03774cdbe262d Mon Sep 17 00:00:00 2001 From: Matheus <30qr4xnl@duck.com> Date: Tue, 3 Sep 2024 23:46:47 -0300 Subject: [PATCH 09/14] feature/lgpd-exclusion-api: adicionando nova api doc openapi --- docs/tech-challenge.json | 85 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/docs/tech-challenge.json b/docs/tech-challenge.json index 9c7eb57..949b4db 100644 --- a/docs/tech-challenge.json +++ b/docs/tech-challenge.json @@ -157,6 +157,64 @@ } } } + }, + "/customers/lgpd-removal": { + "post": { + "tags": [ + "Cliente" + ], + "summary": "Cria solicitação de remoção dados LGPD", + "description": "Endpoint responsável que cria uma solicitação para remoção dados LGPD.", + "operationId": "create-lgpd-removal-request-customer", + "requestBody": { + "description": "Post the necessary fields for the API to create a new removal request.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Customer_lgpd_removal_request" + }, + "examples": { + "Criar uma solicitação": { + "value": { + "name": "Fulano de tal", + "address": "rua xpto 123, bairro xpto", + "phone_number": "54984565122", + "payment_history": true + } + } + } + } + } + }, + "responses": { + "201": { + "description": "Solicitação Criada", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Customer_lgpd_removal_request" + }, + "examples": { + "Criar uma solicitação": { + "value": { + "name": "Fulano de tal", + "address": "rua xpto 123, bairro xpto", + "phone_number": "54984565122", + "payment_history": true + } + } + } + } + } + }, + "400": { + + }, + "500": { + + } + } + } } }, "tags": [ @@ -290,6 +348,33 @@ "cpf", "email" ] + }, + "Customer_lgpd_removal_request": { + "type": "object", + "properties": { + "name": { + "type": "string", + "example": "Fulano de tal" + }, + "address": { + "type": "string", + "example": "rua xpto 123, bairro xpto" + }, + "phone_number": { + "type": "string", + "example": "54984565122" + }, + "payment_history": { + "type": "boolean", + "example": "true" + } + }, + "required": [ + "name", + "address", + "phone_number", + "payment_history" + ] } } } From 4d16cf4f9d9dc1cdc8fd3cad156b54e1576cbca6 Mon Sep 17 00:00:00 2001 From: Matheus <30qr4xnl@duck.com> Date: Tue, 3 Sep 2024 23:47:08 -0300 Subject: [PATCH 10/14] feature/lgpd-exclusion-api: ajustando validate tags dto --- src/core/domain/dtos/lgpd_removal_request_dto.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/domain/dtos/lgpd_removal_request_dto.go b/src/core/domain/dtos/lgpd_removal_request_dto.go index 694f3c4..96d4048 100644 --- a/src/core/domain/dtos/lgpd_removal_request_dto.go +++ b/src/core/domain/dtos/lgpd_removal_request_dto.go @@ -1,8 +1,8 @@ package dtos type LGPDRemovalRequestDto struct { - Name string `json:"name" validate:"required, regexp=^[a-zA-ZÀ-ÿ'’\- ]{1,255}$"` - Address string `json:"address" validate:"required, regexp=^[a-zA-ZÀ-ÿ'’\- ]{1,255}$"` - PhoneNumber string `json:"phone_number" validate:"required, regexp=^\+?(\d{1,3})?[-.\s]?(\(?\d{2}\)?)?[-.\s]?\d{4,5}[-.\s]?\d{4}$"` - PaymentHistory bool `json:"payment_history" validate:"required,oneof=true false"` + Name string `json:"name" validate:"nonzero,min=10,max=255"` + Address string `json:"address" validate:"nonzero,min=10,max=255"` + PhoneNumber string `json:"phone_number" validate:"len=11"` + PaymentHistory bool `json:"payment_history" validate:"nonnil"` } From 882aeb13d177ef6535b1af2fb1304847575681f2 Mon Sep 17 00:00:00 2001 From: Matheus <30qr4xnl@duck.com> Date: Tue, 3 Sep 2024 23:47:27 -0300 Subject: [PATCH 11/14] feature/lgpd-exclusion-api: retirando ssl postgress required --- src/infra/db/database/database.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/infra/db/database/database.go b/src/infra/db/database/database.go index 606cd3b..c256dea 100644 --- a/src/infra/db/database/database.go +++ b/src/infra/db/database/database.go @@ -38,7 +38,7 @@ func (rdb *RealDatabase) First(dest interface{}, conds ...interface{}) error { } func ConnectDB() { - conectionString := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=5432 sslmode=require TimeZone=America/Fortaleza", + conectionString := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=5432 sslmode=disable TimeZone=America/Fortaleza", os.Getenv("POSTGRES_HOST"), os.Getenv("POSTGRES_USER"), os.Getenv("POSTGRES_PASSWORD"), os.Getenv("POSTGRES_DB")) db, err := gorm.Open(postgres.Open(conectionString)) From 13ec581ae3c23ff276dd99093738aba8917a0652 Mon Sep 17 00:00:00 2001 From: Matheus <30qr4xnl@duck.com> Date: Tue, 3 Sep 2024 23:47:48 -0300 Subject: [PATCH 12/14] feature/lgpd-exclusion-api: adicionando logs errors validation e binding --- src/adapters/controllers/customer/customer_controller.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/adapters/controllers/customer/customer_controller.go b/src/adapters/controllers/customer/customer_controller.go index 6b902bf..3600afe 100644 --- a/src/adapters/controllers/customer/customer_controller.go +++ b/src/adapters/controllers/customer/customer_controller.go @@ -1,6 +1,7 @@ package controllers import ( + "fmt" "net/http" "github.com/CAVAh/api-tech-challenge/src/core/domain/dtos" @@ -69,6 +70,7 @@ func CreateLgpdRemovalRequestCustomer(c *gin.Context, usecase *usecases.CreateLg c.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) + fmt.Printf("error binding json: %v\n", err) return } @@ -76,6 +78,7 @@ func CreateLgpdRemovalRequestCustomer(c *gin.Context, usecase *usecases.CreateLg c.JSON(http.StatusBadRequest, gin.H{ "error": err, }) + fmt.Printf("error with validation json: %v\n", err) return } From 447a7f9e9a271f0eefd0550560e115e0a839c78f Mon Sep 17 00:00:00 2001 From: Lucas Cavagnolli Date: Mon, 9 Sep 2024 22:41:29 -0300 Subject: [PATCH 13/14] Update tech-challenge.json --- docs/tech-challenge.json | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/docs/tech-challenge.json b/docs/tech-challenge.json index 949b4db..4224423 100644 --- a/docs/tech-challenge.json +++ b/docs/tech-challenge.json @@ -208,10 +208,10 @@ } }, "400": { - + "description": "Erro de BadRequest" }, "500": { - + "description": "Erro de ServerError" } } } @@ -366,7 +366,7 @@ }, "payment_history": { "type": "boolean", - "example": "true" + "example": true } }, "required": [ @@ -375,6 +375,23 @@ "phone_number", "payment_history" ] + }, + "ErrorSchema": { + "title": "ErrorSchema", + "ErrorSchema": { + "type": "object", + "properties": { + "code": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "message": { + "type": "string" + } + } + } } } } From 20e811474a2b17684458eb1eb9a16a1a8d35e5f4 Mon Sep 17 00:00:00 2001 From: Matheus <30qr4xnl@duck.com> Date: Mon, 9 Sep 2024 22:44:45 -0300 Subject: [PATCH 14/14] feature/lgpd-exclusion-api: ajustes check da pipe --- src/adapters/controllers/customer/customer_controller.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/adapters/controllers/customer/customer_controller.go b/src/adapters/controllers/customer/customer_controller.go index 3600afe..370fabd 100644 --- a/src/adapters/controllers/customer/customer_controller.go +++ b/src/adapters/controllers/customer/customer_controller.go @@ -13,7 +13,14 @@ import ( func ListCustomers(c *gin.Context, usecase *usecases.ListCustomerUsecase) { var inputDto dtos.ListCustomerDto - c.BindQuery(&inputDto) + err := c.BindQuery(&inputDto) + + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{ + "error": err, + }) + return + } if err := validator.Validate(inputDto); err != nil { c.JSON(http.StatusBadRequest, gin.H{