Aplicação fullstack de gerenciamento de tarefas com API REST, filtros, prioridades e interface React com dark mode.
- CRUD completo — criar, listar, buscar, editar e excluir tarefas
- Filtros de listagem — filtrar por status, buscar por texto e ordenar resultados
- Prioridade urgente — tarefas podem receber destaque visual sem poluir a interface
- Status da tarefa — marcar como concluída ou voltar para pendente
- Persistência real — dados armazenados em banco PostgreSQL
- API REST — endpoints organizados para consumo pelo frontend
- Interface React — tela para listar, criar, editar, concluir e excluir tarefas
- Validação de dados — campos obrigatórios, limites de tamanho, status permitido e filtros válidos
A aplicação possui uma tela principal com formulário de criação, lista de tarefas e ações rápidas para concluir, editar e excluir.
Fluxo principal:
- Criar uma tarefa pelo formulário.
- Visualizar a tarefa na lista.
- Marcar como concluída ou pendente.
- Editar título e descrição.
- Excluir tarefa.
| Frontend | Backend | Banco/DevOps |
|---|---|---|
| React 19 | Node.js | PostgreSQL 18 |
| Vite 7 | Express 5 | Docker Compose |
| CSS | CORS | pg |
| Lucide React | dotenv | Git |
- Node.js >= 20
- npm
- PostgreSQL instalado localmente ou Docker
git clone https://github.com/LuizGSN/TaskTrack.git
cd TaskTrackSe você já está com a pasta do projeto aberta, apenas siga para o próximo passo.
npm installCrie o arquivo .env a partir do exemplo:
copy server\.env.example server\.envConfigure a conexão com o PostgreSQL:
DATABASE_URL=postgres://postgres:sua_senha@localhost:5432/todo_desafio
PORT=3333Com PostgreSQL local:
CREATE DATABASE todo_desafio;Ou use Docker:
docker compose up -dnpm run db:migratenpm run devA aplicação estará disponível em:
- Frontend:
http://localhost:5173 - Backend:
http://localhost:3333
O projeto inclui um docker-compose.yml para subir o PostgreSQL com as credenciais padrão do .env.example.
docker compose up -d
npm run db:migrate
npm run devtodo-list-api/
├── .gitignore
├── docker-compose.yml
├── package.json
├── README.md
│
├── client/
│ ├── index.html
│ ├── package.json
│ └── src/
│ ├── api.js # Funções para consumir a API
│ ├── main.jsx # Aplicação React
│ └── styles.css # Estilos da interface
│
└── server/
├── .env.example # Variáveis de ambiente modelo
├── package.json
├── db/
│ ├── migrate.js # Script de migration
│ └── schema.sql # Criação da tabela tasks
└── src/
├── db.js # Pool PostgreSQL
├── server.js # Entry point + rotas da API
├── tasksRepository.js
└── validation.js # Validações de entrada
URL base local:
http://localhost:3333
| Método | Path | Descrição |
|---|---|---|
GET |
/health |
Verifica se a API está online |
Resposta:
{
"status": "ok"
}| Método | Path | Descrição |
|---|---|---|
GET |
/tasks |
Listar todas as tarefas |
GET |
/tasks/:id |
Buscar uma tarefa por ID |
POST |
/tasks |
Criar uma tarefa |
PUT |
/tasks/:id |
Atualizar uma tarefa completa |
PATCH |
/tasks/:id |
Atualizar parcialmente uma tarefa |
DELETE |
/tasks/:id |
Excluir uma tarefa |
O endpoint GET /tasks aceita filtros via query params:
| Parâmetro | Valores | Descrição |
|---|---|---|
status |
pending, completed |
Filtra tarefas por status |
priority |
normal, urgent |
Filtra tarefas por prioridade |
search |
texto com até 80 caracteres | Busca no título e na descrição |
sort |
createdAt, updatedAt, title, status, priority |
Campo usado na ordenação |
order |
asc, desc |
Direção da ordenação |
Exemplo:
curl "http://localhost:3333/tasks?status=pending&priority=urgent&search=readme&sort=title&order=asc"{
"id": 1,
"title": "Estudar Express",
"description": "Criar endpoints REST",
"status": "pending",
"priority": "urgent",
"createdAt": "2026-05-13T19:13:14.140Z",
"updatedAt": "2026-05-13T19:13:14.140Z"
}Status aceitos:
pending— tarefa pendentecompleted— tarefa concluída
Prioridades aceitas:
normal— tarefa comumurgent— tarefa urgente com destaque visual
| Campo | Regra |
|---|---|
title |
Obrigatório, texto e no máximo 120 caracteres |
description |
Opcional, texto e no máximo 500 caracteres |
status |
Opcional, apenas pending ou completed |
priority |
Opcional, apenas normal ou urgent |
Campos não previstos no corpo da requisição são rejeitados.
iddeve ser um número inteiro positivo.statusdeve serpendingoucompleted.prioritydeve sernormalouurgent.searchdeve ter no máximo 80 caracteres.sortdeve sercreatedAt,updatedAt,title,statusoupriority.orderdeve serascoudesc.
curl -X POST http://localhost:3333/tasks \
-H "Content-Type: application/json" \
-d "{\"title\":\"Estudar Express\",\"description\":\"Criar endpoints REST\",\"status\":\"pending\",\"priority\":\"urgent\"}"Resposta:
{
"id": 1,
"title": "Estudar Express",
"description": "Criar endpoints REST",
"status": "pending",
"priority": "urgent",
"createdAt": "2026-05-13T19:13:14.140Z",
"updatedAt": "2026-05-13T19:13:14.140Z"
}curl http://localhost:3333/tasksCom filtros:
curl "http://localhost:3333/tasks?status=completed&priority=urgent&sort=updatedAt&order=desc"Resposta:
[
{
"id": 1,
"title": "Estudar Express",
"description": "Criar endpoints REST",
"status": "pending",
"priority": "urgent",
"createdAt": "2026-05-13T19:13:14.140Z",
"updatedAt": "2026-05-13T19:13:14.140Z"
}
]curl http://localhost:3333/tasks/1curl -X PUT http://localhost:3333/tasks/1 \
-H "Content-Type: application/json" \
-d "{\"title\":\"Estudar React\",\"description\":\"Consumir a API no frontend\",\"status\":\"completed\",\"priority\":\"normal\"}"curl -X PATCH http://localhost:3333/tasks/1 \
-H "Content-Type: application/json" \
-d "{\"status\":\"completed\"}"curl -X PATCH http://localhost:3333/tasks/1 \
-H "Content-Type: application/json" \
-d "{\"priority\":\"urgent\"}"curl -X DELETE http://localhost:3333/tasks/1Resposta:
204 No ContentFormato padrão:
{
"errors": ["Mensagem do erro."]
}| Código | Quando acontece |
|---|---|
400 Bad Request |
Dados inválidos, ID inválido, status inválido ou prioridade inválida |
404 Not Found |
Tarefa não encontrada |
500 Internal Server Error |
Erro inesperado no servidor |
Exemplo:
{
"errors": ["O título é obrigatório."]
}Sugestão de deploy:
- Crie um serviço web apontando para a pasta
server/. - Configure a variável
DATABASE_URLcom a string de conexão do PostgreSQL. - Configure
PORTconforme a plataforma, se necessário. - Rode a migration no ambiente de produção.
- Crie o projeto apontando para a pasta
client/. - Configure a variável
VITE_API_URLcom a URL pública do backend. - Faça o deploy.
Este projeto foi desenvolvido para fins de desafio técnico.
Desenvolvido por Luiz Gonzaga — Estudante de Análise e Desenvolvimento de Sistemas