Skip to content

ricardoaruiz/task-manager-api

Repository files navigation

📋 Task Manager API

Uma API RESTful moderna e robusta para gerenciamento de tarefas, construída com as melhores práticas de desenvolvimento e arquitetura limpa! 🚀

📖 Índice

🎯 Sobre o Projeto

A Task Manager API é uma aplicação backend moderna que permite gerenciar tarefas de forma eficiente com sistema de autenticação completo. O projeto foi desenvolvido seguindo os princípios de Clean Architecture, SOLID e Domain-Driven Design (DDD), garantindo:

  • Escalabilidade: Arquitetura modular e bem organizada
  • Testabilidade: Cobertura de testes abrangente
  • Maintibilidade: Código limpo e bem documentado
  • Performance: Otimizações e boas práticas aplicadas
  • Type Safety: TypeScript em todo o projeto
  • Segurança: Sistema completo de autenticação JWT
  • Autorização: Controle de acesso a recursos protegidos

🛠 Tecnologias Utilizadas

🚀 Core Technologies

  • Node.js - Runtime JavaScript/TypeScript
  • TypeScript - Superset tipado do JavaScript
  • Fastify - Framework web rápido e eficiente
  • PostgreSQL - Banco de dados relacional robusto

🗃 Database & ORM

Development Tools

  • Biome - Linter e formatter ultra-rápido
  • Vitest - Framework de testes moderno
  • TSX - TypeScript executor para desenvolvimento
  • TSUP - Build tool TypeScript zero-config

📖 API Documentation

📝 Validation & Types

🐳 Infrastructure

🔑 Authentication & Security

  • bcryptjs - Hashing de senhas com bcrypt
  • jose - Geração e verificação de JWT tokens
  • @fastify/cookie - Manipulação de cookies HTTP

🔧 Utilities

🏗 Arquitetura e Organização

O projeto segue os princípios da Clean Architecture com uma abordagem hexagonal, promovendo:

🎯 Camadas da Aplicação

┌─────────────────────────────────────┐
│           🌐 HTTP Layer             │
│        (Routes & Controllers)       │
├─────────────────────────────────────┤
│          💼 Use Cases Layer         │
│      (Business Logic & Rules)       │
├─────────────────────────────────────┤
│         🏪 Repository Layer         │
│     (Data Access Abstraction)       │
├─────────────────────────────────────┤
│          💾 Database Layer          │
│        (PostgreSQL & Drizzle)       │
└─────────────────────────────────────┘

🔄 Padrões Implementados

  • 🏭 Factory Pattern: Criação de instâncias de use cases
  • 🔌 Dependency Injection: Inversão de dependências
  • 📦 Repository Pattern: Abstração do acesso a dados
  • 🎯 Use Case Pattern: Encapsulamento da lógica de negócio
  • 🛡 Type Provider Pattern: Validação e tipagem automática

📁 Estrutura de Pastas

