Esta aplicação foi propositalmente construída com problemas, bugs e oportunidades de melhoria que você deve identificar, analisar e corrigir. Seu objetivo é:
- 🔍 EXPLORAR o código e identificar problemas
- 🐛 ENCONTRAR bugs e falhas de segurança
- ⚡ OTIMIZAR performance e consultas ao banco
- 🧪 CORRIGIR testes quebrados
- 🎨 MELHORAR a experiência do usuário
- 📦 CONFIGURAR adequadamente o Docker
⚠️ ATENÇÃO: Nem tudo está funcionando corretamente! Isso é intencional.
Esta é uma aplicação full-stack de blog construída com Node.js, TypeScript, React, PostgreSQL, Docker e AWS S3. A aplicação contém tanto funcionalidades operacionais quanto elementos intencionalmente quebrados para fins de avaliação técnica.
- Framework: Express.js com TypeScript
- Database: PostgreSQL com Sequelize ORM
- Autenticação: JWT tokens
- Storage: AWS S3
- Containerização: Docker
- Framework: React com TypeScript
- Estilização: Styled Components com Design System
- Gerenciamento de Estado: Custom hooks com React Context
- Roteamento: React Router
- Formulários: React Hook Form
- Registro e login de usuários
- Autenticação baseada em JWT tokens
- Rotas protegidas
- CRUD completo de posts
- Conteúdo em markdown
- Upload de imagens para S3
- Tags e categorias
- Contador de visualizações
- Comentários aninhados (respostas)
- Moderação de comentários
- Atualizações em tempo real
- Like/unlike em posts
- Exibição de contador de likes
- Upload de imagens para AWS S3
- Validação de tipos de arquivo
- Restrições de tamanho
❌ PROBLEMA: Queries N+1 causando lentidão extrema
- Localização:
backend/src/controllers/postController.ts
- Sintomas: Para cada post, faz consultas separadas para likes e comentários
- Impacto: 50 posts = 150+ queries desnecessárias
- Sua missão: Implementar eager loading com Sequelize
❌ PROBLEMA: Testes falhando propositalmente
- Localização:
backend/src/tests/auth.test.ts
frontend/src/App.test.tsx
- Sintomas:
npm test
falha em múltiplos casos - Sua missão: Identificar e corrigir assertions incorretas
❌ PROBLEMA: Interface com problemas de usabilidade
- Localização:
frontend/src/components/
efrontend/src/styles/
- Sintomas: Hover states não funcionam, design não responsivo
- Sua missão: Melhorar a experiência do usuário
❌ PROBLEMA: Docker mal configurado
- Localização:
docker-compose.yml
- Sintomas: Senhas em texto plano, sem health checks
- Sua missão: Implementar best practices de segurança
❌ PROBLEMA: Vulnerabilidades de segurança
- Localização: Vários arquivos do backend
- Sintomas: Validações insuficientes, exposição de dados
- Sua missão: Implementar validações robustas
- Node.js (v18+)
- PostgreSQL
- Docker & Docker Compose
- Credenciais AWS S3 (veja instruções abaixo)
Opção 1: AWS Free Tier (Recomendado)
-
Crie uma conta AWS gratuita:
- Acesse aws.amazon.com
- Clique em "Create an AWS Account"
- Complete o cadastro (precisa de cartão, mas não será cobrado no free tier)
-
Obtenha as credenciais:
- Acesse AWS Console → IAM
- Crie um novo usuário para este projeto
- Anexe a política
AmazonS3FullAccess
- Gere as
Access Keys
(salve com segurança!)
-
Crie um bucket S3:
- Acesse S3 no console AWS
- Crie um bucket (nome único globalmente)
- Configure permissões públicas para leitura de imagens
-
Free Tier S3 inclui:
- 5 GB de armazenamento
- 20.000 requests GET
- 2.000 requests PUT
- Suficiente para desenvolvimento!
🚫 Opção 2: SEM AWS - Alternativas Locais
Se não conseguir/quiser usar AWS, você pode simular:
A) Upload Local (Mais Simples)
// Modifique o uploadController.ts para salvar localmente:
const filePath = `./uploads/${filename}`;
fs.writeFileSync(filePath, buffer);
// Retorne URL local: http://localhost:3001/uploads/filename
B) Usar Serviço Gratuito Alternativo
- Cloudinary (gratuito até 25 créditos/mês)
- ImageKit (gratuito até 20GB bandwidth/mês)
- Supabase Storage (gratuito até 1GB)
C) Mock/Fake AWS S3
// No uploadController.ts, apenas simule o upload:
export const uploadImage = (req, res) => {
// Fake successful upload
const fakeUrl = `https://fake-s3-bucket.com/images/${Date.now()}.jpg`;
res.json({ success: true, imageUrl: fakeUrl });
};
Se usar AWS real:
# No arquivo backend/.env
AWS_ACCESS_KEY_ID=AKIA...sua-key-aqui
AWS_SECRET_ACCESS_KEY=sua-secret-key-aqui
AWS_S3_BUCKET=seu-bucket-name
AWS_REGION=us-east-1
Se usar alternativa local:
# No arquivo backend/.env
AWS_ACCESS_KEY_ID=fake-key-for-local-dev
AWS_SECRET_ACCESS_KEY=fake-secret-for-local-dev
AWS_S3_BUCKET=local-uploads
AWS_REGION=local
```
> **💡 DICA**: O foco do desafio NÃO é configurar AWS, e sim resolver os problemas de código! Use a alternativa que for mais rápida para você.
> **📖 ALTERNATIVA COMPLETA**: Se preferir upload local, consulte o arquivo `LOCAL_UPLOAD_GUIDE.md` para implementação detalhada.### 📝 **PASSO A PASSO PARA O DESAFIO:**
#### **Etapa 1: Setup Inicial** (5-10 min)
1. **Clone o repositório**
```bash
git clone <repository-url>
cd tech-challenge
- Configure as variáveis de ambiente
# Backend
cp backend/.env.example backend/.env
# Edite backend/.env com suas credenciais de database e AWS
# Frontend
cp frontend/.env.example frontend/.env.local
- Instale as dependências
# Root
npm install
# Backend
cd backend && npm install
# Frontend
cd frontend && npm install
- 🧪 Execute os testes e veja as falhas
# Backend - você deve ver testes falhando!
cd backend && npm test
# Frontend - também deve falhar!
cd frontend && npm test
- 🐳 Tente subir com Docker (vai ter problemas!)
docker-compose up -d
# Observe os problemas de configuração
- 🔍 Ou suba manualmente e explore
# Inicie o PostgreSQL
# Atualize as configurações de conexão em backend/.env
# Backend
cd backend && npm run dev
# Frontend (em outro terminal)
cd frontend && npm start
-
🕵️ Explore o código e identifique:
- Onde estão os problemas de performance?
- Quais testes estão quebrados e por quê?
- Onde a segurança está comprometida?
- Que problemas de UX existem?
-
🔧 Comece a corrigir:
- Priorize pelos problemas mais críticos
- Teste suas correções
- Documente as mudanças que fez
-
Performance Issues:
- Execute queries e observe quantas são feitas
- Use o Network tab do browser
- Monitore o console do banco de dados
-
Problemas de Teste:
- Leia as mensagens de erro cuidadosamente
- Verifique assertions que fazem sentido
- Execute testes individuais para isolar problemas
-
Problemas de Segurança:
- Procure por senhas em plain text
- Verifique validações de input
- Analise configurações de CORS e headers
-
Problemas de UX:
- Teste a interface em diferentes telas
- Verifique states de hover e foco
- Teste formulários e validações
# Verificar logs do Docker
docker-compose logs -f
# Executar testes específicos
npm test -- --testNamePattern="auth"
# Build de produção para ver warnings
npm run build
# Análise de bundle (se disponível)
npm run analyze
# ✅ ESTES COMANDOS DEVEM PASSAR APÓS SUAS CORREÇÕES:
# Backend tests (devem todos passar!)
cd backend && npm test
# Frontend tests (devem todos passar!)
cd frontend && npm test
# Build deve ser bem-sucedido
npm run build
# Docker deve subir sem problemas
docker-compose up -d --build
# Verificar saúde dos containers
docker-compose ps
# Build completo (deve funcionar sem erros)
npm run build
# Build apenas backend
npm run build:backend
# Build apenas frontend
npm run build:frontend
- Identificou TODOS os problemas críticos
- Corrigiu N+1 queries com eager loading
- Implementou security best practices
- Melhorou significativamente a UX
- Todos os testes passando
- Docker configurado corretamente
- Sugeriu melhorias adicionais de arquitetura
- Identificou a maioria dos problemas
- Corrigiu problemas de performance principais
- Corrigiu testes quebrados
- Melhorou configurações de segurança
- Interface funcional e responsiva
- Identificou alguns problemas óbvios
- Corrigiu pelo menos os testes
- Fez melhorias básicas na interface
- Demonstrou capacidade de debug
Durante o desafio, considere estas questões:
- Performance: Como você mediria o impacto das suas otimizações?
- Segurança: Que outras vulnerabilidades poderiam existir?
- Escalabilidade: Como esta aplicação se comportaria com 10k usuários?
- Monitoramento: Que métricas você implementaria em produção?
- Testing: Como melhorar a cobertura de testes?
NODE_ENV=development
PORT=3001
DB_HOST=localhost
DB_PORT=5432
DB_NAME=tech_challenge_blog
DB_USER=admin
DB_PASSWORD=password123
JWT_SECRET=your-super-secret-jwt-key
JWT_EXPIRES_IN=7d
AWS_ACCESS_KEY_ID=your-aws-access-key
AWS_SECRET_ACCESS_KEY=your-aws-secret-key
AWS_S3_BUCKET=your-s3-bucket-name
AWS_REGION=us-east-1
MAX_FILE_SIZE=5242880
REACT_APP_API_URL=http://localhost:3001/api
POST /api/auth/register
- User registrationPOST /api/auth/login
- User loginGET /api/auth/profile
- Get user profile (protected)PUT /api/auth/profile
- Update profile (protected)
GET /api/posts
- Get all posts (paginated)GET /api/posts/:id
- Get single postPOST /api/posts
- Create post (protected)PUT /api/posts/:id
- Update post (protected)DELETE /api/posts/:id
- Delete post (protected)POST /api/posts/:id/like
- Toggle post like (protected)
GET /api/comments/post/:postId
- Get post commentsPOST /api/comments
- Create comment (protected)PUT /api/comments/:id
- Update comment (protected)DELETE /api/comments/:id
- Delete comment (protected)
POST /api/upload/image
- Upload image (protected)DELETE /api/upload/image/:key
- Delete image (protected)
id
(Primary Key)username
(Unique)email
(Unique)password
(Hashed)firstName
,lastName
avatar
isActive
lastLogin
createdAt
,updatedAt
id
(Primary Key)title
content
excerpt
imageUrl
tags
(Array)isPublished
publishedAt
viewCount
authorId
(Foreign Key)createdAt
,updatedAt
id
(Primary Key)content
postId
(Foreign Key)authorId
(Foreign Key)parentId
(Foreign Key, nullable)isApproved
createdAt
,updatedAt
id
(Primary Key)userId
(Foreign Key)postId
(Foreign Key)createdAt
,updatedAt
- Unique constraint on (userId, postId)
💡 DICA: Use esta seção como referência enquanto resolve os problemas!
❌ Problema Atual (encontre no código!):
// RUIM: Isso causa N+1 queries
const posts = await Post.findAll(); // 1 query
for (const post of posts) {
const author = await post.getAuthor(); // N queries (uma para cada post)
const comments = await post.getComments(); // N queries adicionais
}
✅ Sua Solução Deve Ser:
// BOM: Isso usa apenas 1 query otimizada
const posts = await Post.findAll({
include: [
{ model: User, as: "author" },
{ model: Comment, as: "comments" },
],
});
❌ Encontre e Corrija:
// Senha em plain text (muito ruim!)
const user = { password: "123456" };
// JWT sem expiração
const token = jwt.sign({ userId }, "weak-secret");
// Input sem validação
app.post("/api/posts", (req, res) => {
const { title, content } = req.body; // Sem validação!
});
✅ Como Deve Ficar:
// Hash da senha
const hashedPassword = await bcrypt.hash(password, 12);
// JWT com expiração
const token = jwt.sign({ userId }, process.env.JWT_SECRET, {
expiresIn: "15m",
});
// Input validado
const schema = Joi.object({
title: Joi.string().min(3).max(200).required(),
content: Joi.string().min(10).required(),
});
❌ Problemas a Resolver:
# INSEGURO - encontre no docker-compose.yml!
environment:
- DATABASE_PASSWORD=supersecret123 # Senha exposta!
# Sem health checks
# Sem restart policies
✅ Como Deve Ser:
# SEGURO
secrets:
- db_password
environment:
- DATABASE_PASSWORD_FILE=/run/secrets/db_password
healthcheck:
test: ["CMD", "pg_isready", "-U", "postgres"]
interval: 30s
timeout: 10s
retries: 3
restart: unless-stopped
❌ Encontre Tests Como Este:
// Teste que sempre falha (propositalmente!)
it("should fail - broken test example", async () => {
const user = await User.create(userData);
expect(user.username).toBe("wrongusername"); // ← Obviamente errado!
});
✅ Sua Correção:
// Teste correto
it("should create user with correct username", async () => {
const user = await User.create(userData);
expect(user.username).toBe(userData.username); // ← Correto!
});
Type Safety:
interface User {
id: number;
username: string;
email: string;
}
// TypeScript catches errors at compile time
const user: User = {
id: "1", // Error: Type 'string' is not assignable to type 'number'
username: "john",
email: "john@example.com",
};
Better IDE Support:
- Auto-completion
- Refactoring tools
- Error detection
- Documentation
- Add Indexes
CREATE INDEX idx_posts_author_id ON posts(author_id);
CREATE INDEX idx_posts_published_at ON posts(published_at);
- Query Optimization
// Use eager loading
const posts = await Post.findAll({
include: [
{ model: User, as: "author", attributes: ["id", "username"] },
{ model: Comment, as: "comments", limit: 5 },
],
order: [["publishedAt", "DESC"]],
limit: 10,
});
- Connection Pooling
const sequelize = new Sequelize({
pool: {
max: 20, // Maximum connections
min: 5, // Minimum connections
acquire: 30000,
idle: 10000,
},
});
- Code Splitting
const LazyComponent = React.lazy(() => import("./Component"));
- Memoization
const MemoizedComponent = React.memo(ExpensiveComponent);
- Image Optimization
<img
src={imageUrl}
loading="lazy"
alt="Description"
srcSet={`${imageUrl}?w=300 300w, ${imageUrl}?w=600 600w`}
/>
🚨 IMPORTANTE: Várias dessas práticas estão faltando no código atual!
- Input Validation
const schema = Joi.object({
email: Joi.string().email().required(),
password: Joi.string().min(6).required(),
});
- Password Hashing
const hashedPassword = await bcrypt.hash(password, 12);
- JWT Security
const token = jwt.sign({ userId: user.id }, process.env.JWT_SECRET, {
expiresIn: "15m",
});
💡 DICA: Se você encontrar estes problemas, está no caminho certo!
-
❌ Database Connection Failures
- ✅ Verifique se o PostgreSQL está rodando
- ✅ Confirme credenciais no .env
- ✅ Certifique-se que o banco existe
-
❌ S3 Upload Failures
- ✅ Verifique credenciais AWS
- ✅ Confirme permissões do bucket
- ✅ Valide configuração CORS
- 🆘 SEM AWS? Use alternativa local:
// backend/src/controllers/uploadController.ts // Comente o código AWS e use: const localPath = `./public/uploads/${filename}`; fs.writeFileSync(localPath, buffer); res.json({ imageUrl: `http://localhost:3001/uploads/${filename}` });
-
❌ Build Errors
- ✅ Limpe node_modules e reinstale
- ✅ Corrija erros de TypeScript
- ✅ Verifique todas as dependências
-
❌ Testes Falhando (ESPERADO!)
- ✅ Leia as mensagens de erro
- ✅ Encontre assertions incorretas
- ✅ Corrija as expectativas dos testes
-
❌ Docker Não Sobe
- ✅ Verifique configurações de segurança
- ✅ Adicione health checks
- ✅ Configure restart policies
Lembre-se: O objetivo é demonstrar suas habilidades de debugging, otimização e melhores práticas!
# 1. Clique em "Fork" no GitHub (canto superior direito)
# 2. Isso criará uma cópia do repo na sua conta
# 3. Clone SEU fork (não o original):
git clone https://github.com/SEU-USUARIO/tech-challenge.git
cd tech-challenge
# 4. Adicione o repo original como upstream (para futuras atualizações):
git remote add upstream https://github.com/inovaulaorg/tech-challenge.git
# Crie uma branch descritiva:
git checkout -b feature/correcoes-desafio-tecnico
# Ou use seu nome:
git checkout -b fix/joao-silva-solucoes
# Ou por categoria de correções:
git checkout -b fix/performance-security-tests
# Faça suas correções nos arquivos
# Execute os testes após cada correção:
npm test
# Faça commits frequentes e descritivos:
git add .
git commit -m "fix: corrigir N+1 queries em postController com eager loading"
git add backend/src/tests/auth.test.ts
git commit -m "fix: corrigir assertions quebradas nos testes de auth"
git add docker-compose.yml
git commit -m "security: adicionar secrets e health checks no Docker"
# Continue fazendo commits para cada correção...
Crie um arquivo SOLUCOES.md
na raiz do projeto:
# Crie o arquivo de documentação:
touch SOLUCOES.md
Exemplo de conteúdo para SOLUCOES.md
:
# 🔧 Soluções Implementadas - [Seu Nome]
## 📊 Resumo das Correções
- ✅ **N+1 Queries**: Implementado eager loading no postController
- ✅ **Testes Quebrados**: Corrigidas 8 assertions incorretas
- ✅ **Docker Inseguro**: Adicionados secrets e health checks
- ✅ **UX Problems**: Corrigidos hover states e responsividade
- ✅ **Validações**: Implementadas validações de input robustas
## 🚀 Performance - Antes vs Depois
### N+1 Query Problem (postController.ts)
**Antes**: 50 posts = 150+ queries
```javascript
// Código problemático encontrado
const posts = await Post.findAll();
for (const post of posts) {
const comments = await Comment.findAll({ where: { postId: post.id } });
}
```
Depois: 50 posts = 1 query otimizada
// Minha solução implementada
const posts = await Post.findAll({
include: [
{ model: User, as: "author" },
{ model: Comment, as: "comments" },
],
});
-
auth.test.ts linha 45:
- Antes:
expect(user.username).toBe('wrongusername')
- Depois:
expect(user.username).toBe('testuser')
- Antes:
-
auth.test.ts linha 67:
- Antes:
expect(token).toBeUndefined()
- Depois:
expect(token).toBeDefined()
- Antes:
- Docker Secrets: Senhas não mais em plain text
- Input Validation: Joi schemas em todos os endpoints
- JWT Expiration: Tokens agora expiram em 15min
- CORS: Configuração restritiva implementada
- Rate limiting para APIs
- Logs estruturados com Winston
- Monitoramento com métricas
- Cache com Redis para queries frequentes
- Microserviços separados (auth, posts, media)
- Event-driven architecture
- Database read replicas
- CDN para assets estáticos
#### **5. Push e Abra Pull Request** (5 min)
```bash
# 1. Push sua branch:
git push origin feature/(LOGIN-CIN)-correcoes-desafio-tecnico
# 2. Vá ao GitHub e clique em "Compare & pull request"
# 3. Preencha título descritivo:
Título da PR:
[DESAFIO TÉCNICO] Correções de Performance, Segurança e Testes - João Silva (LOGIN-CIN)
Descrição da PR:
## 🎯 Desafio Técnico - Correções Implementadas
Olá! Aqui estão as correções que implementei para resolver os problemas intencionais do desafio:
### ✅ **Problemas Resolvidos:**
#### 🔴 **Críticos - Resolvidos**
- [x] **N+1 Queries**: Implementado eager loading em `postController.ts`
- [x] **Testes Quebrados**: Corrigidas todas as assertions em `auth.test.ts`
- [x] **Docker Inseguro**: Adicionados secrets, health checks e restart policies
#### 🟡 **Importantes - Resolvidos**
- [x] **UX Issues**: Hover states funcionais no Header component
- [x] **Validações**: Input validation com Joi em todos os endpoints
- [x] **Security**: Hash de senhas, JWT expiration, CORS configuration
### 📊 **Impacto das Correções:**
- **Performance**: Redução de 150+ queries para 1 query otimizada
- **Testes**: 100% dos testes passando (antes 0%)
- **Segurança**: Vulnerabilidades críticas resolvidas
- **UX**: Interface responsiva e acessível
### 🧪 **Como Testar:**
```bash
# 1. Testes automatizados:
npm test # Todos devem passar!
# 2. Build de produção:
npm run build # Deve ser bem-sucedido
# 3. Docker:
docker-compose up -d # Deve subir sem problemas
```
- Ver
SOLUCOES.md
para detalhes técnicos completos - Commits organizados por tipo de correção
- Código comentado onde necessário
- Priorizada performance e segurança
- Mantida compatibilidade com arquitetura existente
- Implementadas best practices de desenvolvimento
Disponível para discussão sobre as soluções implementadas! 🚀
### 🎯 **Dicas para um Pull Request Perfeito:**
#### **✅ DO - Faça:**
- **Commits organizados** por tipo de correção
- **Título descritivo** na PR
- **Documentação clara** das mudanças
- **Testes funcionando** 100%
- **Código limpo** e comentado
#### **❌ DON'T - Evite:**
- Commit único gigante com tudo
- Título genérico tipo "fixes"
- PR sem descrição
- Código não testado
- Mudanças não relacionadas ao desafio
### 📋 **Checklist Final:**
Antes de abrir a PR, confirme:
- [ ] **Todos os testes passando** (`npm test`)
- [ ] **Build de produção funcionando** (`npm run build`)
- [ ] **Docker subindo corretamente** (`docker-compose up`)
- [ ] **Commits organizados** e com mensagens claras
- [ ] **SOLUCOES.md criado** com documentação
- [ ] **PR tem título e descrição detalhados**
- [ ] **Código revisado** e limpo
### 🏆 **Resultado:**
Com este processo, o **entrevistador consegue**:
- ✅ **Ver exatamente** o que você mudou (diff do GitHub)
- ✅ **Avaliar seu código** diretamente online
- ✅ **Entender sua abordagem** pela documentação
- ✅ **Testar localmente** fazendo checkout da sua branch
- ✅ **Dar feedback** específico linha por linha
- ✅ **Avaliar qualidade** dos commits e organização
**Isso facilita muito a avaliação e demonstra profissionalismo!** 🎉
---
## 📄 License
This project is licensed under the MIT License.