Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exam Scheduling API - NodeJS Backend Challenge #8

Open
wants to merge 65 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
67b3e5e
added .gitignore
Sep 19, 2019
613f5fd
added package.json
Sep 19, 2019
dcd6843
initial ts configuration
Sep 19, 2019
a3494f6
first route to test initial config
Sep 19, 2019
ed59bae
nodemon setup
Sep 19, 2019
4a8652f
add initial config swagger openapi specification
Sep 19, 2019
b2d7951
initial docker and docker compose config
Sep 19, 2019
924173b
refactor: created app class to server
Sep 19, 2019
bd6b259
added routes file for separation of responsablitities
Sep 20, 2019
5a09e41
added route test swagger
Sep 20, 2019
09f1636
initial config jest for test
Sep 20, 2019
f18c743
added call for exams api and its unit test
Sep 20, 2019
6b0e5dc
refactor exam service
Sep 20, 2019
6bf708a
renamed service request external api
Sep 20, 2019
f371eb5
replace of axios with request
Sep 21, 2019
1326742
exam listing route completed
Sep 21, 2019
06ce7a5
add simulated database in memory
Sep 21, 2019
f2c825c
unit test database connection
Sep 21, 2019
58d7667
division unit test files
Sep 21, 2019
cdae307
adjustoment unit test database
Sep 21, 2019
42b8e74
added service to save customer and unit test
Sep 21, 2019
e74281a
added customer save route
Sep 21, 2019
696f239
handling for cpf already exists unit test
Sep 21, 2019
3439ec1
adjustment response db and save route
Sep 21, 2019
d2bc07a
added service and unit test update customer
Sep 21, 2019
5f1fee5
added route update customer
Sep 21, 2019
318bf9f
added remove route customer
Sep 21, 2019
ed11fa2
added service find customer by cpf and unit test
Sep 21, 2019
789c024
added customer find route
Sep 21, 2019
f8b969e
added list route
Sep 21, 2019
196be45
refactor customer unit test
Sep 21, 2019
cb40a6c
rename dir inut test customer
Sep 21, 2019
5d1261f
added utils for unit test file
Sep 21, 2019
18e65bb
refactor exam list
Sep 22, 2019
ffd2500
fixed unity test external api
Sep 22, 2019
2667e28
added unit test schedule exam
Sep 22, 2019
611986a
added unit test when same time
Sep 22, 2019
3c0dabb
added schedule route
Sep 22, 2019
d1b2f1f
adjustment unit test
Sep 22, 2019
2c2f767
adjustment route schedule
Sep 22, 2019
95ebfab
added service for get exam bu cpf and sum price and unit test
Sep 22, 2019
83d34ba
added id schedule
Sep 22, 2019
580db5d
added test unit and service for edit schedule
Sep 22, 2019
831ba87
added route update schedule
Sep 22, 2019
76ea798
added service delete schedule and unit test
Sep 22, 2019
48291c1
added route remove schedule
Sep 22, 2019
6a471fc
added interface and other types
Sep 22, 2019
e1370e3
fixed route scedule by cpf
Sep 22, 2019
1021db7
refactor with all routes
Sep 22, 2019
30c76cc
added package-lock
Sep 22, 2019
e499fa1
swagger increments inital
Sep 22, 2019
d5145a4
config env files
Sep 22, 2019
1662ced
adjustment to work default max 2 customer by time in same exam
Sep 22, 2019
66020a3
add travis and adjustment
Sep 22, 2019
4a35d9d
swagger complete
Sep 22, 2019
158279c
added doc with request postman
Sep 22, 2019
ddfb54d
added middlewares layer to complete the architecture
Sep 22, 2019
5067b5b
updated config docker-compose
Sep 22, 2019
ca277f8
updated unit test sintaxe
Sep 22, 2019
c815dde
updated singleton DB
Sep 22, 2019
00fb9af
updated declaration variables
Sep 22, 2019
76ee039
added README.md
Sep 23, 2019
419b745
added selo travis
Sep 23, 2019
ac7cdef
updated format README.md
Sep 23, 2019
5613b1d
Update README.md
LUIZFH Oct 25, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules
package-lock.json
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules
build
6 changes: 6 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
language: node_js
node_js:
- "stable"
cache:
directories:
- "node_modules"
12 changes: 12 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
FROM node:alpine

RUN mkdir -p /var/www/api
WORKDIR /var/www/api

COPY package.json ./
RUN npm install
COPY . ./

EXPOSE 4446

CMD ["npm", "run", "dev"]
55 changes: 0 additions & 55 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,56 +1 @@
Desafio Back-end - Grupo Fleury
====

## Descrição:

O Grupo Fleury deseja disponibilizar uma api restfull para realização de agendamentos para seus clientes,
para tal o usuário precisará ter um cadastro de cliente em nossa base de dados,
selecionar um exame e informar data e hora desejado.

## Regras de Negócio