📦 task-manager-api/
├── 📁 src/                          # Código fonte principal
│   ├── 📄 app.ts                    # Configuração do Fastify
│   ├── 📄 server.ts                 # Inicialização do servidor
│   ├── 📄 env.ts                    # Configuração de ambiente
│   │
│   ├── 📁 @types/                   # Definições de tipos TypeScript
│   │   ├── 📄 fastify.d.ts          # Extensões de tipos do Fastify
│   │   └── 📁 domain/               # Types do domínio da aplicação
│   │       ├── 📄 auth.ts           # Types de autenticação
│   │       ├── 📄 task.ts           # Types de tarefas
│   │       └── 📄 user.ts           # Types de usuários
│   │
│   ├── 📁 db/                       # Configuração do banco de dados
│   │   ├── � schema/               # Schemas das tabelas
│   │   │   ├── 📄 index.ts          # Exportação dos schemas
│   │   │   ├── 📄 tasks-table.ts    # Schema da tabela tasks
│   │   │   └── 📄 user-table.ts     # Schema da tabela users
│   │   ├── 📁 migrations/           # Arquivos de migração
│   │   └── 📁 seed/                 # Scripts de seed
│   │       ├── 📄 seed.ts           # Script principal de seed
│   │       ├── 📄 tasks.ts          # Seed das tarefas
│   │       └── 📄 users.ts          # Seed dos usuários
│   │
│   ├── 📁 lib/                      # Bibliotecas e utilitários
│   │   └── 📄 drizzle.ts            # Configuração do Drizzle ORM
│   │
│   ├── 📁 middlewares/              # Middlewares da aplicação
│   │   └── 📄 check-auth.middleware.ts # Middleware de autenticação
│   │
│   ├── 📁 repositories/             # Camada de acesso a dados
│   │   ├── 📁 drizzle/              # Implementação com Drizzle
│   │   │   ├── 📄 drizzle-task.repository.ts
│   │   │   └── 📄 drizzle-user.repository.ts
│   │   ├── 📁 in-memory/            # Implementação em memória (testes)
│   │   │   ├── 📄 in-memory-task.repository.ts
│   │   │   └── 📄 in-memory-user.repository.ts
│   │   └── 📁 interfaces/           # Contratos dos repositórios
│   │       ├── 📄 task.repository.ts
│   │       └── 📄 user.repository.ts
│   │
│   ├── 📁 routes/                   # Rotas HTTP da aplicação
│   │   ├── 📄 routes.schame.ts      # Schemas comuns das rotas
│   │   ├── 📁 auth/                 # Rotas de autenticação
│   │   │   ├── 📁 login/            # POST /auth/login
│   │   │   └── 📁 signup/           # POST /auth/signup
│   │   ├── 📁 health/               # Rotas de health check
│   │   │   └── 📁 check/            # GET /health/check
│   │   └── 📁 tasks/                # Rotas de tarefas (protegidas)
│   │       ├── 📁 create/           # POST /tasks
│   │       ├── 📁 list/             # GET /tasks
│   │       ├── 📁 load/             # GET /tasks/:id
│   │       ├── 📁 update/           # PUT /tasks/:id
│   │       ├── 📁 delete/           # DELETE /tasks/:id
│   │       └── 📁 complete/         # PATCH /tasks/:id
│   │
│   ├── 📁 services/                 # Serviços da aplicação
│   │   ├── 📄 index.ts              # Exportação dos serviços
│   │   ├── 📁 hash/                 # Serviço de hashing
│   │   │   ├── 📄 hash.service.ts
│   │   │   ├── 📄 hash.service.interface.ts
│   │   │   └── 📄 hash.types.ts
│   │   └── 📁 token/                # Serviço de tokens JWT
│   │       ├── 📄 token.service.ts
│   │       ├── 📄 token.service.interface.ts
│   │       └── 📄 token.types.ts
│   │
│   └── 📁 use-cases/                # Lógica de negócio
│       ├── 📁 auth/                 # Use cases de autenticação
│       │   ├── 📄 login.use-case.ts
│       │   └── 📄 signup.use-case.ts
│       ├── 📁 errors/               # Erros customizados
│       ├── 📁 factory/              # Factory de use cases
│       └── 📁 tasks/                # Use cases de tarefas
│
├── 📁 coverage/                     # Relatórios de cobertura de testes
├── 📁 data/                         # Dados persistentes do PostgreSQL
├── 📄 docker-compose.yml            # Configuração do Docker
├── 📄 drizzle.config.ts             # Configuração do Drizzle Kit
├── 📄 package.json                  # Dependências e scripts
├── 📄 tsconfig.json                 # Configuração do TypeScript
├── 📄 vitest.config.ts              # Configuração do Vitest
├── 📄 vitest.setup.ts               # Setup dos testes
└── 📄 biome.json                    # Configuração do Biome

🎨 Convenções de Nomenclatura

Cada rota segue uma estrutura padronizada:

📁 route-name/
├── 📄 route-name.route.ts           # Implementação da rota
├── 📄 route-name.schemas.ts         # Schemas de validação (Zod)
├── 📄 route-name.types.ts           # Tipos TypeScript
└── 📄 index.ts                      # Exportação da rota

🚀 Instalação e Configuração

📋 Pré-requisitos

  • Node.js ≥ 18.0.0
  • npm ou yarn ou pnpm
  • Docker e Docker Compose (para o banco de dados)

🔧 Passo a Passo

  1. Clone o repositório:
git clone <repository-url>
cd task-manager-api
  1. Instale as dependências:
npm install
  1. Configure o ambiente:
# Crie um arquivo .env baseado no .env.example
cp .env.example .env

# Exemplo de configuração:
# PORT=3000
# PERSISTENCE_TYPE=database
# DATABASE_URL=postgresql://postgres:postgres@localhost:5432/task_manager
# JWT_SECRET=your-super-secret-jwt-key
  1. Inicie o ambiente completo (recomendado):
# Sobe o banco, aplica migrações e popula com dados de exemplo
npm run environment:up

OU configure manualmente:

4a. Inicie o banco de dados:

# Sobe o PostgreSQL via Docker
docker-compose up -d

4b. Execute as migrações:

# Gera e aplica as migrações
npm run db:generate
npm run db:migrate

