Sistema de gerenciamento de tarefas com arquitetura de microsserviços, notificações em tempo real via WebSocket e interface moderna em React.
- Visão Geral
- Arquitetura
- Tecnologias Utilizadas
- Decisões Técnicas e Trade-offs
- Funcionalidades
- Pré-requisitos
- Instalação e Execução
- Estrutura do Projeto
- Testes
- Problemas Conhecidos e Melhorias Futuras
- Tempo de Desenvolvimento
Sistema de gerenciamento de tarefas com suporte a múltiplos usuários, colaboração em tempo real, histórico de alterações e sistema de notificações. Construído com arquitetura de microsserviços.
- Autenticação JWT com tokens de acesso e refresh
- CRUD completo de tarefas com filtros e paginação
- Sistema de comentários e histórico de alterações
- Notificações em tempo real via WebSocket
- Atribuição de tarefas a múltiplos usuários
- Interface responsiva
- Logs centralizados com Winston
- Testes unitários e E2E
O sistema utiliza arquitetura de microsserviços com comunicação via RabbitMQ e REST API.
Abra a imagem em outra aba para ver melhor os detalhes.
Veja o vídeo de demonstração na pasta assets para ter uma visão do sistema funcionando em tempo real com dois usuários ativos.
-
Frontend (React + Vite)
- Interface do usuário
- Cache das requisições com TanStack Query
- Roteamento de páginas com TanStack Router
- WebSocket para notificações em tempo real
-
API Gateway (NestJS)
- Ponto único de entrada
- Proxy para microsserviços
- Gateway WebSocket para notificações
- Autenticação JWT
-
Auth Service (NestJS)
- Gerenciamento de usuários
- Autenticação e autorização
- Geração de tokens JWT (RS256)
-
Tasks Service (NestJS)
- CRUD de tarefas
- Comentários
- Histórico de alterações
- Estatísticas
-
Notifications Service (NestJS)
- Criação e gerenciamento de notificações
- Processamento de eventos (task.created, task.updated, etc.)
-
RabbitMQ
- Message broker para comunicação assíncrona
- Filas dedicadas por serviço
-
PostgreSQL
- Banco de dados relacional
- Esquema único compartilhado
- NestJS - Framework Node.js
- TypeScript - Linguagem tipada
- TypeORM - ORM para o banco PostgreSQL
- RabbitMQ - Message broker
- Socket io - WebSocket
- JWT (RS256) - Autenticação
- Winston- Logging
- Vitest - Testes
- React 19 - UI Library
- TypeScript - Linguagem tipada
- Vite - Ferramenta de build
- TanStack Query - Cache de requisições
- TanStack Router - Roteamento
- Tailwind CSS - Estilização
- Shadcn/ui - Componentes visuais
- Socket io Client - WebSocket
- React Hook Form + Zod - Validação de formulários
- Vitest - Testes
- Docker & Docker Compose - Containerização
- Yarn Workspaces com Turborepo - Monorepo
Decisão: Separar o sistema em microsserviços independentes (Auth, Tasks, Notifications).
Justificativa:
- Escalabilidade independente de cada serviço
- Separação de responsabilidades clara
Trade-offs:
- Maior complexidade operacional
- Necessidade de message broker
- Maior latência na comunicação entre serviços
Decisão: Utilizar RabbitMQ para comunicação assíncrona entre microsserviços.
Justificativa:
- Desacoplamento entre serviços
- Garantia de entrega de mensagens
Trade-offs:
- Dependência adicional (RabbitMQ)
- Complexidade no gerenciamento de filas
- Curva de aprendizado
Decisão: Usar RS256 ao invés de HS256 para assinatura de tokens.
Justificativa:
- Maior segurança (chave privada apenas no Auth Service)
- Validação de tokens sem comunicação com Auth Service
- Padrão recomendado para microsserviços
Trade-offs:
- Performance levemente inferior ao HS256
- Gerenciamento de chaves públicas e privadas
Decisão: Usar banco de dados compartilhado com esquema único ao invés de bancos separados.
Justificativa:
- Simplicidade operacional para projeto de demonstração localhost
- Facilita backup e recovery
Trade-offs:
- Acoplamento no nível de dados
- Dificuldade para escalar serviços independentemente
- Não é tão ideal para produção em larga escala
Decisão: Implementar notificações em tempo real via WebSocket.
Justificativa:
- Experiência do usuário melhorada (notificações instantâneas)
- Reduzir requisições http desnecessárias
Trade-offs:
- Complexidade adicional no backend e frontend
- Gerenciamento de conexões persistentes
Decisão: Usar TanStack Query para cache de requisições http.
Justificativa:
- Gerenciamento automático de cache
- Revalidação inteligente
- Otimizado para requisições assíncronas
Trade-offs:
- Dependência de biblioteca externa
- Curva de aprendizado inicial
Decisão: Estruturar o projeto como monorepo.
Justificativa:
- Compartilhamento de código (logger package)
- Versionamento unificado
- Desenvolvimento sincronizado
Trade-offs:
- Builds mais lentos
- Gerenciamento de dependências mais complexo
- Tamanho do repositório
Decisão: Usar Vitest para testes.
Justificativa:
- Melhor integração com Vite
- Performance superior
- API compatível com Jest
Trade-offs:
- Algumas libs podem ter problemas de compatibilidade
- Registro de usuários
- Login com JWT
- Refresh token automático
- Logout
- Proteção de rotas
- Criar, editar, deletar tarefas
- Listar tarefas com paginação
- Filtros (status, prioridade, busca)
- Atribuir tarefas a múltiplos usuários
- Definir prazo, prioridade e status
- Visualização detalhada de tarefa
- Adicionar comentários em tarefas
- Listar comentários com paginação
- Identificação do autor do comentário
- Registro automático de alterações
- Visualização de histórico por tarefa
- Tracking de mudanças de status, prioridade, etc.
- Notificações em tempo real
- Notificação de atribuição de tarefa
- Notificação de mudança de status
- Notificação de novo comentário
- Marcar como lida
- Marcar todas como lidas
- Contador de não lidas
- Design responsiva
- Componentes acessíveis (Shadcn/ui)
- Loading states
- Error handling
- Notificações Toast
- Node.js 20.x ou superior
- Yarn 1.22.x ou superior
- Docker e Docker Compose (para desenvolvimento com containers)
- PostgreSQL 16.x (se rodar sem Docker)
- Dbeaver ou outra ferramenta semelhante (para se conectar e visualizar as tabelas do banco sem Docker)
- Clone o repositório
git clone
cd VitorHugoAntunes-Desafio-Full-stack-Junior-main- Configure as variáveis de ambiente
Já pré configurado, os arquivos .env.example estão preenchidos com valores padrão para acelerar o processo, mas você pode alterar os valores como desejar.
- chaves JWT (RSA)
Também já estão disponibilizadas nos arquivos de variáveis ambientes. Como este projeto não está deployado em nenhuma nuvem e rodará apenas localmente, não tem problema cada git clone compartilhar as mesmas chaves privadas e públicas, mas caso deseje gerar suas próprias chaves, siga as instruções:
openssl genrsa -out private_key.pem 2048
openssl rsa -in private_key.pem -pubout -out public_key.pem
# Converter para base64 (necessário para .env)
[Convert]::ToBase64String([IO.File]::ReadAllBytes("private_key.pem")) > private_key_base64.txt
[Convert]::ToBase64String([IO.File]::ReadAllBytes("public_key.pem")) > public_key_base64.txtLembrando que estes comandos são para ambiente Windows com powershell, para Linux e MacOS muda de acordo com seu sistema.
- Configure as variáveis de ambiente
Adicione as chaves base64 nos arquivos .env:
JWT_PRIVATE_KEY=<base64-private-key>JWT_PUBLIC_KEY=<base64-public-key>
- Suba os containers
docker-compose build --no-cache
docker-compose up -d- Execute as migrations
As migrations já foram geradas, basta rodar o comando de run para aplicar ao seu banco no docker.
yarn install
yarn migration:run- Acesse a aplicação
- Frontend: http://localhost:5173
- API Gateway: http://localhost:3333
- Swagger Docs: http://localhost:3333/api/docs
- Health checks: http://localhost:3333/health
- Auth Service: Port 3334
- Tasks Service: Port 3335
- Notifications Service: Port 3336
- PostgreSQL: postgresql://postgres:docker@localhost:5432/app_database
- RabbitMQ: amqp://admin:admin@localhost:5672
- RabbitMQ Manegement UI: http://localhost:15672/ (usuário admin e senha admin)
- Instale as dependências
yarn install
cd packages/logger
yarn dev OU yarn build- Configure PostgreSQL e RabbitMQ
yarn docker:devEste comando vai subir no docker uma instância Postgres e outra RabbitMQ para desenvolvimento.
-
Configure as variáveis de ambiente (igual aos passos da Opção 1)
-
Execute os serviços Na raiz do monorepo:
yarn migration:run
yarn devPara popular o banco com dados de exemplo:
# Local
# Na raiz do monorepo
yarn db:seed
# Caso deseje limpar o banco
yarn db:clearCredenciais de teste:
- Email:
alice@example.com| Senha:password123 - Email:
bruno@example.com| Senha:password123 - Email:
carlos@example.com| Senha:password123 - Email:
diana@example.com| Senha:password123 - Email:
eduardo@example.com| Senha:password123
VitorHugoAntunes-Desafio-Full-stack-Junior-main/
├── apps/
│ ├── api-gateway/ # Gateway e proxy para microsserviços
│ ├── auth-service/ # Serviço de autenticação
│ ├── tasks-service/ # Serviço de tarefas
│ ├── notifications-service/# Serviço de notificações
│ └── web/ # Frontend React
├── packages/
│ ├── logger/ # Logger compartilhado (Winston)
│ └── typescript-config/ # Configurações TypeScript
├── docker-compose.yml # containers
├── package.json
└── README.md
Existem outros arquivos que você pode alterar conforme seu desejo, como o turbo.json com configurações do monorepo e os o arquivo client.http dentro de apps/api-gateway semelhante às collections do Postman para testar os endpoints sem necessidade de uma interface.
service/
├── src/
│ ├── modules/
│ │ ├── service/
│ │ │ ├── controllers/
│ │ │ ├── services/
│ │ │ ├── entities/
│ │ │ ├── repositories/
│ │ │ └── dtos/
│ ├── app.module.ts
│ └── main.ts # Entry point
├── test/ # Testes E2E
├── Dockerfile
└── package.json
É uma estrutura padrão que eu segui, mas cada microsserviço contém diferenças significativas, conforme o necessário para cada um funcionar, este guia é apenas de exemplo.
Lembre-se de executar yarn dev ou yarn build antes no packages/logger
# Todos os serviços
# na raiz do monorepo
yarn test
# Serviço específico
cd apps/auth-service
yarn test# Todos os servicos
# na raiz do monorepo
yarn test:e2e
# API Gateway
cd apps/api-gateway
yarn test:e2e
# Serviço específico
cd apps/auth-service
yarn test:e2eO frontend também contém testes unitários.
- Banco de Dados Compartilhado
- Todos os microsserviços usam o mesmo banco PostgreSQL
- Impacto: Acoplamento no nível de dados
- Solução futura: Migrar para bancos separados por serviço
- Implementar busca full-text nas tarefas
- Adicionar upload de anexos em tarefas
- Adicionar testes de carga (k6)
- Implementar cache com Redis
- Adicionar observabilidade (Grafana)
- Implementar CI/CD completo (GitHub Actions)
- Adicionar serviço de analytics
- Deploy dos microsserviços e frontend
- Implementar HTTPS
- Adicionar proteção CSRF
- Otimizar bundle size do frontend
| Fase | Tempo Estimado | Descrição |
|---|---|---|
| Setup Inicial | 4h | Configuração do monorepo, Docker, estrutura base |
| Auth Service | 8h | Implementação completa de autenticação com JWT |
| Tasks Service | 10h | CRUD de tarefas, comentários, histórico |
| Notifications Service | 10h | Sistema de notificações e eventos |
| API Gateway | 6h | Proxy, WebSocket gateway, integração |
| Frontend - Base | 4h | Setup, autenticação, rotas protegidas |
| Frontend - Tarefas | 6h | CRUD, filtros, paginação, formulários |
| Frontend - Notificações | 6h | WebSocket, UI de notificações |
| Frontend - Incrementos | 4h | Responsividade, loading states, error handling |
| Testes | 8h | Testes unitários e E2E |
| DevOps | 6h | Docker Compose e scripts |
| Documentação | 4h | README e Swagger |
| Debug | 8h | Correção de bugs, refinamentos |
- NestJS Documentation
- React Documentation
- TanStack Query
- RabbitMQ Tutorials
- TypeORM Documentation
- Socket.io Documentation
- Tailwind CSS
- Turborepo
- Shadcn/ui
- Autenticação centralizada em microsserviços NestJS
- Tutorial de Microservices com Nest.js em 20 Minutos
- Stackoverflow
- Comunidade Nestjs
Contribuições são bem-vindas! Por favor:
- Fork o projeto
- Crie uma branch para sua feature (
git checkout -b feature/suaFeature) - Commit suas mudanças (
git commit -m 'Add some suaFeature') - Push para a branch (
git push origin feature/suaFeature) - Abra um Pull Request
Este projeto é licenciado - veja o arquivo LICENSE para detalhes.
