Sistema completo de gestão de tarefas com quadro Kanban, autenticação JWT, upload de arquivos e arquitetura limpa.
App: https://everlabs-fullstack.vercel.app API: https://everlabs-fullstack.onrender.com/api-docs
Login de demonstração:
Email: admin@demo.com
Senha: demo12345
⚠️ Hospedado em planos gratuitos: a API "dorme" após 15 min de inatividade — a primeira requisição pode levar 30–50s para acordar. Arquivos anexados em tarefas não persistem entre deploys (disco efêmero do free tier).
Aplicação fullstack de gerenciamento de tarefas no estilo Kanban/SCRUM. O projeto foi construído com foco em boas práticas de engenharia: Clean Architecture, SOLID, injeção de dependências e testes unitários — tanto no backend quanto no frontend.
O backend expõe uma API RESTful documentada com Swagger, e o frontend consome essa API com gerenciamento de estado via Redux Toolkit. Todo o ambiente roda com um único comando via Docker Compose.
- Login e logout com JWT
- Dois perfis de acesso: Admin e User
- Middleware de autorização baseado em roles
- CRUD completo de tarefas
- Atribuição de responsáveis, prioridade (0–10) e datas
- Sistema de tags/etiquetas
- Upload de arquivos anexos
- Drag-and-drop nativo (sem dependência externa) entre colunas
- Status:
TODO→IN_PROGRESS→REVIEW→DONE - Comentários e ocorrências por tarefa
| Ação | Admin | User |
|---|---|---|
| Criar/editar/excluir tarefas | ✅ | ❌ |
| Atualizar status | ✅ | ✅ (próprias) |
| Adicionar comentários | ✅ | ✅ (próprias) |
| Upload de arquivos | ✅ | ✅ (próprias) |
| Tecnologia | Uso |
|---|---|
| Node.js + Express | Runtime e framework HTTP |
| TypeScript | Tipagem estática em todo o projeto |
| Prisma ORM | Acesso ao banco de dados com type-safety |
| PostgreSQL | Banco de dados relacional |
| JWT | Autenticação stateless |
| Zod | Validação de schemas na camada HTTP |
| TSyringe | Injeção de dependências (IoC container) |
| Vitest | Testes unitários |
| Swagger/OpenAPI | Documentação interativa da API |
| Tecnologia | Uso |
|---|---|
| React 18 | Biblioteca de interface |
| TypeScript | Tipagem de componentes, hooks e store |
| Redux Toolkit | Gerenciamento de estado global |
| Vite | Build tool e dev server |
| CSS Modules | Estilização com escopo local |
| Tecnologia | Uso |
|---|---|
| Docker + Docker Compose | Containerização de backend e frontend |
| Nginx | Serve o build do React em produção |
O backend segue Clean Architecture, separando regras de negócio de detalhes de infraestrutura:
backend/src/
├── domain/ # Núcleo da aplicação — sem dependências externas
│ ├── entities/ # Interfaces e tipos de domínio
│ ├── repositories/ # Contratos (interfaces) de acesso a dados
│ ├── providers/ # Contratos de serviços externos
│ └── useCases/ # Casos de uso: lógica de negócio pura
│
├── infra/ # Implementações concretas
│ ├── database/ # Repositórios Prisma (implementam domain/repositories)
│ ├── http/ # Controllers, rotas, middlewares
│ └── providers/ # Serviços: upload de arquivos, hash, etc.
│
└── shared/
├── container/ # Registro de dependências (TSyringe)
└── errors/ # Classes de erro padronizadas
Esse modelo permite, por exemplo, trocar o banco de dados (feito com PostgreSQL) apenas substituindo a implementação do repositório, sem tocar nos casos de uso.
git clone https://github.com/Dieguin77/everlabs-fullstack.git
cd everlabs-fullstack
docker-compose up --build| Serviço | URL |
|---|---|
| Frontend | http://localhost:5173 |
| Backend API | http://localhost:3333 |
| Swagger Docs | http://localhost:3333/api-docs |
Requer um PostgreSQL rodando (local, Docker avulso, ou uma instância gratuita no Supabase/Neon).
Backend:
cd backend
npm install
cp .env.example .env # ajuste DATABASE_URL para seu Postgres
npx prisma migrate dev
npx prisma db seed # cria o usuário admin@demo.com / demo12345
npm run devFrontend:
cd frontend
npm install
cp .env.example .env
npm run dev| Método | Rota | Descrição |
|---|---|---|
POST |
/api/users |
Criar usuário |
POST |
/api/users/authenticate |
Login (retorna JWT) |
GET |
/api/users/me |
Perfil autenticado |
GET |
/api/tasks |
Listar tarefas |
POST |
/api/tasks |
Criar tarefa (Admin) |
PATCH |
/api/tasks/:id/status |
Atualizar status |
POST |
/api/tasks/:id/comments |
Adicionar comentário |
POST |
/api/files/tasks/:id |
Upload de arquivo |
GET |
/api/tags |
Listar tags |
Todas as rotas protegidas exigem o header:
Authorization: Bearer <token>
A documentação completa e interativa está disponível no Swagger em http://localhost:3333/api-docs.
cd backend
# Rodar todos os testes
npm test
# Com relatório de cobertura
npm run test:coverage
# Modo watch
npm run test:watchBackend (backend/.env):
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/everlabs?schema=public"
JWT_SECRET="sua-chave-secreta"
JWT_EXPIRES_IN="7d"
PORT=3333Frontend (frontend/.env):
VITE_API_URL=http://localhost:3333/apiO jeito mais simples é rodar o seed, que cria admin@demo.com / demo12345:
cd backend
npx prisma db seedOu criar um usuário próprio via API:
curl -X POST http://localhost:3333/api/users \
-H "Content-Type: application/json" \
-d '{
"name": "Admin",
"email": "admin@exemplo.com",
"password": "123456",
"role": "ADMIN"
}'Clean Architecture — A separação entre domain e infra mantém os casos de uso independentes de banco de dados, framework e qualquer detalhe externo. Isso facilita testes e evolução do sistema.
TSyringe (IoC Container) — A inversão de controle permite injetar implementações concretas nos casos de uso sem acoplamento. Trocar a implementação de um repositório ou provider não exige alterar nenhuma regra de negócio.
Redux Toolkit — Escolhido pela previsibilidade e ferramentas de debug (Redux DevTools). Para o volume de estado desse projeto, o RTK Query simplificou o cache das requisições.
Drag-and-drop nativo — Implementado com a API HTML5 Drag and Drop, sem bibliotecas externas. Reduz bundle size e dá controle total sobre o comportamento.
PostgreSQL — Usado tanto localmente (via Docker Compose) quanto em produção, para manter paridade entre ambientes. A Clean Architecture torna a troca de banco (ex.: MySQL) uma mudança isolada na camada de repositório.
Desenvolvido por Diego Batista