4c. Popule com dados de exemplo (opcional):

npm run db:seed
  1. Inicie o servidor de desenvolvimento:
npm run dev

🎉 Pronto! A API estará rodando em http://localhost:3000

📖 Acesse a documentação interativa:

  • Scalar API Docs: http://localhost:3000/docs

🔧 Variáveis de Ambiente

Crie um arquivo .env na raiz do projeto com as seguintes variáveis:

# Porta do servidor
PORT=3000

# Tipo de persistência: 'database' ou 'in-memory'
PERSISTENCE_TYPE=database

# URL de conexão com PostgreSQL
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/task_manager

# Chave secreta para assinatura dos tokens JWT
JWT_SECRET=your-super-secret-jwt-key

Tipos de Persistência:

  • database: Usa PostgreSQL com Drizzle ORM (recomendado para produção)
  • in-memory: Usa repositório em memória (ideal para testes e desenvolvimento rápido)

🔍 Verificação da Instalação

Teste se tudo está funcionando:

curl http://localhost:3000/health/check

Resposta esperada:

{
  "status": "ok"
}

🌱 Dados de Exemplo

O projeto inclui um sistema de seed que popula o banco com dados de exemplo:

👥 Usuários:

📋 Tarefas:

  • 20 tarefas de exemplo distribuídas entre os usuários
  • 10 tarefas não completadas (IDs ímpares)
  • 10 tarefas completadas (IDs pares)

Para popular o banco:

npm run db:seed

Exemplo de tarefa criada:

  • Título: "Task #1", "Task #2", etc.
  • Descrição: "Description Task #1", "Description Task #2", etc.
  • Status: Alternado entre completo/incompleto
  • Usuário: Associada aos usuários de exemplo

🔧 Scripts Disponíveis

🏃‍♂️ Desenvolvimento

npm run dev          # Inicia o servidor em modo desenvolvimento (watch)
npm run build        # Compila o projeto para produção (usando TSUP)
npm run start        # Inicia o servidor compilado

🗃 Database

npm run db:generate      # Gera migrações baseadas no schema
npm run db:migrate       # Aplica migrações pendentes
npm run db:studio        # Abre o Drizzle Studio (GUI do banco)
npm run db:seed          # Popula o banco com dados de exemplo

🐳 Environment

npm run environment:up   # Sobe ambiente completo (DB + migrations + seed)
npm run environment:down # Derruba o ambiente Docker

🧪 Testes

npm run test         # Executa todos os testes
npm run test:ui      # Interface gráfica dos testes
npm run test:watch   # Executa testes em modo watch
npm run test:coverage # Gera relatório de cobertura

🎨 Qualidade de Código

npm run lint         # Executa o linter
npm run lint:fix     # Corrige problemas de lint automaticamente
npm run format       # Verifica formatação
npm run format:fix   # Formata o código
npm run check        # Executa lint + format
npm run check:fix    # Corrige lint + format

📚 Documentação da API

🌐 Base URL

http://localhost:3000

📖 Documentação Interativa

  • Scalar API Reference: http://localhost:3000/docs
  • Swagger JSON: http://localhost:3000/documentation/json

A documentação é gerada automaticamente usando OpenAPI 3.0 com schemas Zod integrados!

🏥 Health Check

GET /health/check

Verifica se a API está funcionando.

Response:

{
  "status": "ok",
  "timestamp": "2024-01-01T00:00:00.000Z"
}

Authentication Endpoints

POST /auth/signup

Registra um novo usuário no sistema.

Body:

{
  "name": "João Silva",
  "email": "[email protected]",
  "password": "123456",
  "passwordConfirmation": "123456"
}

Response (201):

{
  "id": "01HZ1234567890ABCDEFGHIJKL",
  "name": "João Silva",
  "email": "[email protected]"
}

POST /auth/login

Autentica um usuário e retorna um token JWT.

Body:

{
  "email": "[email protected]",
  "password": "123456"
}

Response (200):

Status: 200 OK
Set-Cookie: token=<JWT_TOKEN>; HttpOnly; Secure; SameSite=Strict; Max-Age=7200

🔒 Nota: O token JWT é retornado como um cookie HTTP-only para maior segurança.

�📋 Tasks Endpoints (Protegidos - Requerem Autenticação)

GET /tasks

Lista todas as tarefas do usuário autenticado com paginação e filtros opcionais.

Headers:

Cookie: token=<JWT_TOKEN>

Query Parameters:

  • title (string, opcional): Filtro por título
  • description (string, opcional): Filtro por descrição
  • page (number, opcional): Página atual (padrão: 1)
  • itemsPerPage (number, opcional): Items por página (padrão: 10)

