# desafio-sse Este repositório contém a solução para o desafio da Kenoby. ## TOC - [Instalação](#Instalação) - [Configuração](#Configuração) # Instalação Requisitos: * [NodeJS](https://nodejs.org/en/) * [Yarn](https://yarnpkg.com/en/) * [Docker](https://docs.docker.com/compose/install/) O Yarn foi escolhido por conta do avançado sistema de cache, entratanto, pode ser utilizado com o npm padrão. ``` bash yarn ``` Após a instação das dependências, deve-se executar o comando para subir a infraestrutura da API (Postgres e Elastic Search). No diretório raiz do projeto (Para o Elastic Search) ```bash sudo docker-composer up ``` Dentro do diretório `./docker/sql` (Para o Postgres) ``` bash sudo docker-composer up ``` Quando a infraestrutura já estiver operacional, execute as migrations ``` bash yarn sequelize db:migrate ``` **OBS: Se estiver utilizando o banco Postgres é importante definir a variável de ambiente TEST_RUN_MIGRATIONS_AND_SEEDERS igual a false no arquivo .env.** Para rodar o servidor em ambiente de produção ``` bash yarn start ``` Executar o comando para rodar o servidor em ambiente de desenvolvimento. ``` bash yarn dev ``` Executar o comando para rodar os testes de unidade e integração. ``` bash yarn test ``` ## Uso .desafio-sse/ ├─ \_\_tests\_\_ ├─ data ├─ docker ├─ src ├─── app ├─── config ├─── database ├─── errors ├─── helpers ├─── routes └─── services A seguinte estrutura é descrita: * \_\_tests\_\_ diretório onde ficam os testes unitários e de integrações. * data/ diretório que contém seeders para população da base de dados. * docker/ diretório que contém configurações e scripts para inicializar containers do Docker. * src/ diretório que contém todo o código fonte da aplicação (Podendo ser utilizado pelo Webpack para gerar o `dist`. * app/ diretório que contém a regra de negócio da API, como controllers, models e middlewares. * config/ arquivos em JS que fazem o setup de dependências chaves para o correto funcionamento da aplicação. * database/ migrations, seeders e banco de dados local. * errors/ arquivos em JS que representam exceções da aplicação. * helpers/ arquivos em JS que contém funções auxiliares para várias funcionalidades. * routes/ arquivos em JS para realizar o mapeamento das rotas. * services/ abstrações de integrações com serviços externos como por exemplo: Elastic Search. # Configuração Realizar cópias do .env.example. ``` bash cp .env.example .env cp .env.example .env.test ``` ## Variáveis de ambiente | Variável | Descrição | |:----------:|:-------------:| | APP_ENV | Ambiente da aplicação, podendo ser *development*, *testing*, *staging* ou *production*. | | APP_SENTRY_DSN | Callback do Sentry para o envio de exceções/logs. | | APP_CANDIDATURES_BATCH_MAX_SIZE | Tamanho máximo de processamento de candidaturas por requisição. | | SERVER_PROTOCOL | Protocolo utilizado pelo servidor, podendo ser http ou https. | | SERVER_HOST | Endereço do servidor. | | SERVER_PORT | Porta do servidor. | | DB_USERNAME | Usuário do banco de dados. | | DB_PASSWORD | Senha do banco de dados. | | DB_DATABASE | Nome do banco de dados. | | DB_HOST | Endereço do banco de dados. | | DB_DIALECT | Tipo de banco de dados que será utilizado pelo Sequelize. | | DB_STORAGE_SQLITE | Adaptador para ser utilizado na persistência dos dados no SQLite (Para desenvolvimento e testes automatizados). | | DB_OPERATORS_ALIASES | Permitir o uso de apelidos para operações de busca. | | TEST_RUN_MIGRATIONS_AND_SEEDERS | Executar ou não as migrations completamente. Indicado **false** quando for utilizar o Postgres, que já possui as tabelas de positions e applicants. | | ELASTIC_SEARCH_PROTOCOL | Protocolo utilizado pelo ES, podendo ser http ou https. | | ELASTIC_SEARCH_HOST | Endereço do ES. | | ELASTIC_SEARCH_PORT | Porta do ES. | **Nota: Com o ambiente da aplicação (APP_ENV) definido como *development*, serviços externos como Sentry serão desabilitados.** ### Variáveis de ambiente sugeridas para ambiente de desenvolvimento ###### .env ```env APP_ENV=development APP_SENTRY_DSN= APP_CANDIDATURES_BATCH_MAX_SIZE=25 SERVER_PROTOCOL=https SERVER_HOST=localhost SERVER_PORT=3333 DB_USERNAME=kenoby DB_PASSWORD=12345 DB_DATABASE=kenoby DB_HOST=localhost DB_DIALECT=postgres DB_STORAGE_SQLITE= DB_OPERATORS_ALIASES=false TEST_RUN_MIGRATIONS_AND_SEEDERS=false ELASTIC_SEARCH_PROTOCOL=http ELASTIC_SEARCH_HOST=localhost ELASTIC_SEARCH_PORT=9200 ``` ###### .env.test ```env APP_ENV=testing APP_SENTRY_DSN= APP_CANDIDATURES_BATCH_MAX_SIZE=25 SERVER_PROTOCOL=https SERVER_HOST=localhost SERVER_PORT=3333 DB_USERNAME=kenoby DB_PASSWORD=12345 DB_DATABASE=kenoby DB_HOST=localhost # Dialect Options -> sqlite | postgres DB_DIALECT=sqlite DB_STORAGE_SQLITE=./__tests__/database.sqlite DB_OPERATORS_ALIASES=false TEST_RUN_MIGRATIONS_AND_SEEDERS=true ELASTIC_SEARCH_PROTOCOL=http ELASTIC_SEARCH_HOST=localhost ELASTIC_SEARCH_PORT=9200 ``` Exemplos de requisições para teste. Pode ser utilizado também outras ferramentas como [Postman](https://www.postman.com/). Utilizando o CURL, temos: Para adicionar novas candidaturas: ##### POST - /v1/candidatures ```bash= curl -XPOST -H "Content-type: application/json" -d '[ { "applicant_email": "eduardo.zagari@kenoby.com", "position_name": "HR Supervisor", "situation": "hired" }, { "applicant_email": "lzricardo.ecomp@gmail.com", "position_name": "HR Supervisor", "situation": "hired" } ]' 'http://localhost:3333/v1/candidatures' ``` ##### Tipos de repostas possíveis | Code HTTP | Descrição | |:----------:|:-------------:| | 200 | Candidaturas criadas com sucesso. | | 404 | Vagas ou candidatos não encontrados. | | 422 | Corpo da requisição é inválido. | | 422 | Candidaturas máximas para vaga excedida. | | 422 | Candidaturas duplicadas. | | 500 | Erro interno no servidor. Contacte o administrador. | ##### Estrutura do corpo da resposta em caso de sucesso ```json= [ { "applicant_email": "eduardo.zagari@kenoby.com", "position_name": "HR Supervisor", "situation": "hired" }, { "applicant_email": "lzricardo.ecomp@gmail.com", "position_name": "HR Supervisor", "situation": "hired" } ] ``` ##### Estrutura do corpo da resposta em caso de falha ```json= "error": { "message": "Request body schema invalid.", "validation": "'value' must contain less than or equal to 25 items" } ``` Para consultar candidaturas por pelo e-mail do candidato ou nome da vaga: ##### GET - /v1/candidatures?applicant_email=value&position_name=value ```bash= curl -XGET -H "Content-type: application/json" 'http://localhost:3333/v1/candidatures?position_name=HR Supervisor' ``` ```bash= curl -XGET -H "Content-type: application/json" 'http://localhost:3333/v1/candidatures?applicant_email=eduardo.zagari@kenoby.com&position_name=HR Supervisor' ``` ##### Tipos de repostas possíveis | Code HTTP | Descrição | |:----------:|:-------------:| | 200 | Candidaturas encontradas ou não. | | 422 | Query param da requisição é inválido. | | 500 | Erro interno no servidor. Contacte o administrador. | ##### Estrutura do corpo da resposta ```json= [ { "id": 4, "applicant_email": "tatiane.mesquita@kenoby.com", "position_name": "HR Supervisor", "situation": "hired", "createdAt": "2020-06-22T02:19:17.384Z", "updatedAt": "2020-06-22T02:19:17.384Z" }, { "id": 5, "applicant_email": "eduardo.zagari@kenoby.com", "position_name": "HR Supervisor", "situation": "hired", "createdAt": "2020-06-22T03:26:12.007Z", "updatedAt": "2020-06-22T03:26:12.007Z" }, { "id": 6, "applicant_email": "lzricardo.ecomp@gmail.com", "position_name": "HR Supervisor", "situation": "hired", "createdAt": "2020-06-22T03:26:12.007Z", "updatedAt": "2020-06-22T03:26:12.007Z" } ] ``` ```json= [] ``` ##### Estrutura do corpo da resposta em caso de falha ```json= "error": { "message": "Request query params schema invalid.", "validation": "'applicant_email' or 'position_name' are required" } ```