Skip to content

gabrielgpavao/kimoveis-api-node

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

46 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Documentação da API

Sumário


1. Visão Geral

Aplicação Backend (API) criada para gerenciar os dados de uma imobiliária. É possível cadastrar novos clientes, cadastrar novos imóveis, associá-los a um endereço e categoria, bem como agendar uma visita do cliente para o imóvel.

Principais tecnologias utilizadas:


2. Diagrama de Entidade Relacionamento

Voltar para o topo

Relações entre as tabelas do banco de dados.

DER


3. Início Rápido

Voltar para o topo

3.1. Instalando Dependências

Clone o projeto em sua máquina e instale as dependências com o comando:

Caso use npm

npm install

Caso use yarn

yarn

3.2. Variáveis de Ambiente

Em seguida, crie um arquivo .env, copiando o formato do arquivo .env.example:

cp .env.example .env

Configure suas variáveis de ambiente com suas credenciais do PostgreSQL e um novo Banco de Dados da sua escolha.

3.3. Migrations

Execute as migrations com o comando:

Caso use npm

npm run typeorm migration:run -d src/data-source.ts

Caso use yarn

yarn typeorm migration:run -d src/data-source.ts

4. Endpoints

Voltar para o topo

Índice


4.1. Login

Voltar para os Endpoints

/login

Exemplo de Request:

POST /login
Host: http://localhost:3000/
Authorization: None
Content-type: application/json

Corpo da Requisição:

{
	"email": "gabriel@mail.com",
	"password": "1234"
}

Schema de Validação com Zod:

email: z
  .string()
  .email(),
password: z
  .string()

OBS.: Chaves não presentes no schema serão ignoradas.

Exemplo de Response:

201 Created
{
	"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhZG1pbiI6dHJ1ZSwiaWF0IjoxNjc4ODE2MzE4LCJleHAiOjE2Nzg5MDI3MTgsInN1YiI6IjYifQ.TLL1i1jU4rpOwiqqS8n0J4vr2rMa4i68hZ0v6yIwTdI"
}

Possíveis Erros:

Código do Erro Descrição Causa
400 Bad Request ZodError - Invalid Body. Corpo da requisição possui alguma chave ou valor incorreto.
401 Unauthorized Invalid credentials Email ou senha estão incorretos.

4.2. Users

Voltar para os Endpoints

O objeto User é definido como:

Campo Tipo Descrição
id number Identificador único do usuário
name string O nome do usuário.
email string O e-mail do usuário. Valor Único.
password string A senha de acesso do usuário
admin boolean Define se o usuário é Administrador ou não. Campo opcional.
createdAt date Data de criação gerada no momento da criação. Read-only.
updatedAt date Data de atualização gerada no momento de qualquer alteração. Read-only.
deletedAt date Data de deleção gerada no momento da deleção. Read-only.

Endpoints

Método Rota Descrição
POST /users Criação de um usuário.
GET /users Lista todos os usuários
PATCH /users/:id Atualiza um usuário usando seu ID como parâmetro
DELETE /users/:id Realiza um soft delete em um usuário usando seu ID como parâmetro

4.2.1. Criação de Usuário

Voltar para os Endpoints

/users

Exemplo de Request:

POST /users
Host: http://localhost:3000/
Authorization: None
Content-type: application/json

Corpo da Requisição:

{
	"name": "Gabriel",
	"email": "gabriel@mail.com",
	"password": "1234"
}

OBS.: A chave "admin" é opcional. O valor padrão é false.

Schema de Validação com Zod:

name: z
  .string()
  .max(45, 'String must contain at most 45 character(s)'),
email: z
  .string()
  .email('Invalid email'),
password: z
  .string()
  .max(120, 'String must contain at most 120 character(s)'),
admin: z
  .boolean()
  .default(false)

OBS.: Chaves não presentes no schema serão ignoradas.

Exemplo de Response:

201 Created
{
	"id": 1,
	"name": "Gabriel",
	"email": "gabriel@mail.com",
	"admin": false,
  "createdAt": "2023-04-16",
  "updatedAt": "2023-04-16",
  "deletedAt": null
}