Response:

{
  "data": [
    {
      "id": "01HZ1234567890ABCDEFGHIJKL",
      "title": "Minha tarefa",
      "description": "Descrição da tarefa",
      "completedAt": null
    }
  ]
}

POST /tasks

Cria uma nova tarefa para o usuário autenticado.

Headers:

Cookie: token=<JWT_TOKEN>

Body:

{
  "title": "Nova tarefa",
  "description": "Descrição da nova tarefa"
}

Response (201):

{
  "id": "01HZ1234567890ABCDEFGHIJKL",
  "title": "Nova tarefa",
  "description": "Descrição da nova tarefa",
  "completedAt": null
}

GET /tasks/:id

Busca uma tarefa específica do usuário autenticado pelo ID.

Headers:

Cookie: token=<JWT_TOKEN>

Response (200):

{
  "id": "01HZ1234567890ABCDEFGHIJKL",
  "title": "Minha tarefa",
  "description": "Descrição da tarefa",
  "completedAt": null
}

Response (404):

{
  "error": "Task not found"
}

Response (401):

Status: 401 Unauthorized

PUT /tasks/:id

Atualiza uma tarefa existente do usuário autenticado.

Headers:

Cookie: token=<JWT_TOKEN>

Body:

{
  "title": "Título atualizado",
  "description": "Descrição atualizada"
}

Response (204): (No Content)

PATCH /tasks/:id

Marca uma tarefa do usuário autenticado como completada.

Headers:

Cookie: token=<JWT_TOKEN>

Response (204): (No Content)

DELETE /tasks/:id

Remove uma tarefa do usuário autenticado.

Headers:

Cookie: token=<JWT_TOKEN>

Response (200):

{
  "id": "01HZ1234567890ABCDEFGHIJKL",
  "title": "Tarefa removida",
  "description": "Descrição da tarefa removida",
  "completedAt": null
}

📊 Códigos de Status HTTP

  • 200 - OK (sucesso)
  • 201 - Created (recurso criado)
  • 204 - No Content (sucesso sem conteúdo)
  • 400 - Bad Request (dados inválidos)
  • 401 - Unauthorized (não autenticado)
  • 404 - Not Found (recurso não encontrado)
  • 422 - Unprocessable Entity (validação falhou)
  • 500 - Internal Server Error (erro interno)

🔐 Sistema de Autenticação

A API utiliza JWT (JSON Web Tokens) para autenticação com as seguintes características:

  • 🍪 Cookies HTTP-only: Tokens armazenados em cookies seguros
  • ⏰ Expiração: Tokens válidos por 2 horas
  • 🔒 Proteção: Rotas de tarefas protegidas por middleware de autenticação
  • 🛡️ Segurança: Cookies com flags HttpOnly, Secure e SameSite=Strict

Fluxo de Autenticação:

  1. Usuário faz login via POST /auth/login
  2. API retorna token JWT como cookie HTTP-only
  3. Cliente envia cookie automaticamente nas próximas requisições
  4. Middleware verifica e decodifica o token
  5. Usuário autenticado pode acessar rotas protegidas

🧪 Testes

O projeto possui uma suite de testes abrangente usando Vitest:

🎯 Tipos de Testes

  • Unit Tests: Testam componentes isolados (use cases, services)
  • Authentication Tests: Testam fluxos de login, signup e validação de tokens
  • Authorization Tests: Testam middleware de autenticação e controle de acesso
  • Integration Tests: Testam a integração entre camadas
  • Repository Tests: Testam implementações in-memory e database

📊 Cobertura de Testes

npm run test:coverage

Os relatórios são gerados em coverage/index.html e podem ser visualizados no navegador.

🔧 Configuração de Testes

  • In-memory repositories: Testes isolados sem dependência do PostgreSQL
  • Mock services: Hash e token services mockados para testes determinísticos
  • Factory pattern: Factories separadas para testes (InMemoryUseCaseFactory)
  • Setup automático: Configuração automática do ambiente de teste (vitest.setup.ts)
  • Path mapping: Suporte a imports absolutos com @/ nos testes
  • Coverage exclusions: Arquivos de configuração e interfaces excluídos da cobertura
  • Authentication mocking: Simulação de contexto de usuário autenticado nos testes

🎨 Boas Práticas

Code Quality

  • TypeScript Strict Mode: Tipagem rigorosa em todo o projeto
  • Biome Linting: Linter e formatter ultra-rápido (substitui ESLint + Prettier)
  • Conventional Commits: Commits padronizados e semânticos
  • Path Mapping: Imports absolutos com @/ para melhor organização
  • Schema-First Design: Validação de dados com schemas Zod tipados