- Cliente precisa estar cadastrado em base de dados para realizar o agendamento
- Caso o cliente não exista em base, deverá ser feito o cadastro antecipadamente.
- Não será possível realizar agendamento de mais de 2 pacientes para o mesmo exame na mesma data e hora, esse valor de 2 deverá ser parametrizado.
- O cadastro de cliente deverá ter os campos: Nome, CPF e Data de Nascimento
- Não poderá ser cadastrado mais de um cliente para o mesmo CPF
- A lista de exames disponíveis para agendamento deverá ser consumida do endpoint ( http://www.mocky.io/v2/5d681ede33000054e7e65c3f).

## Features
- Deverá haver um endpoint para listagem dos exames disponíveis para agendamento, exibindo apenas nome do exame e id
- Deverá haver um endpoint para criação de um cliente
- Deverá haver um endpoint para atualização de um cliente
- Deverá haver um endpoint para exclusão de um cliente
- Deverá haver um endpoint para busca de um cliente baseado no seu cpf
- Deverá haver um endpoint para listagem de todos os clientes cadastrados

- Deverá haver um endpoint para listagem dos agendamentos de um cliente por cpf, deverá conter o valor total (soma dos valores dos exames selecionados para o agendamento)
- Deverá haver um endpoint para edição de um agendamento realizado, apenas dia e hora poderão ser editados
- Deverá haver um endpoint para exclusão de um agendamento realizado

## Requisitos

- A API deverá ter um swagger
- Teste unitário
- Utilizar uma estrutura de dados a sua escolha para simular a base de dados em memória
- Para vaga de Back-end NodeJS utilizar Typecript, para Vaga de .net utilizar .net core 2.x
- Aplicação deverá conter um Readme contendo instruções de como realizar o build e rodar a Aplicação


## Diferencial
- No readme separe uma sessão para explicar a arquitetura da api
- Tenha em mente conceitos de SOLID e clean architecture
- Docker
- Esteira de CI/CD no github (exemplo Travis CI)

## Como submeter?

Deverá ser enviado um PULL REQUEST com o seu teste.

### Como funciona?

- Fork deste repositório
- Clonar a partir do repositório que foi criada na sua conta
- Procure fazer o máximo de commits com todas as suas decisões
- Abra um Pull Request para este repositório

124 changes: 124 additions & 0 deletions data/db.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
class DB {

private static instance: DB
private static customers: Array<any>
private static schedules: Array<any>

private constructor() {
DB.customers = []
DB.schedules = []
}

public static connection(): DB {
if (!DB.instance) {
DB.instance = new DB()
}

return DB.instance
}

public findCustomer(cpf: string) {
const customer = DB.customers.find( item => item.cpf === cpf)

return {
success: customer ? true: false,
data: customer || null,
message: customer ? 'item successfully find' : 'item not found'
}
}

public addCustomer(data: any) {
let result = !DB.customers.find(item => item.cpf === data.cpf) ? DB.customers.push({...data}) : null

return {
success: result ? true: false,
data: DB.customers.find( item => item.cpf === data.cpf && item.name === data.name) || null,
message: result ? 'item successfully saved' : 'item already exists'
}
}

public updateCustomer(cpf: string, data: any) {
let customerIndex = DB.customers.findIndex( item => item.cpf === cpf )

if (customerIndex > -1) {
DB.customers[customerIndex] = { ...data, cpf }
}

return {
success: customerIndex > -1 ? true: false,
data: DB.customers.find( item => item.cpf === cpf ) || null,
message: customerIndex > -1 ? 'item successfully updated' : 'item not found'
}
}

public removeCustomer(cpf: string): any {
let customer = DB.customers.find( item => item.cpf === cpf )

if (customer) {
DB.customers = DB.customers.filter( item => item.cpf !== cpf)
}

return {
success: customer ? true: false,
data: customer || null,
message: customer ? 'item successfully removed' : 'item not found'
}
}

public listCustomer() {
const customers = DB.customers
return {
success: customers ? true: false,
data: customers || null,
message: customers ? 'items successfully removed' : 'items not found'
}
}

public createSchedule(data: any): any {
let id = DB.schedules.length + 1
DB.schedules.push({ ...data, id })
return DB.schedules.find( item => item.cpf == data.cpf && item.examId === data.examId)
}

public updateSchedule(id: number, date: any): any {
let scheduleIndex = DB.schedules.findIndex( item => item.id === id)

if (scheduleIndex > -1) {
DB.schedules[scheduleIndex] = { ...DB.schedules[scheduleIndex] , date: date}
}

return {
success: scheduleIndex > -1 ? true: false,
data: DB.schedules.find( item => item.id === id ) || null,
message: scheduleIndex > -1 ? 'item successfully updated' : 'item not found'
}
}

public getByScheduleByDate( examId: string, date: any ) {
return DB.schedules.filter( item => item.examId === examId && item.date === date )
}

public getScheduleByCpf(cpf: string): any {
return DB.schedules.filter(item => item.cpf === cpf)
}

public removeSchedule(id: number): any {
let schedule = DB.schedules.find( item => item.id === id )

if (schedule) {
DB.schedules = DB.schedules.filter( item => item.id !== id)
}

return {
success: schedule ? true: false,
data: schedule || null,
message: schedule ? 'item successfully removed' : 'item not found'
}
}

public static resetForUnitTest(): void {
DB.instance = new DB()
}
}

export default DB
11 changes: 11 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
version: "3"

services:
api:
build: .
env_file:
- ./env/local.env
ports:
- "4446:4446"
environment:
- NODE_ENV=local
Loading