Uma API REST completa para um sistema de blog educacional, desenvolvida com Node.js, Fastify e PostgreSQL, implementando autenticação JWT e CRUD completo para posts educacionais.
Render Deploy: https://blog-dinamico-app.onrender.com/
-
RM 362457 - Alessandra Guedes
-
RM 362166 - Ana Carolina
-
RM 363723 - Vinicius Faria
-
RM 360942 - Vitor Freire
- Node.js - Runtime JavaScript
- Fastify - Framework web rápido e eficiente
- TypeScript - Tipagem estática para JavaScript
- PostgreSQL - Banco de dados relacional
- Zod - Validação de schemas e tipos
- Bcrypt.js - Hash de senhas
- JWT (@fastify/jwt) - Autenticação e autorização
- Vitest - Framework de testes moderno
- @vitest/coverage-v8 - Cobertura de testes
- Swagger/OpenAPI - Documentação automática da API
- @fastify/swagger - Integração Swagger com Fastify
- @fastify/swagger-ui - Interface visual da documentação
- Docker & Docker Compose - Containerização
- GitHub Actions - CI/CD pipeline
- Render - Plataforma de deploy
- DBeaver - Gerenciamento do banco de dados
O projeto segue os princípios da Clean Architecture e SOLID, organizando o código em camadas bem definidas:
src/
├── entities/ # Entidades de domínio
├── repositories/ # Camada de acesso a dados
├── use-cases/ # Regras de negócio
├── http/ # Controladores e rotas
│ ├── controller/ # Controladores HTTP
│ └── middleware/ # Middlewares de autenticação
├── lib/ # Configurações de bibliotecas
├── env/ # Configurações de ambiente
└── utils/ # Utilitários gerais
- ✅ CRUD Completo de Posts - Criar, listar, buscar, atualizar e deletar
- ✅ Sistema de Autenticação JWT - Login seguro para professores
- ✅ Busca Textual - Pesquisa por título e conteúdo dos posts
- ✅ Documentação Swagger - API totalmente documentada
- ✅ Testes Automatizados - Unitários e de integração
- ✅ CI/CD Pipeline - Deploy automatizado
- ✅ Containerização - Docker ready
-- Usuários do sistema
CREATE TABLE "user" (
id SERIAL PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
senha VARCHAR(255) NOT NULL
);
-- Professores (vinculados aos usuários)
CREATE TABLE professor (
id SERIAL PRIMARY KEY,
nome VARCHAR(100) NOT NULL,
materia VARCHAR(100),
user_id INTEGER UNIQUE NOT NULL REFERENCES "user"(id) ON DELETE CASCADE
);
-- Posts educacionais
CREATE TABLE post (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
titulo VARCHAR(200) NOT NULL,
resumo VARCHAR(500),
conteudo TEXT NOT NULL,
professor_id INTEGER NOT NULL REFERENCES professor(id) ON DELETE CASCADE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
- Login - Professor faz login com email/senha
- Verificação - Sistema valida credenciais e verifica se é professor
- Token JWT - Token é gerado com dados do usuário e professor
- Autorização - Rotas protegidas verificam token e permissões
// Apenas usuários autenticados
app.register(jwtAuth)
// Apenas professores podem criar/editar posts
app.register(professorAuth)
POST /user
- Cadastro de usuárioPOST /user/signin
- Login (retorna JWT token)
GET /posts
- Listar todos os postsGET /posts/:id
- Buscar post por IDGET /posts/search?query=termo
- Buscar posts por texto
POST /posts
- Criar novo postPUT /posts/:id
- Atualizar postDELETE /posts/:id
- Deletar post
GET /docs
- Interface Swagger da APIGET /
- Status da aplicação
- Node.js 18+
- Docker e Docker Compose
- PostgreSQL (ou usar via Docker)
git clone https://github.com/ViniciusFaria-png/tech-challenge-fase-02.git
cd tech-challenge-fase-02
Crie o arquivo .env
baseado no .env.example
:
cp .env.example .env
Configure as variáveis:
# Aplicação
PORT=3000
ENV=development
# Banco de Dados
POSTGRES_DB=blog_dinamico
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres123
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
# JWT
JWT_SECRET=seu-jwt-secret-super-secreto
# Subir todos os serviços
docker-compose up -d
# Verificar logs
docker-compose logs -f
A aplicação estará disponível em:
- API: http://localhost:3000
- Documentação: http://localhost:3000/docs
- PostgreSQL: localhost:5432
# Instalar dependências
npm install
# Subir apenas o banco
docker-compose up postgres -d
# Executar migrações (SQL files em /sql)
npm run migrate # ou execute manualmente via DBeaver
# Iniciar em modo desenvolvimento
npm run start:dev
# Testes unitários
npm test
# Testes com cobertura
npm run test:coverage
# Testes em modo watch
npm run test:watch
O projeto possui um pipeline automatizado que:
- Testes - Executa todos os testes unitários e de integração
- Build - Compila o TypeScript
- Docker - Constrói e publica imagem Docker
- Deploy - Faz deploy automático no Render
# .github/workflows/main.yml
- Checkout do código
- Setup Node.js 18
- Instalar dependências
- Executar testes com PostgreSQL
- Build da aplicação
- Build e push da imagem Docker
A aplicação está configurada para deploy automático no Render:
- Build Command:
npm run build
- Start Command:
npm start
- Environment: Produção com PostgreSQL gerenciado
__tests__/
├── integration/ # Testes de integração (API)
├── unit/ # Testes unitários
│ ├── entities/ # Testes de entidades
│ ├── use-cases/ # Testes de casos de uso
│ └── repositories/ # Testes de repositórios
├── setup/ # Configuração de testes
│ ├── mocks/ # Mocks e fixtures
│ └── utils/ # Utilitários de teste
└── utils/ # Helpers de teste
- Entidades: 100%
- Use Cases: 95%+
- Controladores: 90%+
- Repositórios: 85%+
Desafio: Configurar o pipeline de deploy automático no Render foi mais complexo que esperado.
Dificuldades:
- Compreender as especificidades da plataforma Render
- Configurar corretamente as variáveis de ambiente
- Sincronizar o build da aplicação com o deploy
- Gerenciar secrets do Docker Hub no GitHub Actions
Solução:
- Estudo detalhado da documentação do Render
- Configuração manual das variáveis de ambiente na plataforma
- Criação de pipeline robusto no GitHub Actions
- Implementação de health checks para verificar deploy
Desafio: Setup e gerenciamento do banco de dados PostgreSQL no Render.
Dificuldades:
- Criar instância PostgreSQL gerenciada no Render
- Conectar aplicação ao banco remoto
- Executar scripts SQL de inicialização
- Gerenciar migrações e seeds de dados
Solução:
- Uso do DBeaver para conexão direta ao banco
- Execução manual dos scripts SQL (
01-schema.sql
,02-data.sql
) - Configuração de connection pooling para otimização
- Implementação de health checks do banco
Desafio: Desenvolver sistema de autenticação robusto com diferenciação de usuários e professores.
Dificuldades:
- Integrar JWT com Fastify de forma adequada
- Criar middleware de autenticação para diferentes níveis de acesso
- Proteger rotas sensíveis (apenas professores podem criar/editar posts)
- Gerenciar tokens de forma segura
- Implementar refresh token strategy
Solução:
// Middleware de autenticação de professor
export async function professorAuth(request: FastifyRequest, reply: FastifyReply) {
try {
await request.jwtVerify();
const payload = request.user as any;
if (!payload.isProfessor || !payload.professorId) {
return reply.status(403).send({
message: "Acesso negado. Apenas professores podem realizar esta ação."
});
}
request.user = {
id: payload.sub,
email: payload.email,
professor_id: payload.professorId.toString()
};
} catch (error) {
return reply.status(401).send({
message: "Token inválido ou expirado"
});
}
}
Desafio: Configurar ambiente de testes que simule o ambiente de produção.
Dificuldades:
- Setup de banco PostgreSQL para testes
- Isolamento entre testes
- Mocking de dependências externas
- Testes de autenticação e autorização
Solução:
- Configuração de banco de testes no CI/CD
- Uso de factories e mocks para dados de teste
- Implementação de
fakeAuth
para testes - Limpeza automática do banco entre testes
- Cache Redis - Para melhorar performance das consultas
- Rate Limiting - Proteção contra spam e ataques
- Upload de Imagens - Para posts com conteúdo visual
- Notificações - Sistema de alertas para novos posts
- Comentários - Interação entre alunos e professores
- Analytics - Métricas de uso e engajamento
- Fork o projeto
- Crie uma branch para sua feature (
git checkout -b feature/AmazingFeature
) - Commit suas mudanças (
git commit -m 'Add some AmazingFeature'
) - Push para a branch (
git push origin feature/AmazingFeature
) - Abra um Pull Request
Este projeto está sob a licença MIT. Veja o arquivo LICENSE para mais detalhes.