🛡 Security

  • Input Validation: Validação rigorosa com Zod e schemas tipados
  • SQL Injection Protection: ORM type-safe (Drizzle) com queries preparadas
  • CORS Configuration: Configuração adequada para diferentes ambientes
  • UUIDv7 Validation: Validação específica de IDs usando UUIDv7
  • Error Handling: Tratamento adequado de erros sem vazamento de informações

🚀 Performance

  • Connection Pooling: Pool de conexões nativo do PostgreSQL
  • Query Optimization: Queries otimizadas com Drizzle ORM
  • Pagination: Paginação eficiente com LIMIT/OFFSET
  • UUIDv7: IDs ordenáveis por timestamp para melhor performance de consultas
  • Fastify Framework: Framework web de alta performance para Node.js
  • Build Optimization: Build otimizado com TSUP para produção

📚 Documentation

  • OpenAPI 3.0: Documentação automática gerada pelos schemas Zod
  • Scalar UI: Interface moderna e interativa para testar a API
  • JSDoc Comments: Comentários estruturados em pontos críticos
  • Type Definitions: Tipos bem definidos e documentados
  • Schema Descriptions: Descrições detalhadas em todos os campos da API
  • README Detalhado: Documentação completa do projeto

🐛 Debug e Monitoramento

🔍 Ferramentas de Debug

  1. Drizzle Studio: Interface visual do banco de dados
npm run db:studio
  1. Vitest UI: Interface gráfica dos testes
npm run test:ui
  1. Scalar API Documentation: Documentação interativa da API
# Acesse: http://localhost:3000/docs
  1. Logs Estruturados: Sistema de logs do Fastify com queries SQL visíveis

📊 Monitoramento

  • Health Check Endpoint: Verificação básica de saúde da API (/health/check)
  • Database Connection: Verificação da conectividade com o banco via Drizzle
  • OpenAPI Documentation: Documentação completa e testável da API
  • Query Logging: Logs detalhados das queries SQL executadas
  • CORS Configuration: Configuração flexível para desenvolvimento e produção

🚀 Recursos Extras

🎯 Features Implementadas

  • Sistema de Autenticação Completo: JWT com cookies HTTP-only seguros
  • Gerenciamento de Usuários: Registro, login e autenticação
  • Controle de Acesso: Middleware de autenticação para rotas protegidas
  • Relacionamento de Dados: Tarefas associadas a usuários específicos
  • Documentação Interativa: Interface Scalar para testar todos os endpoints
  • Dual Persistence: Suporte a banco PostgreSQL e repositório em memória
  • Data Seeding: Sistema automático de população com usuários e tarefas
  • Environment Scripts: Scripts para gerenciar todo o ambiente de desenvolvimento
  • Comprehensive Testing: Testes unitários para todos os use cases e auth
  • Type Safety: Validação completa com Zod e tipagem TypeScript
  • Modern Tooling: Biome para linting/formatting, Vitest para testes
  • Production Ready: Build otimizado com TSUP e configurações de produção
  • Security First: Hash de senhas com bcrypt, tokens JWT seguros

🎮 Comandos Úteis

# Setup completo do ambiente
npm run environment:up

# Testar a API rapidamente
curl http://localhost:3000/health/check

# Registrar um novo usuário
curl -X POST http://localhost:3000/auth/signup \
  -H "Content-Type: application/json" \
  -d '{"name":"Test User","email":"[email protected]","password":"123456","passwordConfirmation":"123456"}'

# Fazer login (salva cookie automaticamente)
curl -X POST http://localhost:3000/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]","password":"123456"}' \
  -c cookies.txt

# Listar tarefas (usando cookie salvo)
curl http://localhost:3000/tasks -b cookies.txt

# Ver dados no banco
npm run db:studio

# Executar testes com interface
npm run test:ui

# Ver documentação interativa
# Abra: http://localhost:3000/docs

🤝 Contribuição

Contribuições são sempre bem-vindas!

  1. Faça um fork do projeto
  2. Crie uma branch para sua feature (git checkout -b feature/amazing-feature)
  3. Commit suas mudanças (git commit -m 'Add some amazing feature')
  4. Push para a branch (git push origin feature/amazing-feature)
  5. Abra um Pull Request

📝 Licença

Este projeto está sob a licença ISC. Veja o arquivo LICENSE para mais detalhes.


Feito com ❤️ e muito ☕ por desenvolvedores apaixonados por código limpo!

🚀 Happy Coding! 🚀

About

REST API to manage tasks

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages