Skip to content

emmanuelmarcosdeoliveira/first-node-api

Repository files navigation

📚 First Node API

Node.js TypeScript Fastify PostgreSQL Drizzle ORM Vitest Docker JWT

📋 Índice

📖 Sobre o Projeto

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).

Principais Funcionalidades

  • ✅ 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

🔄 Fluxo Principal da Aplicação

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
Loading

🎯 Principais Componentes do Fluxo:

  1. 🔐 Autenticação: Sistema JWT com validação de credenciais
  2. 🛡️ Autorização: Controle de acesso baseado em roles (Manager/Student)
  3. ✅ Validação: Schemas Zod para validação de dados
  4. 🗄️ Persistência: PostgreSQL com Drizzle ORM
  5. 🔒 Segurança: Hash de senhas com Argon2

🚀 Tecnologias Utilizadas

  • 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

📁 Estrutura do Projeto

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

🔧 Configuração e Instalação

Pré-requisitos

  • Node.js 18+
  • PostgreSQL 14+
  • Docker (opcional)

Instalação

  1. Clone o repositório
git clone https://github.com/emmanuelmarcosdeoliveira/first-node-api
cd first-node-api
  1. Instale as dependências
npm install
  1. Configure as variáveis de ambiente
cp .env.example .env

Configure 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"
  1. Execute as migrações do banco
npm run db:migrate
  1. Popule o banco com dados iniciais
npm run db:seed
  1. Inicie o servidor
npm run dev

A aplicação estará disponível em http://localhost:3333

📊 Fluxo da Aplicação

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]
Loading

🔐 Autenticação e Autorização

Sistema de Roles

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

Fluxo de Autenticação

  1. Login: O usuário faz login com email e senha
  2. Validação: As credenciais são verificadas no banco de dados
  3. Token JWT: Um token é gerado contendo o ID e role do usuário
  4. Middleware: Todas as rotas protegidas verificam o token JWT
  5. Autorização: O sistema verifica se o usuário tem a role necessária

Proteção de Rotas

// Middleware para verificar JWT
preHandler: [checkRequestJWT, checkUserRole("manager")];

📝 API Endpoints

Autenticação

Método Endpoint Descrição Autenticação
POST /sessions Login do usuário Não

Cursos

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

Exemplo de Requisição - Login

curl -X POST http://localhost:3333/sessions \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "password": "senha123"
  }'

Exemplo de Resposta - Login

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Exemplo de Requisição - Criar Curso

curl -X POST http://localhost:3333/courses \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer SEU_JWT_TOKEN" \
  -d '{
    "title": "Curso de Node.js"
  }'

🧪 Testes

Executar Testes

# Executar todos os testes
npm run tests

# Executar testes com coverage
npm run test:coverage

# Executar testes em modo watch
npm run test:watch

Estrutura dos Testes

  • Factories: Criação de dados de teste
  • Integration Tests: Testes de integração das rotas
  • Coverage: Relatório de cobertura de código

🐳 Docker

Executar com Docker

# Construir a imagem
docker build -t first-node-api .

# Executar o container
docker run -p 3333:3333 first-node-api

Docker Compose

# Subir todos os serviços
docker-compose up -d

# Ver logs
docker-compose logs -f

# Parar serviços
docker-compose down

📚 Documentação da API

A 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

🤝 Contribuição

Exemplo:

  1. Faça um fork do projeto

  2. Crie uma branch para sua feature (git checkout -b feature/AmazingFeature)

  3. Commit suas mudanças (git commit -m 'Add some AmazingFeature')

  4. Push para a branch (git push origin feature/AmazingFeature)

  5. Abra um Pull Request



Scripts Disponíveis

# 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 testes

👨‍💻 Author


Emmanuel Oliveira

developed by 💖 Emmanuel Oliveira
© Todos os Direitos Reservados

Releases

No releases published

Packages

No packages published