Projeto para praticar conceitos SOLID na criação de uma API Node.js
Para implementar os 5 princípios do SOLID, foram feitas estas decisões de design patterns:
Dependency inversion
- Os controllers ficam responsáveis de instanciar os use cases passando as dependências, assim podemos focar em criar repositórios genéricos que vão forçar os repositórios de dependência seguirem as regras do jogo, deixando todo o código bem independente em termos de regras de negócio dos casos de uso, que nesta versão da API, por ser algo bem simplificado, ficou como uma simples interface mesmo, mas poderia ser uma classe abstrata.
GymPass style app.
- Deve ser possível se cadastrar;
- Deve ser possível se autenticar;
- Deve ser possível obter o perfil de um usuário logado;
- Deve ser possível obter o número de check-ins realizados pelo usuário logado;
- Deve ser possível o usuário obter o seu histórico de check-ins;
- Deve ser possível o usuário buscar academias próximas (até 10km);
- Deve ser possível o usuário buscar academias pelo nome;
- Deve ser possível o usuário realizar check-in em uma academia;
- Deve ser possível validar o check-in de um usuário;
- Deve ser possível cadastrar uma academia;
- O usuário não deve poder se cadastrar com um e-mail duplicado;
- O usuário não pode fazer 2 check-ins no mesmo dia;
- O usuário não pode fazer check-in se não estiver perto (100m) da academia;
- O check-in só pode ser validado até 20 minutos após ser criado;
- O check-in só pode ser validado por administradores;
- A academia só pode ser cadastrada por administradores;
- A senha do usuário precisa estar criptografada;
- Os dados da aplicação precisam estar persistidos em um banco PostgreSQL;
- Todas listas de dados precisam estar paginadas com 20 itens por página;
- O usuário deve ser identificado por um JWT (JSON Web Token);
Rodando todos os testes unitários com Github Actions a cada push:
Rodando todos os testes e2e com Github Actions a cada PR:
- 22 Testes unitários em todos os use cases, usando banco de dados em memória
- 14 Testes e2e em todas as rotas, usando um banco de dados isolado
------------------|---------|----------|---------|---------|
File | % Stmts | % Branch | % Funcs | % Lines |
------------------|---------|----------|---------|---------|
All files | 95.17 | 90.06 | 96.59 | 95.17 |
------------------|---------|----------|---------|---------|
Setup do projeto
- Create .npmrc file with
save-exact=true
- [todo] Someday, test an upgrade automation with renovate
- npm i typescript @types/node tsx tsup -D
- npx tsc --init
- Change on tsconfig.json
"target": "es2020",
andbaseUrl
andpaths
- Create start:dev, start and build scripts
- Create a .gitignore file
- npm i fastify dotenv zod
- set the env.ts env validation
- npm i eslint @rocketseat/eslint-config -D (or just eslint --init to setup a fresh config)
- .eslintrc.json and .eslintignore
- Install prisma
- npm i prisma -D
- npx prisma init
- npx prisma generate
- npm i @prisma/client
- Run postgres docker image
- edit .env
DATABASE_URL="postgresql://docker:docker@localhost:5432/apisolid?schema=public"
- docker compose up/down (create/delete)
- docker compose start/stop
- edit .env
- Create other models and run the migration
- Setup Vitest
- npm install -D vitest vite-tsconfig-paths @vitest/coverage-v8
- vite.config.ts
- Create use cases and tests, using TDD methodology
- Create factories for repo dependencies in use-cases inside controllers
- Create controllers
- Setup for JWT Auth
- npm i @fastify/jwt
- env and app.js chore
- Setup for Vitest Testing Environments
- Create /prisma/vitest-environment-prisma
- On /prisma/vitest-environment-prisma:
- run npm init -y
- change the main for prisma-test-environment.ts
- run npm link
- Back on root dir
- run npm link vitest-environment-prisma
- Setup CI/CD
- run all unit tests on every push on github using github actions
- run all ee2 tests on every pull request on github using github actions
- API documentation with Swagger