Add auth docs, user CRUD, and password pepper
This commit is contained in:
parent
916225f19e
commit
4680035e02
8 changed files with 2282 additions and 26 deletions
|
|
@ -21,6 +21,9 @@ import (
|
|||
// @Schemes http
|
||||
// @contact.name Engenharia SaveInMed
|
||||
// @contact.email devops@saveinmed.com
|
||||
// @securityDefinitions.apikey BearerAuth
|
||||
// @in header
|
||||
// @name Authorization
|
||||
func main() {
|
||||
cfg := config.Load()
|
||||
|
||||
|
|
|
|||
|
|
@ -250,6 +250,532 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/auth/login": {
|
||||
"post": {
|
||||
"description": "Autentica usuário e retorna token JWT.",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Autenticação"
|
||||
],
|
||||
"summary": "Login",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Credenciais",
|
||||
"name": "payload",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handler.loginRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handler.authResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Unauthorized",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/auth/register": {
|
||||
"post": {
|
||||
"description": "Cria um usuário e opcionalmente uma empresa, retornando token JWT.",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Autenticação"
|
||||
],
|
||||
"summary": "Cadastro de usuário",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Dados do usuário e empresa",
|
||||
"name": "payload",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handler.registerAuthRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"201": {
|
||||
"description": "Created",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handler.authResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/payments/webhook": {
|
||||
"post": {
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Pagamentos"
|
||||
],
|
||||
"summary": "Recebe notificações do Mercado Pago",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Evento do gateway",
|
||||
"name": "notification",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.PaymentWebhookEvent"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.PaymentSplitResult"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/shipments": {
|
||||
"post": {
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Logistica"
|
||||
],
|
||||
"summary": "Gera guia de postagem/transporte",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Dados de envio",
|
||||
"name": "shipment",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handler.createShipmentRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"201": {
|
||||
"description": "Created",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.Shipment"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/shipments/{order_id}": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Logistica"
|
||||
],
|
||||
"summary": "Rastreia entrega",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Order ID",
|
||||
"name": "order_id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.Shipment"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/users": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Usuários"
|
||||
],
|
||||
"summary": "Listar usuários",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "Página",
|
||||
"name": "page",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "Tamanho da página",
|
||||
"name": "page_size",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Filtro por empresa",
|
||||
"name": "company_id",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.UserPage"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Usuários"
|
||||
],
|
||||
"summary": "Criar usuário",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Novo usuário",
|
||||
"name": "payload",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handler.createUserRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"201": {
|
||||
"description": "Created",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.User"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"403": {
|
||||
"description": "Forbidden",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/users/{id}": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Usuários"
|
||||
],
|
||||
"summary": "Obter usuário",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "User ID",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.User"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"403": {
|
||||
"description": "Forbidden",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Not Found",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"put": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Usuários"
|
||||
],
|
||||
"summary": "Atualizar usuário",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "User ID",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"description": "Campos para atualização",
|
||||
"name": "payload",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handler.updateUserRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.User"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"403": {
|
||||
"description": "Forbidden",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Not Found",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"Usuários"
|
||||
],
|
||||
"summary": "Excluir usuário",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "User ID",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"204": {
|
||||
"description": "No Content",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"403": {
|
||||
"description": "Forbidden",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Not Found",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
|
|
@ -268,11 +794,14 @@ const docTemplate = `{
|
|||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"role": {
|
||||
"description": "pharmacy, distributor, admin",
|
||||
"is_verified": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"license_number": {
|
||||
"type": "string"
|
||||
},
|
||||
"sanitary_license": {
|
||||
"role": {
|
||||
"description": "pharmacy, distributor, admin",
|
||||
"type": "string"
|
||||
},
|
||||
"updated_at": {
|
||||
|
|
@ -301,6 +830,9 @@ const docTemplate = `{
|
|||
"seller_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"shipping": {
|
||||
"$ref": "#/definitions/domain.ShippingAddress"
|
||||
},
|
||||
"status": {
|
||||
"$ref": "#/definitions/domain.OrderStatus"
|
||||
},
|
||||
|
|
@ -376,6 +908,52 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"domain.PaymentSplitResult": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"marketplace_fee": {
|
||||
"type": "integer"
|
||||
},
|
||||
"order_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"payment_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"seller_receivable": {
|
||||
"type": "integer"
|
||||
},
|
||||
"status": {
|
||||
"type": "string"
|
||||
},
|
||||
"total_paid_amount": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"domain.PaymentWebhookEvent": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"marketplace_fee": {
|
||||
"type": "integer"
|
||||
},
|
||||
"order_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"payment_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"seller_amount": {
|
||||
"type": "integer"
|
||||
},
|
||||
"status": {
|
||||
"type": "string"
|
||||
},
|
||||
"total_paid_amount": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"domain.Product": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
@ -411,6 +989,124 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"domain.Shipment": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"carrier": {
|
||||
"type": "string"
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"external_tracking": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"order_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"status": {
|
||||
"type": "string"
|
||||
},
|
||||
"tracking_code": {
|
||||
"type": "string"
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"domain.ShippingAddress": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"city": {
|
||||
"type": "string"
|
||||
},
|
||||
"complement": {
|
||||
"type": "string"
|
||||
},
|
||||
"country": {
|
||||
"type": "string"
|
||||
},
|
||||
"district": {
|
||||
"type": "string"
|
||||
},
|
||||
"number": {
|
||||
"type": "string"
|
||||
},
|
||||
"recipient_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"state": {
|
||||
"type": "string"
|
||||
},
|
||||
"street": {
|
||||
"type": "string"
|
||||
},
|
||||
"zip_code": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"domain.User": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"company_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"email": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"role": {
|
||||
"type": "string"
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"domain.UserPage": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"page": {
|
||||
"type": "integer"
|
||||
},
|
||||
"page_size": {
|
||||
"type": "integer"
|
||||
},
|
||||
"total": {
|
||||
"type": "integer"
|
||||
},
|
||||
"users": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/domain.User"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"handler.authResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"expires_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"token": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"handler.createOrderRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
@ -425,6 +1121,80 @@ const docTemplate = `{
|
|||
},
|
||||
"seller_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"shipping": {
|
||||
"$ref": "#/definitions/domain.ShippingAddress"
|
||||
}
|
||||
}
|
||||
},
|
||||
"handler.createShipmentRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"carrier": {
|
||||
"type": "string"
|
||||
},
|
||||
"external_tracking": {
|
||||
"type": "string"
|
||||
},
|
||||
"order_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"tracking_code": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"handler.createUserRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"company_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"email": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"password": {
|
||||
"type": "string"
|
||||
},
|
||||
"role": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"handler.loginRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"email": {
|
||||
"type": "string"
|
||||
},
|
||||
"password": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"handler.registerAuthRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"company": {
|
||||
"$ref": "#/definitions/handler.registerCompanyTarget"
|
||||
},
|
||||
"company_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"email": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"password": {
|
||||
"type": "string"
|
||||
},
|
||||
"role": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -437,10 +1207,30 @@ const docTemplate = `{
|
|||
"corporate_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"role": {
|
||||
"license_number": {
|
||||
"type": "string"
|
||||
},
|
||||
"sanitary_license": {
|
||||
"role": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"handler.registerCompanyTarget": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"cnpj": {
|
||||
"type": "string"
|
||||
},
|
||||
"corporate_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"license_number": {
|
||||
"type": "string"
|
||||
},
|
||||
"role": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
|
|
@ -478,6 +1268,33 @@ const docTemplate = `{
|
|||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"handler.updateUserRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"company_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"email": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"password": {
|
||||
"type": "string"
|
||||
},
|
||||
"role": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"securityDefinitions": {
|
||||
"BearerAuth": {
|
||||
"type": "apiKey",
|
||||
"name": "Authorization",
|
||||
"in": "header"
|
||||
}
|
||||
}
|
||||
}`
|
||||
|
|
|
|||
|
|
@ -246,6 +246,532 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/auth/login": {
|
||||
"post": {
|
||||
"description": "Autentica usuário e retorna token JWT.",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Autenticação"
|
||||
],
|
||||
"summary": "Login",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Credenciais",
|
||||
"name": "payload",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handler.loginRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handler.authResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Unauthorized",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/auth/register": {
|
||||
"post": {
|
||||
"description": "Cria um usuário e opcionalmente uma empresa, retornando token JWT.",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Autenticação"
|
||||
],
|
||||
"summary": "Cadastro de usuário",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Dados do usuário e empresa",
|
||||
"name": "payload",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handler.registerAuthRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"201": {
|
||||
"description": "Created",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handler.authResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/payments/webhook": {
|
||||
"post": {
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Pagamentos"
|
||||
],
|
||||
"summary": "Recebe notificações do Mercado Pago",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Evento do gateway",
|
||||
"name": "notification",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.PaymentWebhookEvent"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.PaymentSplitResult"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/shipments": {
|
||||
"post": {
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Logistica"
|
||||
],
|
||||
"summary": "Gera guia de postagem/transporte",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Dados de envio",
|
||||
"name": "shipment",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handler.createShipmentRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"201": {
|
||||
"description": "Created",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.Shipment"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/shipments/{order_id}": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Logistica"
|
||||
],
|
||||
"summary": "Rastreia entrega",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Order ID",
|
||||
"name": "order_id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.Shipment"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/users": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Usuários"
|
||||
],
|
||||
"summary": "Listar usuários",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "Página",
|
||||
"name": "page",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "Tamanho da página",
|
||||
"name": "page_size",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Filtro por empresa",
|
||||
"name": "company_id",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.UserPage"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Usuários"
|
||||
],
|
||||
"summary": "Criar usuário",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Novo usuário",
|
||||
"name": "payload",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handler.createUserRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"201": {
|
||||
"description": "Created",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.User"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"403": {
|
||||
"description": "Forbidden",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/users/{id}": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Usuários"
|
||||
],
|
||||
"summary": "Obter usuário",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "User ID",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.User"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"403": {
|
||||
"description": "Forbidden",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Not Found",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"put": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Usuários"
|
||||
],
|
||||
"summary": "Atualizar usuário",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "User ID",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"description": "Campos para atualização",
|
||||
"name": "payload",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handler.updateUserRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.User"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"403": {
|
||||
"description": "Forbidden",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Not Found",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"Usuários"
|
||||
],
|
||||
"summary": "Excluir usuário",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "User ID",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"204": {
|
||||
"description": "No Content",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"403": {
|
||||
"description": "Forbidden",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Not Found",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
|
|
@ -264,11 +790,14 @@
|
|||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"role": {
|
||||
"description": "pharmacy, distributor, admin",
|
||||
"is_verified": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"license_number": {
|
||||
"type": "string"
|
||||
},
|
||||
"sanitary_license": {
|
||||
"role": {
|
||||
"description": "pharmacy, distributor, admin",
|
||||
"type": "string"
|
||||
},
|
||||
"updated_at": {
|
||||
|
|
@ -297,6 +826,9 @@
|
|||
"seller_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"shipping": {
|
||||
"$ref": "#/definitions/domain.ShippingAddress"
|
||||
},
|
||||
"status": {
|
||||
"$ref": "#/definitions/domain.OrderStatus"
|
||||
},
|
||||
|
|
@ -372,6 +904,52 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"domain.PaymentSplitResult": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"marketplace_fee": {
|
||||
"type": "integer"
|
||||
},
|
||||
"order_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"payment_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"seller_receivable": {
|
||||
"type": "integer"
|
||||
},
|
||||
"status": {
|
||||
"type": "string"
|
||||
},
|
||||
"total_paid_amount": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"domain.PaymentWebhookEvent": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"marketplace_fee": {
|
||||
"type": "integer"
|
||||
},
|
||||
"order_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"payment_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"seller_amount": {
|
||||
"type": "integer"
|
||||
},
|
||||
"status": {
|
||||
"type": "string"
|
||||
},
|
||||
"total_paid_amount": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"domain.Product": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
@ -407,6 +985,124 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"domain.Shipment": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"carrier": {
|
||||
"type": "string"
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"external_tracking": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"order_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"status": {
|
||||
"type": "string"
|
||||
},
|
||||
"tracking_code": {
|
||||
"type": "string"
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"domain.ShippingAddress": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"city": {
|
||||
"type": "string"
|
||||
},
|
||||
"complement": {
|
||||
"type": "string"
|
||||
},
|
||||
"country": {
|
||||
"type": "string"
|
||||
},
|
||||
"district": {
|
||||
"type": "string"
|
||||
},
|
||||
"number": {
|
||||
"type": "string"
|
||||
},
|
||||
"recipient_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"state": {
|
||||
"type": "string"
|
||||
},
|
||||
"street": {
|
||||
"type": "string"
|
||||
},
|
||||
"zip_code": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"domain.User": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"company_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"email": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"role": {
|
||||
"type": "string"
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"domain.UserPage": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"page": {
|
||||
"type": "integer"
|
||||
},
|
||||
"page_size": {
|
||||
"type": "integer"
|
||||
},
|
||||
"total": {
|
||||
"type": "integer"
|
||||
},
|
||||
"users": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/domain.User"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"handler.authResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"expires_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"token": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"handler.createOrderRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
@ -421,6 +1117,80 @@
|
|||
},
|
||||
"seller_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"shipping": {
|
||||
"$ref": "#/definitions/domain.ShippingAddress"
|
||||
}
|
||||
}
|
||||
},
|
||||
"handler.createShipmentRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"carrier": {
|
||||
"type": "string"
|
||||
},
|
||||
"external_tracking": {
|
||||
"type": "string"
|
||||
},
|
||||
"order_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"tracking_code": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"handler.createUserRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"company_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"email": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"password": {
|
||||
"type": "string"
|
||||
},
|
||||
"role": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"handler.loginRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"email": {
|
||||
"type": "string"
|
||||
},
|
||||
"password": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"handler.registerAuthRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"company": {
|
||||
"$ref": "#/definitions/handler.registerCompanyTarget"
|
||||
},
|
||||
"company_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"email": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"password": {
|
||||
"type": "string"
|
||||
},
|
||||
"role": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -433,10 +1203,30 @@
|
|||
"corporate_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"role": {
|
||||
"license_number": {
|
||||
"type": "string"
|
||||
},
|
||||
"sanitary_license": {
|
||||
"role": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"handler.registerCompanyTarget": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"cnpj": {
|
||||
"type": "string"
|
||||
},
|
||||
"corporate_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"license_number": {
|
||||
"type": "string"
|
||||
},
|
||||
"role": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
|
|
@ -474,6 +1264,33 @@
|
|||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"handler.updateUserRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"company_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"email": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"password": {
|
||||
"type": "string"
|
||||
},
|
||||
"role": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"securityDefinitions": {
|
||||
"BearerAuth": {
|
||||
"type": "apiKey",
|
||||
"name": "Authorization",
|
||||
"in": "header"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -10,11 +10,13 @@ definitions:
|
|||
type: string
|
||||
id:
|
||||
type: string
|
||||
is_verified:
|
||||
type: boolean
|
||||
license_number:
|
||||
type: string
|
||||
role:
|
||||
description: pharmacy, distributor, admin
|
||||
type: string
|
||||
sanitary_license:
|
||||
type: string
|
||||
updated_at:
|
||||
type: string
|
||||
type: object
|
||||
|
|
@ -32,6 +34,8 @@ definitions:
|
|||
type: array
|
||||
seller_id:
|
||||
type: string
|
||||
shipping:
|
||||
$ref: '#/definitions/domain.ShippingAddress'
|
||||
status:
|
||||
$ref: '#/definitions/domain.OrderStatus'
|
||||
total_cents:
|
||||
|
|
@ -83,6 +87,36 @@ definitions:
|
|||
seller_receivable:
|
||||
type: integer
|
||||
type: object
|
||||
domain.PaymentSplitResult:
|
||||
properties:
|
||||
marketplace_fee:
|
||||
type: integer
|
||||
order_id:
|
||||
type: string
|
||||
payment_id:
|
||||
type: string
|
||||
seller_receivable:
|
||||
type: integer
|
||||
status:
|
||||
type: string
|
||||
total_paid_amount:
|
||||
type: integer
|
||||
type: object
|
||||
domain.PaymentWebhookEvent:
|
||||
properties:
|
||||
marketplace_fee:
|
||||
type: integer
|
||||
order_id:
|
||||
type: string
|
||||
payment_id:
|
||||
type: string
|
||||
seller_amount:
|
||||
type: integer
|
||||
status:
|
||||
type: string
|
||||
total_paid_amount:
|
||||
type: integer
|
||||
type: object
|
||||
domain.Product:
|
||||
properties:
|
||||
batch:
|
||||
|
|
@ -106,6 +140,83 @@ definitions:
|
|||
updated_at:
|
||||
type: string
|
||||
type: object
|
||||
domain.Shipment:
|
||||
properties:
|
||||
carrier:
|
||||
type: string
|
||||
created_at:
|
||||
type: string
|
||||
external_tracking:
|
||||
type: string
|
||||
id:
|
||||
type: string
|
||||
order_id:
|
||||
type: string
|
||||
status:
|
||||
type: string
|
||||
tracking_code:
|
||||
type: string
|
||||
updated_at:
|
||||
type: string
|
||||
type: object
|
||||
domain.ShippingAddress:
|
||||
properties:
|
||||
city:
|
||||
type: string
|
||||
complement:
|
||||
type: string
|
||||
country:
|
||||
type: string
|
||||
district:
|
||||
type: string
|
||||
number:
|
||||
type: string
|
||||
recipient_name:
|
||||
type: string
|
||||
state:
|
||||
type: string
|
||||
street:
|
||||
type: string
|
||||
zip_code:
|
||||
type: string
|
||||
type: object
|
||||
domain.User:
|
||||
properties:
|
||||
company_id:
|
||||
type: string
|
||||
created_at:
|
||||
type: string
|
||||
email:
|
||||
type: string
|
||||
id:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
role:
|
||||
type: string
|
||||
updated_at:
|
||||
type: string
|
||||
type: object
|
||||
domain.UserPage:
|
||||
properties:
|
||||
page:
|
||||
type: integer
|
||||
page_size:
|
||||
type: integer
|
||||
total:
|
||||
type: integer
|
||||
users:
|
||||
items:
|
||||
$ref: '#/definitions/domain.User'
|
||||
type: array
|
||||
type: object
|
||||
handler.authResponse:
|
||||
properties:
|
||||
expires_at:
|
||||
type: string
|
||||
token:
|
||||
type: string
|
||||
type: object
|
||||
handler.createOrderRequest:
|
||||
properties:
|
||||
buyer_id:
|
||||
|
|
@ -116,6 +227,54 @@ definitions:
|
|||
type: array
|
||||
seller_id:
|
||||
type: string
|
||||
shipping:
|
||||
$ref: '#/definitions/domain.ShippingAddress'
|
||||
type: object
|
||||
handler.createShipmentRequest:
|
||||
properties:
|
||||
carrier:
|
||||
type: string
|
||||
external_tracking:
|
||||
type: string
|
||||
order_id:
|
||||
type: string
|
||||
tracking_code:
|
||||
type: string
|
||||
type: object
|
||||
handler.createUserRequest:
|
||||
properties:
|
||||
company_id:
|
||||
type: string
|
||||
email:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
password:
|
||||
type: string
|
||||
role:
|
||||
type: string
|
||||
type: object
|
||||
handler.loginRequest:
|
||||
properties:
|
||||
email:
|
||||
type: string
|
||||
password:
|
||||
type: string
|
||||
type: object
|
||||
handler.registerAuthRequest:
|
||||
properties:
|
||||
company:
|
||||
$ref: '#/definitions/handler.registerCompanyTarget'
|
||||
company_id:
|
||||
type: string
|
||||
email:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
password:
|
||||
type: string
|
||||
role:
|
||||
type: string
|
||||
type: object
|
||||
handler.registerCompanyRequest:
|
||||
properties:
|
||||
|
|
@ -123,9 +282,22 @@ definitions:
|
|||
type: string
|
||||
corporate_name:
|
||||
type: string
|
||||
license_number:
|
||||
type: string
|
||||
role:
|
||||
type: string
|
||||
sanitary_license:
|
||||
type: object
|
||||
handler.registerCompanyTarget:
|
||||
properties:
|
||||
cnpj:
|
||||
type: string
|
||||
corporate_name:
|
||||
type: string
|
||||
id:
|
||||
type: string
|
||||
license_number:
|
||||
type: string
|
||||
role:
|
||||
type: string
|
||||
type: object
|
||||
handler.registerProductRequest:
|
||||
|
|
@ -150,6 +322,19 @@ definitions:
|
|||
status:
|
||||
type: string
|
||||
type: object
|
||||
handler.updateUserRequest:
|
||||
properties:
|
||||
company_id:
|
||||
type: string
|
||||
email:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
password:
|
||||
type: string
|
||||
role:
|
||||
type: string
|
||||
type: object
|
||||
info:
|
||||
contact:
|
||||
email: devops@saveinmed.com
|
||||
|
|
@ -310,6 +495,348 @@ paths:
|
|||
summary: Cadastro de produto com rastreabilidade de lote
|
||||
tags:
|
||||
- Produtos
|
||||
/api/v1/auth/login:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: Autentica usuário e retorna token JWT.
|
||||
parameters:
|
||||
- description: Credenciais
|
||||
in: body
|
||||
name: payload
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/handler.loginRequest'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/handler.authResponse'
|
||||
"400":
|
||||
description: Bad Request
|
||||
schema:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
"401":
|
||||
description: Unauthorized
|
||||
schema:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
summary: Login
|
||||
tags:
|
||||
- Autenticação
|
||||
/api/v1/auth/register:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: Cria um usuário e opcionalmente uma empresa, retornando token JWT.
|
||||
parameters:
|
||||
- description: Dados do usuário e empresa
|
||||
in: body
|
||||
name: payload
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/handler.registerAuthRequest'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"201":
|
||||
description: Created
|
||||
schema:
|
||||
$ref: '#/definitions/handler.authResponse'
|
||||
"400":
|
||||
description: Bad Request
|
||||
schema:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
summary: Cadastro de usuário
|
||||
tags:
|
||||
- Autenticação
|
||||
/api/v1/payments/webhook:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
parameters:
|
||||
- description: Evento do gateway
|
||||
in: body
|
||||
name: notification
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/domain.PaymentWebhookEvent'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/domain.PaymentSplitResult'
|
||||
summary: Recebe notificações do Mercado Pago
|
||||
tags:
|
||||
- Pagamentos
|
||||
/api/v1/shipments:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
parameters:
|
||||
- description: Dados de envio
|
||||
in: body
|
||||
name: shipment
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/handler.createShipmentRequest'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"201":
|
||||
description: Created
|
||||
schema:
|
||||
$ref: '#/definitions/domain.Shipment'
|
||||
summary: Gera guia de postagem/transporte
|
||||
tags:
|
||||
- Logistica
|
||||
/api/v1/shipments/{order_id}:
|
||||
get:
|
||||
parameters:
|
||||
- description: Order ID
|
||||
in: path
|
||||
name: order_id
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/domain.Shipment'
|
||||
summary: Rastreia entrega
|
||||
tags:
|
||||
- Logistica
|
||||
/api/v1/users:
|
||||
get:
|
||||
parameters:
|
||||
- description: Página
|
||||
in: query
|
||||
name: page
|
||||
type: integer
|
||||
- description: Tamanho da página
|
||||
in: query
|
||||
name: page_size
|
||||
type: integer
|
||||
- description: Filtro por empresa
|
||||
in: query
|
||||
name: company_id
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/domain.UserPage'
|
||||
"400":
|
||||
description: Bad Request
|
||||
schema:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
security:
|
||||
- BearerAuth: []
|
||||
summary: Listar usuários
|
||||
tags:
|
||||
- Usuários
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
parameters:
|
||||
- description: Novo usuário
|
||||
in: body
|
||||
name: payload
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/handler.createUserRequest'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"201":
|
||||
description: Created
|
||||
schema:
|
||||
$ref: '#/definitions/domain.User'
|
||||
"400":
|
||||
description: Bad Request
|
||||
schema:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
"403":
|
||||
description: Forbidden
|
||||
schema:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
security:
|
||||
- BearerAuth: []
|
||||
summary: Criar usuário
|
||||
tags:
|
||||
- Usuários
|
||||
/api/v1/users/{id}:
|
||||
delete:
|
||||
parameters:
|
||||
- description: User ID
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
type: string
|
||||
responses:
|
||||
"204":
|
||||
description: No Content
|
||||
schema:
|
||||
type: string
|
||||
"400":
|
||||
description: Bad Request
|
||||
schema:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
"403":
|
||||
description: Forbidden
|
||||
schema:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
"404":
|
||||
description: Not Found
|
||||
schema:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
security:
|
||||
- BearerAuth: []
|
||||
summary: Excluir usuário
|
||||
tags:
|
||||
- Usuários
|
||||
get:
|
||||
parameters:
|
||||
- description: User ID
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/domain.User'
|
||||
"400":
|
||||
description: Bad Request
|
||||
schema:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
"403":
|
||||
description: Forbidden
|
||||
schema:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
"404":
|
||||
description: Not Found
|
||||
schema:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
security:
|
||||
- BearerAuth: []
|
||||
summary: Obter usuário
|
||||
tags:
|
||||
- Usuários
|
||||
put:
|
||||
consumes:
|
||||
- application/json
|
||||
parameters:
|
||||
- description: User ID
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
type: string
|
||||
- description: Campos para atualização
|
||||
in: body
|
||||
name: payload
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/handler.updateUserRequest'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/domain.User'
|
||||
"400":
|
||||
description: Bad Request
|
||||
schema:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
"403":
|
||||
description: Forbidden
|
||||
schema:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
"404":
|
||||
description: Not Found
|
||||
schema:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
security:
|
||||
- BearerAuth: []
|
||||
summary: Atualizar usuário
|
||||
tags:
|
||||
- Usuários
|
||||
schemes:
|
||||
- http
|
||||
securityDefinitions:
|
||||
BearerAuth:
|
||||
in: header
|
||||
name: Authorization
|
||||
type: apiKey
|
||||
swagger: "2.0"
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ type Config struct {
|
|||
MarketplaceCommission float64
|
||||
JWTSecret string
|
||||
JWTExpiresIn time.Duration
|
||||
PasswordPepper string
|
||||
CORSOrigins []string
|
||||
}
|
||||
|
||||
|
|
@ -37,6 +38,7 @@ func Load() Config {
|
|||
MarketplaceCommission: getEnvFloat("MARKETPLACE_COMMISSION", 2.5),
|
||||
JWTSecret: getEnv("JWT_SECRET", "dev-secret"),
|
||||
JWTExpiresIn: getEnvDuration("JWT_EXPIRES_IN", 24*time.Hour),
|
||||
PasswordPepper: getEnv("PASSWORD_PEPPER", ""),
|
||||
CORSOrigins: getEnvStringSlice("CORS_ORIGINS", []string{"*"}),
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,17 @@ func New(svc *usecase.Service) *Handler {
|
|||
return &Handler{svc: svc}
|
||||
}
|
||||
|
||||
// Register handles sign-up creating a company when requested.
|
||||
// Register godoc
|
||||
// @Summary Cadastro de usuário
|
||||
// @Description Cria um usuário e opcionalmente uma empresa, retornando token JWT.
|
||||
// @Tags Autenticação
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param payload body registerAuthRequest true "Dados do usuário e empresa"
|
||||
// @Success 201 {object} authResponse
|
||||
// @Failure 400 {object} map[string]string
|
||||
// @Failure 500 {object} map[string]string
|
||||
// @Router /api/v1/auth/register [post]
|
||||
func (h *Handler) Register(w http.ResponseWriter, r *http.Request) {
|
||||
var req registerAuthRequest
|
||||
if err := decodeJSON(r.Context(), r, &req); err != nil {
|
||||
|
|
@ -77,7 +87,17 @@ func (h *Handler) Register(w http.ResponseWriter, r *http.Request) {
|
|||
writeJSON(w, http.StatusCreated, authResponse{Token: token, ExpiresAt: exp})
|
||||
}
|
||||
|
||||
// Login validates credentials and emits a JWT token.
|
||||
// Login godoc
|
||||
// @Summary Login
|
||||
// @Description Autentica usuário e retorna token JWT.
|
||||
// @Tags Autenticação
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param payload body loginRequest true "Credenciais"
|
||||
// @Success 200 {object} authResponse
|
||||
// @Failure 400 {object} map[string]string
|
||||
// @Failure 401 {object} map[string]string
|
||||
// @Router /api/v1/auth/login [post]
|
||||
func (h *Handler) Login(w http.ResponseWriter, r *http.Request) {
|
||||
var req loginRequest
|
||||
if err := decodeJSON(r.Context(), r, &req); err != nil {
|
||||
|
|
@ -636,7 +656,18 @@ func (h *Handler) GetAdminDashboard(w http.ResponseWriter, r *http.Request) {
|
|||
writeJSON(w, http.StatusOK, dashboard)
|
||||
}
|
||||
|
||||
// CreateUser handles the creation of platform users.
|
||||
// CreateUser godoc
|
||||
// @Summary Criar usuário
|
||||
// @Tags Usuários
|
||||
// @Security BearerAuth
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param payload body createUserRequest true "Novo usuário"
|
||||
// @Success 201 {object} domain.User
|
||||
// @Failure 400 {object} map[string]string
|
||||
// @Failure 403 {object} map[string]string
|
||||
// @Failure 500 {object} map[string]string
|
||||
// @Router /api/v1/users [post]
|
||||
func (h *Handler) CreateUser(w http.ResponseWriter, r *http.Request) {
|
||||
requester, err := getRequester(r)
|
||||
if err != nil {
|
||||
|
|
@ -676,7 +707,18 @@ func (h *Handler) CreateUser(w http.ResponseWriter, r *http.Request) {
|
|||
writeJSON(w, http.StatusCreated, user)
|
||||
}
|
||||
|
||||
// ListUsers supports pagination and optional company filter.
|
||||
// ListUsers godoc
|
||||
// @Summary Listar usuários
|
||||
// @Tags Usuários
|
||||
// @Security BearerAuth
|
||||
// @Produce json
|
||||
// @Param page query int false "Página"
|
||||
// @Param page_size query int false "Tamanho da página"
|
||||
// @Param company_id query string false "Filtro por empresa"
|
||||
// @Success 200 {object} domain.UserPage
|
||||
// @Failure 400 {object} map[string]string
|
||||
// @Failure 500 {object} map[string]string
|
||||
// @Router /api/v1/users [get]
|
||||
func (h *Handler) ListUsers(w http.ResponseWriter, r *http.Request) {
|
||||
requester, err := getRequester(r)
|
||||
if err != nil {
|
||||
|
|
@ -713,7 +755,17 @@ func (h *Handler) ListUsers(w http.ResponseWriter, r *http.Request) {
|
|||
writeJSON(w, http.StatusOK, pageResult)
|
||||
}
|
||||
|
||||
// GetUser returns a single user by ID.
|
||||
// GetUser godoc
|
||||
// @Summary Obter usuário
|
||||
// @Tags Usuários
|
||||
// @Security BearerAuth
|
||||
// @Produce json
|
||||
// @Param id path string true "User ID"
|
||||
// @Success 200 {object} domain.User
|
||||
// @Failure 400 {object} map[string]string
|
||||
// @Failure 403 {object} map[string]string
|
||||
// @Failure 404 {object} map[string]string
|
||||
// @Router /api/v1/users/{id} [get]
|
||||
func (h *Handler) GetUser(w http.ResponseWriter, r *http.Request) {
|
||||
requester, err := getRequester(r)
|
||||
if err != nil {
|
||||
|
|
@ -743,7 +795,20 @@ func (h *Handler) GetUser(w http.ResponseWriter, r *http.Request) {
|
|||
writeJSON(w, http.StatusOK, user)
|
||||
}
|
||||
|
||||
// UpdateUser updates profile fields or password.
|
||||
// UpdateUser godoc
|
||||
// @Summary Atualizar usuário
|
||||
// @Tags Usuários
|
||||
// @Security BearerAuth
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "User ID"
|
||||
// @Param payload body updateUserRequest true "Campos para atualização"
|
||||
// @Success 200 {object} domain.User
|
||||
// @Failure 400 {object} map[string]string
|
||||
// @Failure 403 {object} map[string]string
|
||||
// @Failure 404 {object} map[string]string
|
||||
// @Failure 500 {object} map[string]string
|
||||
// @Router /api/v1/users/{id} [put]
|
||||
func (h *Handler) UpdateUser(w http.ResponseWriter, r *http.Request) {
|
||||
requester, err := getRequester(r)
|
||||
if err != nil {
|
||||
|
|
@ -802,7 +867,17 @@ func (h *Handler) UpdateUser(w http.ResponseWriter, r *http.Request) {
|
|||
writeJSON(w, http.StatusOK, user)
|
||||
}
|
||||
|
||||
// DeleteUser removes a user by ID.
|
||||
// DeleteUser godoc
|
||||
// @Summary Excluir usuário
|
||||
// @Tags Usuários
|
||||
// @Security BearerAuth
|
||||
// @Param id path string true "User ID"
|
||||
// @Success 204 {string} string "No Content"
|
||||
// @Failure 400 {object} map[string]string
|
||||
// @Failure 403 {object} map[string]string
|
||||
// @Failure 404 {object} map[string]string
|
||||
// @Failure 500 {object} map[string]string
|
||||
// @Router /api/v1/users/{id} [delete]
|
||||
func (h *Handler) DeleteUser(w http.ResponseWriter, r *http.Request) {
|
||||
requester, err := getRequester(r)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ func New(cfg config.Config) (*Server, error) {
|
|||
|
||||
repo := postgres.New(db)
|
||||
gateway := payments.NewMercadoPagoGateway(cfg.MercadoPagoBaseURL, cfg.MarketplaceCommission)
|
||||
svc := usecase.NewService(repo, gateway, cfg.MarketplaceCommission, cfg.JWTSecret, cfg.JWTExpiresIn)
|
||||
svc := usecase.NewService(repo, gateway, cfg.MarketplaceCommission, cfg.JWTSecret, cfg.JWTExpiresIn, cfg.PasswordPepper)
|
||||
h := handler.New(svc)
|
||||
|
||||
mux := http.NewServeMux()
|
||||
|
|
|
|||
|
|
@ -61,11 +61,19 @@ type Service struct {
|
|||
jwtSecret []byte
|
||||
tokenTTL time.Duration
|
||||
marketplaceCommission float64
|
||||
passwordPepper string
|
||||
}
|
||||
|
||||
// NewService wires use cases together.
|
||||
func NewService(repo Repository, pay PaymentGateway, commissionPct float64, jwtSecret string, tokenTTL time.Duration) *Service {
|
||||
return &Service{repo: repo, pay: pay, jwtSecret: []byte(jwtSecret), tokenTTL: tokenTTL, marketplaceCommission: commissionPct}
|
||||
func NewService(repo Repository, pay PaymentGateway, commissionPct float64, jwtSecret string, tokenTTL time.Duration, passwordPepper string) *Service {
|
||||
return &Service{
|
||||
repo: repo,
|
||||
pay: pay,
|
||||
jwtSecret: []byte(jwtSecret),
|
||||
tokenTTL: tokenTTL,
|
||||
marketplaceCommission: commissionPct,
|
||||
passwordPepper: passwordPepper,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) RegisterCompany(ctx context.Context, company *domain.Company) error {
|
||||
|
|
@ -171,7 +179,7 @@ func (s *Service) HandlePaymentWebhook(ctx context.Context, event domain.Payment
|
|||
}
|
||||
|
||||
func (s *Service) CreateUser(ctx context.Context, user *domain.User, password string) error {
|
||||
hashed, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||||
hashed, err := bcrypt.GenerateFromPassword([]byte(s.pepperPassword(password)), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -207,7 +215,7 @@ func (s *Service) GetUser(ctx context.Context, id uuid.UUID) (*domain.User, erro
|
|||
|
||||
func (s *Service) UpdateUser(ctx context.Context, user *domain.User, newPassword string) error {
|
||||
if newPassword != "" {
|
||||
hashed, err := bcrypt.GenerateFromPassword([]byte(newPassword), bcrypt.DefaultCost)
|
||||
hashed, err := bcrypt.GenerateFromPassword([]byte(s.pepperPassword(newPassword)), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -378,7 +386,7 @@ func (s *Service) Authenticate(ctx context.Context, email, password string) (str
|
|||
return "", time.Time{}, err
|
||||
}
|
||||
|
||||
if err := bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(password)); err != nil {
|
||||
if err := bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(s.pepperPassword(password))); err != nil {
|
||||
return "", time.Time{}, errors.New("invalid credentials")
|
||||
}
|
||||
|
||||
|
|
@ -399,6 +407,13 @@ func (s *Service) Authenticate(ctx context.Context, email, password string) (str
|
|||
return signed, expiresAt, nil
|
||||
}
|
||||
|
||||
func (s *Service) pepperPassword(password string) string {
|
||||
if s.passwordPepper == "" {
|
||||
return password
|
||||
}
|
||||
return password + s.passwordPepper
|
||||
}
|
||||
|
||||
// VerifyCompany marks a company as verified.
|
||||
func (s *Service) VerifyCompany(ctx context.Context, id uuid.UUID) (*domain.Company, error) {
|
||||
company, err := s.repo.GetCompany(ctx, id)
|
||||
|
|
|
|||
Loading…
Reference in a new issue