👤
Registrado
Aplicação de registro de usuários capaz de criar, ler, atualizar e deletar usuários do banco de dados (CRUD). O projeto é dividido em Front-end e Back-end, ambos os ambientes (e o banco de dados) são executados dentro de um container criado pelo Docker Compose
🧰
Desenvolvido com
- Next.js
- Sass/Scss
- TypeScript
- Node.js
- Express
- Prisma
- PostgreSQL
- Docker
🔧
Instalação
⚠️ É necessário ter o Docker e o Docker Compose instalados na sua máquina para executar esse projeto em containers.
- Clone este repositório:
git clone [email protected]:adilsongb/registrado-app.git
- Acesse a pasta do projeto:
cd registrado-app
- Suba os containers da aplicação usando o comando do Docker Compose:
📌 O processo de instalação das dependências é feito durante a construção do container de cada ambiente.
docker-compose up
⚠️ O ambiente de desenvolvimento é criado através do arquivodocker-compose.yml
! Com ele os containers de Back e Front são atualizados a cada mudança feita nos arquivos do projeto.
- Tudo certo! Você pode acessar a aplicação nos seguintes endereços:
- Front-end:
http://localhost:3000/
- Back-end:
http://localhost:3001/
- Front-end:
💻
Deploy
- O deploy é realizado na plataforma do Heroku. Links das aplicações:
- Front-end: https://registrado-frontend.herokuapp.com/
- Back-end: https://registrado-backend.herokuapp.com/
- O deploy de ambos os ambientes (Front e Back-end) é executado automaticamente através do GitHub Actions. Qualquer mudança feita na branch
main
do repositório remoto do projeto já inicia o processo de deploy. - O arquivo da action de deploy se encontra em:
.github/workflows/main.yml
.
💡
Dica
- No projeto há um arquivo
app.code-workspace
, com ele é criado um workspace no VSCode separando o Front-end e o Back-end da aplicação.
Back-end
- O back-end da aplicação foi desenvolvido com
Node.js
,TypeScript
,Express
ePrisma
. A aplicação pode ser acessada localmente (Se o container estiver em execução) no endereçohttp://localhost:3001/
.
📁
Organização
└── 📂 registrado-app
├── 📂 backend
| ├── 📂 prisma
| | ├── 📁 migrations // Histórico de migrações de schema do Prisma
| | ├── 📄 seed.ts // Arquivo com os dados iniciais do DB
| | └── 📄 schema.prisma // Arquivo que referencia e configura as tabelas do DB
| └── 📂 src
│ ├── 📂 database
│ | └── 📄 connection.ts // Faz a conexão com o banco de dados através do Prisma Client
| ├── 📁 models // Pasta com arquivos que se comunicam diretamente com o DB
| ├── 📁 services // Pasta com arquivos que fazem conexão com o cliente e o DB
| ├── 📁 controllers // Pasta com arquivos que se comunicam diretamente com o cliente
| ├── 📁 interfaces // Pasta com interfaces de tipagem de objetos
| ├── 📁 validations // Pasta com as validações executadas pela biblioteca Joi
| ├── 📁 middlewares
| | └── 📄 error.ts // Middleware para tratamento de erros da API
| ├── 📁 routes // Pasta com as rotas (Endpoints) da API
| └── 📄 server.ts // Arquivo de configuração e inicialização da API
└── 📁 frontend
🎯
Endpoints
GET
-
/users/page/:page
-
Retorna um array contendo 10 usuários. Dependendo do número passado no parâmetro
:page
apenas uma fração especifica de usuários é retornada, por exemplo: O endpoint/users/page/2
retorna os usuários de ordem 11-20. (Endpoint criado especialmente para dar o efeito de paginação no Front-end)🪃 Exemplo de retorno
[ { "id": 1, "name": "Adilson Gabriel", "email": "[email protected]", "password": "F4MAJVQ3hkFElTb", "createdAt": "2022-05-26T21:42:34.364Z" }, { "id": 2, "name": "Carlos Nogueira", "email": "[email protected]", "password": "GsI2Y00ca05Lftu", "createdAt": "2022-05-26T21:42:34.364Z" }, { "id": 3, "name": "Amanda Sousa", "email": "[email protected]", "password": "Up6CsttZ6mmKbcd", "createdAt": "2022-05-26T21:42:34.364Z" }, { "id": 4, "name": "Bernardo Gomes", "email": "[email protected]", "password": "IrbWXLmxziRXLlu", "createdAt": "2022-05-26T21:42:34.365Z" }, { "id": 5, "name": "Beatriz Castro", "email": "[email protected]", "password": "sfD551gbKmfad9u", "createdAt": "2022-05-26T21:42:34.365Z" }, { "id": 6, "name": "Eliza Marcena", "email": "[email protected]", "password": "5yF8V4CEhUXtub6", "createdAt": "2022-05-26T21:42:34.365Z" }, { "id": 7, "name": "Matheus Santos", "email": "[email protected]", "password": "C4BDJ0pmghaKgEz", "createdAt": "2022-05-26T21:42:34.365Z" }, { "id": 8, "name": "Joyce Vizoto", "email": "[email protected]", "password": "iArEIBlEA1mHow0", "createdAt": "2022-05-26T21:42:34.365Z" }, { "id": 9, "name": "Anthony Barbosa", "email": "[email protected]", "password": "KYfqh4UcjRFbQao", "createdAt": "2022-05-26T21:42:34.365Z" }, { "id": 10, "name": "João Marcelo", "email": "[email protected]", "password": "PSfasLke187BBzT", "createdAt": "2022-05-26T21:42:34.365Z" } ]
-
-
/users/get/:id
-
Retorna um objeto contendo o usuário que possui o
id
passado pelo parâmetro.🪃 Exemplo de retorno
/users/get/1
{ "id": 1, "name": "Adilson Gabriel", "email": "[email protected]", "password": "F4MAJVQ3hkFElTb", "createdAt": "2022-05-26T22:19:19.023Z" }
-
-
/users/find?[email || name]=[string]&skip=[number]
-
Retorna um array contendo todos os usuários filtrados pela query. O endpoint aceita filtrar pelos atributos
email
ename
. A queryskip
deve ser obrigatória para criar o efeito de paginação caso a pesquisa retorne mais que 10 usuários.🪃 Exemplo de retorno
/users/find?email=hotmail&skip=1
[ { "id": 11, "name": "Lila Hudson", "email": "[email protected]", "password": "OoscW4dbwZZAcPy", "createdAt": "2022-05-26T22:31:09.228Z" }, { "id": 12, "name": "Royne Tremblay", "email": "[email protected]", "password": "QtWFaPmp51NyrgO", "createdAt": "2022-05-26T22:31:09.228Z" }, { "id": 16, "name": "Rosella Nogueira", "email": "[email protected]", "password": "Bm9iXnpnmAyoVVi", "createdAt": "2022-05-26T22:31:09.228Z" }, { "id": 35, "name": "Vilma Dincley", "email": "[email protected]", "password": "AJr9AiPzekXP_lQ", "createdAt": "2022-05-26T22:31:09.229Z" }, { "id": 36, "name": "Katheryn Wunsch", "email": "[email protected]", "password": "ie9ZNkeTfEjYyy8", "createdAt": "2022-05-26T22:31:09.229Z" }, { "id": 40, "name": "Willie Cruick", "email": "[email protected]", "password": "5Owmrjbdbrj1W8t", "createdAt": "2022-05-26T22:31:09.229Z" }, { "id": 41, "name": "Erick Wisoky", "email": "[email protected]", "password": "x4F7vq58SGdyEa7", "createdAt": "2022-05-26T22:31:09.229Z" }, { "id": 42, "name": "Melvin O'connell", "email": "[email protected]", "password": "sdIKcjKjyQEyuDC", "createdAt": "2022-05-26T22:31:09.229Z" }, { "id": 44, "name": "Shanel Cronack", "email": "[email protected]", "password": "GVHapyvXJeAujfd", "createdAt": "2022-05-26T22:31:09.230Z" }, { "id": 46, "name": "Corbin Satthy", "email": "[email protected]", "password": "WBwH0mLhos6vTkq", "createdAt": "2022-05-26T22:31:09.230Z" } ]
/users/find?name=gabriel&skip=1
[ { "id": 1, "name": "Adilson Gabriel", "email": "[email protected]", "password": "F4MAJVQ3hkFElTb", "createdAt": "2022-05-26T22:31:09.227Z" } ]
-
-
/users/count?[email || name]=[string]
-
Retorna a quantidade de usuários registrados no banco de dados. O endpoint aceita uma query que filtra a quantidade de usuários com
email
ouname
especifico.🪃 Exemplo de retorno
/users/count
50
/users/count?email=hotmail
12
-
POST
-
/users/create
-
Registra um novo usuário no banco de dados. O endpoint deve receber na requisição um body com o seguinte objeto:
{ "name": "Daenarys Targaryen", "email": "[email protected]", "password": "drogodracarys" }
-
As seguintes validações do Joi são consideradas:
name
: É obrigatório na requisição, deve ser umastring
e ter no mínimo 6 caracteres;email
: É obrigatório na requisição, deve ser umastring
e ter o formato[email protected]
;password
: É obrigatório na requisição, deve ser umastring
e ter no mínimo 8 caracteres.
🪃 Exemplo de retorno
{ "id": 51, "name": "Daenarys Targaryen", "email": "[email protected]", "password": "drogodracarys", "createdAt": "2022-05-26T23:21:26.932Z" }
-
PUT
-
/users/update/:id
-
Atualiza as informações de um determinado usuário com base no
:id
passado por parâmetro. A requisição deve ter um objeto com os atributos que serão atualizados no banco de dados, por exemplo:{ "email": "[email protected]" }
-
As seguintes validações do Joi são consideradas:
name
: Deve ser umastring
e ter no mínimo 6 caracteres;email
: Deve ser umastring
e ter o formato[email protected]
;password
: Deve ser umastring
e ter no mínimo 8 caracteres.
🪃 Exemplo de retorno
{ "id": 1, "name": "Adilson Gabriel", "email": "[email protected]", "password": "F4MAJVQ3hkFElTb", "createdAt": "2022-05-26T22:31:09.227Z" }
-
DELETE
-
/users/delete/:id
-
Deleta um usuário do banco de dados de acordo com o
:id
passado por parâmetro.🪃 Exemplo de retorno
/users/delete/5
{ "id": 5, "name": "Beatriz Castro", "email": "[email protected]", "password": "sfD551gbKmfad9u", "createdAt": "2022-05-26T22:31:09.227Z" }
-
💾
Banco de dados
-
A aplicação utiliza o banco de dados
PostgreSQL
, criado pelo Docker Compose, para armazenar os dados, ou seja, não é necessário ter o PostgreSQL instalado na máquina.
🔷 Comandos do Prisma
⚠️ Os comandos a seguir devem ser executados no terminal do container de Back-end!- Reseta o banco de dados:
npx prisma migrate reset --force
; - Registras os usuários de
seed.ts
:npx prisma db seed
;- Use este comando quando o banco de dados estiver vazio.
- Reseta o banco de dados:
Front-end
- O front-end da aplicação foi desenvolvido com
Next.js
,TypeScript
,Sass
eAxios
. A aplicação pode ser acessada localmente (Se o container estiver em execução) no endereçohttp://localhost:3000/
.
📁
Organização
└── 📂 registrado-app
├── 📂 frontend
| ├── 📂 components // Pasta com os componentes Next.js da aplicação
| ├── 📂 contexts // Pasta com o Context API e Provider
| ├── 📂 hooks
| | └── 📄 useMediaQuery.ts // Hook auxiliar para responsividade da aplicação
| ├── 📂 interfaces // Arquivos de tipagem de dados
| ├── 📂 pages // Pasta com as páginas da aplicação
| ├── 📂 public
| ├── 📂 services
| | └── 📄 api.ts // Arquivo de conexão com a API através do Axios
| ├── 📂 styles // Estilos da aplicação feito em Scss
| ├── 📄 Dockerfile // Arquivo de configuração do container Docker
| └── 📄 tsconfig.json // Arquivo de configuração do TypeScript
└── 📁 backend