Possíveis Erros:

Código do Erro Descrição Causa
409 Conflict Email already registered. Email inserido já está registrado.
400 Bad Request ZodError - Invalid Body. Corpo da requisição possui alguma chave ou valor incorreto.

4.2.2. Listando Usuários

Voltar aos Endpoints

/users

Esta rota só pode ser acessada por usuários administradores que estão logados.

Exemplo de Request:

GET /users
Host: http://localhost:3000/
Authorization: Bearer Token
Content-type: application/json

Corpo da Requisição:

Vazio

Exemplo de Response:

200 OK
[
  {
    "id": 1,
    "name": "Gabriel",
    "email": "gabriel@mail.com",
    "admin": false,
    "createdAt": "2023-04-16",
    "updatedAt": "2023-04-16",
    "deletedAt": null
  }
]

Possíveis Erros:

Código do Erro Descrição Causa
401 Unauthorized Missing Bearer Token. Token não enviado.
401 Unauthorized JWT malformed. Token violado ou incompleto
403 Forbidden Insufficient Permission. Tentativa de acesso sem permissão de administrador

4.2.3. Atualização de Usuário

Voltar para os Endpoints

/users/:id

Apenas administradores podem atualizar qualquer usuário. Usuários não-administradores podem apenas atualizar a si mesmo.

Exemplo de Request:

PATCH /users/1
Host: http://localhost:3000/
Authorization: Bearer Token
Content-type: application/json

Corpo da Requisição:

{
	"name": "Gabriel Pavão"
}

OBS.: A chave "admin" não pode ser atualizada.

Schema de Validação com Zod:

name: z
  .string()
  .max(45, 'String must contain at most 45 character(s)')
  .optional(),
email: z
  .string()
  .email('Invalid email')
  .optional(),
password: z
  .string()
  .max(120, 'String must contain at most 120 character(s)')
  .optional()

OBS.: Chaves não presentes no schema serão ignoradas.

Exemplo de Response:

200 OK
{
	"id": 1,
	"name": "Gabriel Pavão",
	"email": "gabriel@mail.com",
	"admin": false,
  "createdAt": "2023-04-16",
  "updatedAt": "2023-04-16",
  "deletedAt": null
}

Possíveis Erros:

Código do Erro Descrição Causa
400 Bad Request ZodError - Invalid Body. Corpo da requisição possui alguma chave ou valor incorreto.
401 Unauthorized Missing Bearer Token. Token não enviado.
401 Unauthorized JWT malformed. Token violado ou incompleto
403 Forbidden Insufficient Permission. Tentativa de acesso sem permissão de administrador
404 Not Found User not found. ID inserido na url não existe.
409 Conflict Email already registered. Email inserido já está registrado.

4.2.4. Deleção de Usuário

Voltar para os Endpoints

/users/:id

A rota realiza um soft delete do usuário e pode ser acessada apenas por usuários administradores.

Exemplo de Request:

DELETE /users/1
Host: http://localhost:3000/
Authorization: Bearer Token
Content-type: application/json

Corpo da Requisição:

Vazio

Exemplo de Response:

204 No Content

Possíveis Erros:

Código do Erro Descrição Causa
401 Unauthorized Missing Bearer Token. Token não enviado.
401 Unauthorized JWT malformed. Token violado ou incompleto
403 Forbidden Insufficient Permission. Tentativa de acesso sem permissão de administrador
404 Not Found User not found. ID inserido na url não existe.

4.3. Categories

Voltar para os Endpoints

O objeto Category é definido como:

Campo Tipo Descrição
id number Identificador único da categoria
name string O nome da categoria. Valor único.

Endpoints

Método Rota Descrição
POST /categories Criação de uma categoria
GET /categories Lista todas as categorias
GET /categories/:id/realEstate Lista todos imóveis que pertencem a uma categoria

4.3.1. Criação de Categorias

Voltar para os Endpoints

/categories

A rota pode ser acessada apenas por usuários administradores.

Exemplo de Request:

POST /categories
Host: http://localhost:3000/
Authorization: Bearer Token
Content-type: application/json

Corpo da Requisição:

{
	"name": "Apartamento"
}

Schema de Validação com Zod:

name: z
  .string()
  .max(45)

OBS.: Chaves não presentes no schema serão ignoradas.

Exemplo de Response:

201 Created
{
	"id": 1,
	"name": "Apartamento"
}

Possíveis Erros:

Código do Erro Descrição Causa
400 Bad Request ZodError - Invalid Body. Corpo da requisição possui alguma chave ou valor incorreto.
401 Unauthorized Missing Bearer Token. Token não enviado.
401 Unauthorized JWT malformed. Token violado ou incompleto
403 Forbidden Insufficient Permission. Tentativa de acesso sem permissão de administrador
409 Conflict Category already exists. Categoria inserida já está registrada.

4.3.2. Listando as Categorias

Voltar aos Endpoints

/categories

A rota possui acesso livre.

Exemplo de Request:

GET /categories
Host: http://localhost:3000/
Authorization: None
Content-type: application/json

Corpo da Requisição:

Vazio

Exemplo de Response:

200 OK
[
  {
	  "id": 1,
	  "name": "Apartamento"
  }
]

Possíveis Erros:

Nenhum erro é esperado para essa rota. O máximo que pode acontecer é o retorno de uma lista vazia.


4.3.3. Listando Imóveis de uma Categoria

Voltar aos Endpoints

/categories/:id/realEstate

A rota possui acesso livre.

Exemplo de Request:

GET /categories/1/realEstate
Host: http://localhost:3000/
Authorization: None
Content-type: application/json

Corpo da Requisição:

Vazio

Exemplo de Response:

200 OK
{
  "id": 1,
  "name": "Apartamento",
  "realEstate": [
    {
      "id": 1,
      "value": "100000.00",
      "size": 500,
      "sold": false,
      "createdAt": "2023-03-02",
      "updatedAt": "2023-03-02"
    }
  ]
}

Possíveis Erros:

Código do Erro Descrição Causa
404 Not Found Category not found. ID da categoria informada não existe.

4.4. Real Estates

Voltar para os Endpoints

O objeto Real Estate é definido como:

Campo Tipo Descrição
id number Identificador único do imóvel
value float Preço do imóvel
size number Área total do imóvel
categoryId number ID da categoria da qual o imóvel pertence
sold boolean Booleano que informa se o imóvel foi vendido. Read-only.
createdAt date Data de criação gerada no momento da criação. Read-only.
updatedAt date Data de atualização gerada no momento de qualquer alteração. Read-only.
address object Objeto contendo os dados do endereço do imóvel. Ver tabela abaixo para saber mais.

O objeto Address é definido como:

Campo Tipo Descrição
id number Identificador único do endereço
street string Nome da rua do endereço
zipCode string Código postal (CEP) do endereço em até 8 dígitos
number string Número do imóvel
city string Cidade do endereço
state string Estado do endereço no formato AA. Ex: SP.

Endpoints

Método Rota Descrição
POST /realEstate Criação de um imóvel
GET /realEstate Lista todos os imóveis

4.4.1. Criação de Imóveis

Voltar para os Endpoints

/realEstate

A rota pode ser acessada apenas por usuários administradores.

Exemplo de Request:

POST /realEstate
Host: http://localhost:3000/
Authorization: Bearer Token
Content-type: application/json

Corpo da Requisição:

{
	"value": 100000.00,
	"size": 500,
	"categoryId": 1,
	"address": {
		"street": "Rua das Flores",
		"number": "15"
		"zipCode": "66520000",
		"city": "Curitiba",
		"state": "PR"
	}
}

Schema de Validação de Real Estate com Zod:

value: z
	.number()
	.min(-9999999999.99)
	.max(9999999999.99)
	.or(z.string()),
size: z
	.number()
	.int()
	.positive()
categoryId: z
	.number()
	.int()
address: Address

Schema de Validação de Address com Zod:

street: z
	.string()
	.max(45),
zipCode: z
	.string()
	.max(8),
number: z
	.string()
	.max(7)
	.nullish(),
city: z
	.string()
	.max(20),
state: z.string().max(2)

OBS.: Chaves não presentes no schema serão ignoradas.

Exemplo de Response:

201 Created
{
	"id": 1,
	"value": "100000.00",
	"size": 500,
	"sold": false,
	"createdAt": "2023-04-27",
	"updatedAt": "2023-04-27",
	"address": {
		"id": 1,
		"street": "Rua das Flores",
		"number": "15",
		"zipCode": "66520000",
		"city": "Curitiba",
		"state": "PR",
	},
	"category": {
		"id": 1,
		"name": "Apartamento"
	}
}

Possíveis Erros:

Código do Erro Descrição Causa
400 Bad Request ZodError - Invalid Body. Corpo da requisição possui alguma chave ou valor incorreto.
401 Unauthorized Missing Bearer Token. Token não enviado.
401 Unauthorized JWT malformed. Token violado ou incompleto
403 Forbidden Insufficient Permission. Tentativa de acesso sem permissão de administrador
409 Conflict Address already exists. Endereço inserido já está registrado.

4.4.2. Listando Imóveis

Voltar para os Endpoints

/realEstate

A rota possui acesso livre.

Exemplo de Request:

POST /realEstate
Host: http://localhost:3000/
Authorization: None
Content-type: application/json

Corpo da Requisição:

Vazio

Exemplo de Response:

200 OK
[
	{
		"id": 1,
		"value": "100000.00",
		"size": 500,
		"createdAt": "2023-04-27",
		"updatedAt": "2023-04-27",
		"sold": false,
		"address": {
			"id": 1,
			"street": "Rua das Flores",
			"number": "15",
			"zipCode": "66520000",
			"city": "Curitiba",
			"state": "PR",
		}
	}
]

Possíveis Erros:

Nenhum erro é esperado para essa rota. O máximo que pode acontecer é o retorno de uma lista vazia.


4.5. Schedules

Voltar para os Endpoints

O objeto Schedules é definido como:

Campo Tipo Descrição
id number Identificador único da categoria
date date Data de agendamento da visita ao imóvel no formato AAAA-DD-MM
hour string Horário de agendamento da visita ao imóvel no formato HH:MM
realEstateId number ID do imóvel a ser visitado
userId number ID do usuário que está agendando a visita. Read-only.

Endpoints

Método Rota Descrição
POST /schedules Agenda uma visita a um imóvel
GET /schedules/realEstate/:id Lista todos os agendamentos de um imóvel

4.5.1. Agendando Visita a um Imóvel

Voltar para os Endpoints

/schedules

A rota pode ser acessada apenas por usuários logados.

Exemplo de Request:

POST /schedules
Host: http://localhost:3000/
Authorization: Bearer Token
Content-type: application/json

Corpo da Requisição:

{
	"date": "2023/04/19",
  	"hour": "15:00",
	"realEstateId": 1
}

Schema de Validação de Real Estate com Zod:

date: z
	.string()
	.refine((date: string) => {
		const dateRegex: RegExp = /^\d{4}\/(0[1-9]|1[012])\/(0[1-9]|[12][0-9]|3[01])$/
		return dateRegex.test(date)
	}, { message: 'Invalid date, date format is YYYY/DD/MM' })
	.refine((date: any) => {
		date = date.split('/')
		const handleDate = new Date(date[0], date[2] - 1, date[1])
		const dateDay = handleDate.getDay()	
		return dateDay >= 1 && dateDay <= 5
	}, { message: 'Invalid date, work days are monday to friday'}),
hour: z
	.string()
	.refine((hour: string) => {
		const hourRegex: RegExp = /^(0[8-9]|1[0-7]):[0-5][0-9]$/
		return hourRegex.test(hour)
	}, { message: `Invalid hour, available times are 8AM to 18PM` }),

realEstateId: z
	.number()
	.int()

Exemplo de Response:

201 Created
{
	"message": "Schedule created"
}

Possíveis Erros:

Código do Erro Descrição Causa
400 Bad Request ZodError - Invalid Body. Corpo da requisição possui alguma chave ou valor incorreto.
400 Bad Request Invalid hour, available times are 8AM to 18PMy. A hora informada é antes das 8:00 ou depois das 18:00.
400 Bad Request Invalid date, work days are monday to friday. A data informada corresponde a um sábado ou domingo.
401 Unauthorized Missing Bearer Token. Token não enviado.
401 Unauthorized JWT malformed. Token violado ou incompleto
404 Not Found RealEstate not found. ID do imóvel fornecido não existe
409 Conflict Schedule to this real estate at this date and time already exists. Já existe uma visita marcada para esse imóvel nessa mesma data e hora.
409 Conflict User schedule to this real estate at this date and time already exists. O próprio usuário já possui uma outra visita agendada nessa mesma data e hora.

4.5.2. Listar Agendamentos de um Imóvel

Voltar para os Endpoints

/schedules/realEstate/:id

A rota pode ser acessada apenas por usuários administradores.

Exemplo de Request:

POST /schedules/realEstate/:id
Host: http://localhost:3000/
Authorization: Bearer Token
Content-type: application/json

Corpo da Requisição:

Vazio

Exemplo de Response:

200 OK
{
	"id": 1,
	"value": "100000.00",
	"size": 500,
	"createdAt": "2023-04-27",
	"updatedAt": "2023-04-27",
	"sold": false,
	"category": {
		"id": 1,
		"name": "Apartamento"
	},
	"address": {
		"id": 1,
		"street": "Rua das Flores",
		"zipCode": "66520000",
		"number": 15,
		"city": "Curitiba",
		"state": "PR"
	},
	"schedules": [
		{
			"id": 1,
			"date": "2023-04-19",
			"hour": "15:00:00",
			"user": {
				"id": 1,
				"name": "Gabriel",
				"email": "gabriel@mail.com",
				"admin": true,
				"createdAt": "2023-03-01",
				"updatedAt": "2023-03-01",
				"deletedAt": null
			}
		}
	]
}

Possíveis Erros:

Código do Erro Descrição Causa
401 Unauthorized Missing Bearer Token. Token não enviado.
401 Unauthorized JWT malformed. Token violado ou incompleto
403 Forbidden Insufficient Permission. Tentativa de acesso sem permissão de administrador

5. Sobre os Testes

Essa aplicação possui testes, que são utilizados para validar, se todas as regras de negócio foram aplicadas de maneira correta.

Os testes estão localizados em src/__tests__.

Na subpasta integration estão os testes.

Já na subpasta mocks estão os dados que serão utilizados para os testes.

No arquivo jest.config.ts estão algumas configurações necessárias para os testes rodarem.

De modo algum altere qualquer um desses arquivos. Isso poderá comprometer a integridade dos testes.

E também não altere o script de test localizado no package.json. Isso será utilizado para rodar os testes.

Rodando os testes

Para rodar os testes é necessário que no seu terminal, você esteja dentro do diretório do projeto.

Estando no terminal e dentro do caminho correto, você poderá utilizar os comandos a seguir:

Rodar todos os testes

# caso use npm
npm run test

# caso use yarn
yarn test

Rodar todos os testes e ter um log ainda mais completo

# caso use npm
npm run test --all

# caso use yarn
yarn test --all

Rodar os testes de uma pasta específica

detalhe: repare que tests está envolvido por 2 underlines. Isso se chama dunder.

# caso use npm
npm run test <subpasta>

# caso use yarn
yarn test <subpasta>

Rodar os testes de um arquivo específico

# caso use npm
npm run test <subpasta>/<arquivo>

# caso use yarn
yarn test <subpasta>/<arquivo>

Caso você queira verificar todas as opções de execução de testes, visite a Documentação oficial do Jest

Após rodar um dos comandos aparecerá um log no seu terminal, contendo as informações da execução do teste.

Observação: O teste pode demorar alguns segundos para ser finalizado. Quanto maior for o teste, mais tempo será consumido para a execução.

About

API para Gerenciamento de uma Imobiliária.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published