API RESTful da aplicação Focus Timer, uma aplicação de produtividade baseada na técnica de Pomodoro. Essa API é responsável por criar e autenticar os usuários, criar timers personalizados e criar tasks para máxima produtividade.
- Typescript
- Node.js
- Express.js
- MongoDB
- Mongoose
- JWT
- Vitest
- Swagger
A arquitetura utilizada no Focus Timer foi MVC (Models, View e Controllers) + camadas de Service e Repositories.
Uma breve explicação sobre a arquitetura:
Defini todos os campos dentro de Schemas do MongoDB utilizando o Mongoose.
São o entry point das rotas. Nelas me concentrei em:
Receber e responder requisições HTTP
Validar dados básicos
Enviar o payload para a camada de services A controller não contém regra de negócio, apenas orquestra a requisição.
Separei e tratei todas as regras de negócio da aplicação nessa camada. Em alguns casos, já faço o retorno do dado de forma segura para a controller (removendo informações sensíveis, por exemplo).
Camada responsável por se comunicar diretamente com o MongoDB. Utilizando o Mongoose, implementei métodos para persistir, alterar, buscar e deletar dados.
A camada de View é representada pelo retorno padronizado em JSON.
A estrutura é focada na separação entre camadas, controllers (entrada/saida HTTP), services (regras de negócio), repositories (acesso a dados), schemas/middlewares (validação), errors (classes de erros padronizadas), codes (códigos centralizados de sucesso, erros gerais e erros de validação).
src
├── codes
├── config
├── controllers
├── docs
│ └── routes
├── errors
├── middlewares
│ ├── auth
│ ├── avatar
│ ├── errors
│ └── validations
├── models
├── repositories
├── routes
├── schemas
│ ├── auth
│ ├── task
│ ├── timer
│ └── user
├── services
├── types
└── utils{
"code": "OPERATION_CODE",
"data": {}
}{
"errors": [
{
"code": "ERROR_CODE",
"field": "fieldName"
}
]
}codecódigo único que identifica a operação realizadadataobjeto retornado quando faz sentido enviar dadoserrorsarray de erros padronizadosfieldquando aplicável, identifica o campo que gerou o erro
Esse padrão facilita o consumo pelo frontend e mantém previsibilidade nas respostas.
CRUD de usuáriosLogin com JWTUtilização da lib Bcrypt para hash de senhasUpload de avatar de usuário em Bucket na Oracle CloudCRUD de tasksConfiguração de timer personalizado
Rotas protegidas com middleware de autenticaçãoValidações com a lib ZodUtilização da lib file-type para verificar a sequência de bytes dos arquivos enviados, garantindo que estão no formato requisitadoUso de dotenv, evitando dados sensíveis serem hardcodedUtilização da lib Multer para carregar imagens em memóriaUtilização estratégica da lib Sharp para redimensionamento e compressão de imagens
Testes unitários usando VitestDocumentação de rotas com SwaggerFluxo de CI e CD com Docker e Github Actions
Persistência com MongoDB
Maior coverage de testesEstatísticas de produtividade (histórico de sessões, métricas de foco, etc.)
- Clone o repositório
git clone https://github.com/matholv512/focus-timer-backend.git- Entre na pasta do projeto
cd focus-timer-backend- Preencha o arquivo .env usando o .env-sample como exemplo
PORT=
DB_URL=
NODE_ENV=
JWT_SECRET=
FRONTEND_URL=
OCI_BUCKET_NAME=
OCI_REGION=- Instale as dependências
npm install- Rode o projeto
npm run devnpm run testO projeto conta com fluxo de CI e CD, utilizando Docker, Github Actions e Oracle Cloud.
No CI configurei a pipeline para:
- Verificar o repositório e montar o setup com node.
- Instalar as dependências.
- Rodar os testes.
- Logar no GHCR (Github Container Registry).
- Buildar uma imagem docker usando o Dockerfile na raiz do projeto, gerando duas versões: uma versão latest e outra versão com ${{ github.sha }} para manter a rastreabilidade por commit, as imagens geradas são de arquitetura Linux/ARM64 para a compatibilidade com a vm de deploy escolhida.
- Fazer o push dessas imagens para o GHCR.
No CD configurei a pipeline para:
- Esperar pelo pipeline de CI
- Conectar-se via SSH usando as credenciais salvas nos secrets do Github (host, username e a key com a chave privada da VM).
- Entrar na pasta onde está o projeto, previamente configurado com os .env localmente nessa VM.
- Rodar o comando docker para obter a imagem mais recente:
-
compose pull backend
- E então subir os containers docker:
-
docker compose up -d backend
A aplicação roda em:
- Uma VM Oracle Cloud A1 flex (ARM64).
- Docker + Docker Compose.
- Nginx como servidor gateway (reverse proxy).
- Certbot para emissão de certificado HTTPS.
- Bucket Object Storage para armazenar os avatares dos usuários.
Os testes rodam em:
- Uma outra VM Oracle Cloud A1 flex (ARM64) isolada para atuar como runner self hosted do Github Actions, contando com menores recursos de hardware.