- 📖 Sobre o Projeto
- 🔄 Fluxo Principal da Aplicação
- 🚀 Tecnologias Utilizadas
- 📁 Estrutura do Projeto
- 🔧 Configuração e Instalação
- 📊 Fluxo da Aplicação
- 🔐 Autenticação e Autorização
- 📝 API Endpoints
- 🧪 Testes
- 🐳 Docker
- 📚 Documentação da API
- 🤝 Contribuição
- 👨💻 Author
Esta é uma API RESTful desenvolvida em Node.js com TypeScript que gerencia um sistema de cursos online. A aplicação permite autenticação de usuários, criação e gerenciamento de cursos, e controle de acesso baseado em roles (estudante/gerente).
- ✅ Sistema de autenticação JWT
- ✅ Controle de acesso baseado em roles
- ✅ CRUD de cursos
- ✅ Sistema de matrículas
- ✅ Validação de dados com Zod
- ✅ Documentação automática da API
- ✅ Testes automatizados
- ✅ Containerização com Docker
Este diagrama mostra o fluxo mais importante da aplicação, desde a autenticação até o gerenciamento de cursos:
flowchart TD
Start([👤 Usuário Acessa API]) --> Auth{🔐 Autenticado?}
Auth -->|Não| Login[🔑 POST /sessions<br/>Login com Email/Senha]
Login --> Verify[🔍 Verificar Credenciais<br/>no PostgreSQL]
Verify --> Hash[🔒 Validar Hash<br/>com Argon2]
Hash --> ValidCreds{✅ Credenciais<br/>Válidas?}
ValidCreds -->|Não| Error400[❌ Erro 400<br/>Credenciais Inválidas]
ValidCreds -->|Sim| GenerateJWT[🎫 Gerar JWT Token<br/>com ID + Role]
GenerateJWT --> TokenResponse[📤 Retornar Token JWT]
Auth -->|Sim| ProtectedRoute[🛡️ Rota Protegida<br/>Header: Authorization]
TokenResponse --> ProtectedRoute
ProtectedRoute --> ValidateJWT[🔍 Validar JWT Token]
ValidateJWT --> ValidToken{✅ Token<br/>Válido?}
ValidToken -->|Não| Error401[❌ Erro 401<br/>Token Inválido]
ValidToken -->|Sim| CheckRole[👥 Verificar Role<br/>do Usuário]
CheckRole --> ManagerRole{👨💼 Role =<br/>Manager?}
ManagerRole -->|Não| Error403[❌ Erro 403<br/>Sem Permissão]
ManagerRole -->|Sim| BusinessLogic[⚙️ Executar<br/>Lógica de Negócio]
BusinessLogic --> CourseOps{📚 Operação<br/>com Cursos}
CourseOps -->|GET /courses| ListCourses[📋 Listar Cursos<br/>com Paginação]
CourseOps -->|POST /courses| CreateCourse[➕ Criar Curso<br/>Validar com Zod]
CourseOps -->|GET /courses/:id| GetCourse[🔍 Buscar Curso<br/>por ID]
ListCourses --> DBQuery1[🗄️ Consulta PostgreSQL<br/>com Drizzle ORM]
CreateCourse --> ValidateData[✅ Validar Dados<br/>com Zod Schema]
GetCourse --> DBQuery2[🗄️ Consulta PostgreSQL<br/>com Drizzle ORM]
ValidateData --> ValidData{✅ Dados<br/>Válidos?}
ValidData -->|Não| ErrorValidation[❌ Erro 400<br/>Dados Inválidos]
ValidData -->|Sim| DBInsert[🗄️ Inserir no<br/>PostgreSQL]
DBQuery1 --> Success1[✅ Sucesso 200<br/>Lista de Cursos]
DBQuery2 --> Success2[✅ Sucesso 200<br/>Dados do Curso]
DBInsert --> Success3[✅ Sucesso 201<br/>Curso Criado]
Error400 --> End([🏁 Fim])
Error401 --> End
Error403 --> End
ErrorValidation --> End
Success1 --> End
Success2 --> End
Success3 --> End
classDef startEnd fill:#1e3a8a,stroke:#60a5fa,stroke-width:3px,color:#ffffff
classDef process fill:#7c3aed,stroke:#a78bfa,stroke-width:3px,color:#ffffff
classDef decision fill:#ea580c,stroke:#fb923c,stroke-width:3px,color:#ffffff
classDef database fill:#059669,stroke:#34d399,stroke-width:3px,color:#ffffff
classDef success fill:#047857,stroke:#10b981,stroke-width:3px,color:#ffffff
classDef error fill:#dc2626,stroke:#f87171,stroke-width:3px,color:#ffffff
class Start,End startEnd
class Login,Verify,Hash,GenerateJWT,ProtectedRoute,ValidateJWT,CheckRole,BusinessLogic,ListCourses,CreateCourse,GetCourse,ValidateData,TokenResponse process
class Auth,ValidCreds,ValidToken,ManagerRole,CourseOps,ValidData decision
class DBQuery1,DBQuery2,DBInsert database
class Success1,Success2,Success3 success
class Error400,Error401,Error403,ErrorValidation error
- 🔐 Autenticação: Sistema JWT com validação de credenciais
- 🛡️ Autorização: Controle de acesso baseado em roles (Manager/Student)
- ✅ Validação: Schemas Zod para validação de dados
- 🗄️ Persistência: PostgreSQL com Drizzle ORM
- 🔒 Segurança: Hash de senhas com Argon2
- Node.js - Runtime JavaScript
- TypeScript - Linguagem de programação tipada
- Fastify - Framework web rápido e eficiente
- PostgreSQL - Banco de dados relacional
- Drizzle ORM - ORM type-safe para TypeScript
- Zod - Validação de schemas
- JWT - Autenticação baseada em tokens
- Argon2 - Hash de senhas seguro
- Vitest - Framework de testes
- Docker - Containerização
- Pino - Logger estruturado
src/
├── @types/ # Definições de tipos personalizados
├── database/ # Configuração e schema do banco
│ ├── client.ts # Cliente do banco de dados
│ ├── schema.ts # Definição das tabelas
│ └── seed.ts # Dados iniciais
├── routes/ # Rotas da API
│ ├── hooks/ # Middlewares de autenticação
│ ├── create-course.ts # Criação de cursos
│ ├── get-courses.ts # Listagem de cursos
│ ├── get-courses-by-id.ts # Busca por ID
│ └── login.ts # Autenticação
├── test/ # Testes automatizados
│ └── factories/ # Factories para testes
├── utils/ # Utilitários
├── app.ts # Configuração do Fastify
└── server.ts # Servidor principal
- Node.js 18+
- PostgreSQL 14+
- Docker (opcional)
- Clone o repositório
git clone https://github.com/emmanuelmarcosdeoliveira/first-node-api
cd first-node-api- Instale as dependências
npm install- Configure as variáveis de ambiente
cp .env.example .envConfigure as seguintes variáveis no arquivo .env:
Exemplo:
DATABASE_URL="postgresql://usuario:senha@localhost:5432/nome_do_banco"
JWT_SECRET="seu_jwt_secret_aqui"
NODE_ENV="development"- Execute as migrações do banco
npm run db:migrate- Popule o banco com dados iniciais
npm run db:seed- Inicie o servidor
npm run devA aplicação estará disponível em http://localhost:3333
graph TD
A[Cliente] --> B[Fastify Server]
B --> C{Endpoint}
C -->|POST /sessions| D[Login Route]
D --> E[Verificar Credenciais]
E --> F[Hash Password com Argon2]
F --> G{Credenciais Válidas?}
G -->|Sim| H[Gerar JWT Token]
G -->|Não| I[Retornar Erro 400]
H --> J[Retornar Token]
C -->|GET /courses| K[Get Courses Route]
K --> L[Verificar JWT]
L --> M{Token Válido?}
M -->|Não| N[Retornar Erro 401]
M -->|Sim| O[Verificar Role Manager]
O --> P{Role Manager?}
P -->|Não| Q[Retornar Erro 403]
P -->|Sim| R[Buscar Cursos no BD]
R --> S[Retornar Lista de Cursos]
C -->|POST /courses| T[Create Course Route]
T --> U[Verificar JWT]
U --> V{Token Válido?}
V -->|Não| W[Retornar Erro 401]
V -->|Sim| X[Verificar Role Manager]
X --> Y{Role Manager?}
Y -->|Não| Z[Retornar Erro 403]
Y -->|Sim| AA[Validar Dados com Zod]
AA --> BB{Dados Válidos?}
BB -->|Não| CC[Retornar Erro 400]
BB -->|Sim| DD[Criar Curso no BD]
DD --> EE[Retornar ID do Curso]
A aplicação implementa um sistema de controle de acesso baseado em roles:
- Student: Usuário estudante (role padrão)
- Manager: Usuário gerente com permissões administrativas
- Login: O usuário faz login com email e senha
- Validação: As credenciais são verificadas no banco de dados
- Token JWT: Um token é gerado contendo o ID e role do usuário
- Middleware: Todas as rotas protegidas verificam o token JWT
- Autorização: O sistema verifica se o usuário tem a role necessária
// Middleware para verificar JWT
preHandler: [checkRequestJWT, checkUserRole("manager")];| Método | Endpoint | Descrição | Autenticação |
|---|---|---|---|
| POST | /sessions |
Login do usuário | Não |
| Método | Endpoint | Descrição | Autenticação | Role |
|---|---|---|---|---|
| GET | /courses |
Listar todos os cursos | Sim | Manager |
| GET | /courses/:id |
Buscar curso por ID | Sim | Manager |
| POST | /courses |
Criar novo curso | Sim | Manager |
curl -X POST http://localhost:3333/sessions \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"password": "senha123"
}'{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}curl -X POST http://localhost:3333/courses \
-H "Content-Type: application/json" \
-H "Authorization: Bearer SEU_JWT_TOKEN" \
-d '{
"title": "Curso de Node.js"
}'# Executar todos os testes
npm run tests
# Executar testes com coverage
npm run test:coverage
# Executar testes em modo watch
npm run test:watch- Factories: Criação de dados de teste
- Integration Tests: Testes de integração das rotas
- Coverage: Relatório de cobertura de código
# Construir a imagem
docker build -t first-node-api .
# Executar o container
docker run -p 3333:3333 first-node-api# Subir todos os serviços
docker-compose up -d
# Ver logs
docker-compose logs -f
# Parar serviços
docker-compose downA documentação interativa da API está disponível em:
- Desenvolvimento:
http://localhost:3333/docs
A documentação é gerada automaticamente usando:
- OpenAPI/Swagger: Especificação da API
- Scalar: Interface de documentação moderna
Exemplo:
-
Faça um fork do 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
# Desenvolvimento
npm run dev # Inicia servidor em modo desenvolvimento
# Banco de Dados
npm run db:generate # Gera migrações
npm run db:migrate # Executa migrações
npm run db:studio # Abre Drizzle Studio
npm run db:seed # Popula banco com dados iniciais
# Testes
npm run tests # Executa testes
npm run pretest # Executa migrações antes dos testesdeveloped by 💖 Emmanuel Oliveira
© Todos os Direitos Reservados
