Skip to content

clauthucio/handsON

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🎮 API de Gerenciamento de Loja - Mundo Geek

Descrição

API RESTful para gerenciamento de categorias e produtos da loja "Mundo Geek", especializada em produtos colecionáveis, jogos de tabuleiro e itens de cultura pop.

A API foi desenvolvida com as melhores práticas de arquitetura de software, incluindo:

  • Linguagem: TypeScript
  • Framework Web: Express.js
  • ORM: TypeORM
  • Banco de Dados: PostgreSQL
  • Validação: Zod
  • Padrão Arquitetural: MVC com Serviços

🚀 Como Começar

Pré-requisitos

  • Node.js (v16 ou superior)
  • npm ou yarn
  • PostgreSQL (v12 ou superior)

Instalação

  1. Instale as dependências do projeto:
npm install
  1. Configure as variáveis de ambiente:

Edite o arquivo .env na raiz do projeto com suas credenciais do PostgreSQL:

DB_HOST=localhost
DB_PORT=5432
DB_USERNAME=postgres
DB_PASSWORD=sua_senha_aqui
DB_DATABASE=mundo_geek

NODE_ENV=development
PORT=3000
  1. Crie o banco de dados PostgreSQL:
CREATE DATABASE mundo_geek;
  1. Inicie o servidor em modo desenvolvimento:
npm run dev

O servidor rodará em http://localhost:3000

Comandos Disponíveis

npm run dev      # Inicia servidor em modo desenvolvimento com hot-reload
npm run build    # Compila TypeScript para JavaScript
npm start        # Inicia servidor em produção

📊 Estrutura do Projeto

src/
├── server.ts                    # Ponto de entrada da aplicação
├── config/
│   └── index.ts                 # Configurações e variáveis de ambiente
├── database/
│   └── data-source.ts           # Conexão e configuração TypeORM
├── entities/
│   ├── Categoria.ts             # Entidade Categoria
│   └── Produto.ts               # Entidade Produto
├── services/
│   ├── CategoriaService.ts       # Lógica de negócio - Categorias
│   └── ProdutoService.ts         # Lógica de negócio - Produtos
├── controllers/
│   ├── CategoriaController.ts    # Manipulação de requisições - Categorias
│   └── ProdutoController.ts      # Manipulação de requisições - Produtos
├── routes/
│   ├── categoriaRoutes.ts        # Rotas de Categorias
│   └── produtoRoutes.ts          # Rotas de Produtos
├── middlewares/
│   └── errorHandler.ts           # Tratamento centralizado de erros
└── validates/
    ├── CategoriaValidation.ts    # Schemas Zod para Categorias
    └── ProdutoValidation.ts      # Schemas Zod para Produtos

🗄️ Modelo de Dados

Entidade: Categoria

Representa uma categoria de produtos na loja.

{
  id: string (UUID);              // Identificador único
  nome: string;                   // Nome da categoria (único, obrigatório)
  descricao?: string;             // Descrição opcional
  dataCriacao: Date;              // Data de criação (automática)
  dataAtualizacao: Date;          // Data da última atualização (automática)
  produtos?: Produto[];           // Lista de produtos da categoria
}

Entidade: Produto

Representa um item disponível na loja.

{
  id: string (UUID);              // Identificador único
  nome: string;                   // Nome do produto (obrigatório)
  descricao?: string;             // Descrição opcional
  preco: number;                  // Preço do produto (> 0)
  estoque: number;                // Quantidade em estoque (>= 0)
  dataCriacao: Date;              // Data de criação (automática)
  dataAtualizacao: Date;          // Data da última atualização (automática)
  categoria: Categoria;           // Relacionamento com Categoria (1:N)
  categoriaId: string;            // Chave estrangeira para Categoria
}

Relacionamento

Categoria 1:N Produto

  • Uma categoria pode ter muitos produtos
  • Um produto pertence a apenas uma categoria
  • Ao deletar uma categoria, seus produtos são deletados em cascata (ON DELETE CASCADE)

📡 Endpoints da API

Base URL

http://localhost:3000/api

Categorias

1. Criar Categoria

POST /categorias
Content-Type: application/json

{
  "nome": "Jogos de Tabuleiro",
  "descricao": "Jogos estratégicos e educacionais"
}

Resposta (201 Created):

{
  "success": true,
  "message": "Categoria criada com sucesso",
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "nome": "Jogos de Tabuleiro",
    "descricao": "Jogos estratégicos e educacionais",
    "dataCriacao": "2024-02-02T10:30:00Z",
    "dataAtualizacao": "2024-02-02T10:30:00Z"
  }
}

2. Listar Todas as Categorias

GET /categorias

Resposta (200 OK):

{
  "success": true,
  "message": "Categorias encontradas",
  "total": 2,
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "nome": "Jogos de Tabuleiro",
      "descricao": "Jogos estratégicos e educacionais",
      "dataCriacao": "2024-02-02T10:30:00Z",
      "dataAtualizacao": "2024-02-02T10:30:00Z",
      "produtos": []
    }
  ]
}

3. Obter Categoria por ID

GET /categorias/{id}

Resposta (200 OK):

{
  "success": true,
  "message": "Categoria encontrada",
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "nome": "Jogos de Tabuleiro",
    "descricao": "Jogos estratégicos e educacionais",
    "dataCriacao": "2024-02-02T10:30:00Z",
    "dataAtualizacao": "2024-02-02T10:30:00Z",
    "produtos": []
  }
}

4. Atualizar Categoria

PUT /categorias/{id}
Content-Type: application/json

{
  "nome": "Jogos Modernos",
  "descricao": "Jogos estratégicos atualizados"
}

Resposta (200 OK):

{
  "success": true,
  "message": "Categoria atualizada com sucesso",
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "nome": "Jogos Modernos",
    "descricao": "Jogos estratégicos atualizados",
    "dataCriacao": "2024-02-02T10:30:00Z",
    "dataAtualizacao": "2024-02-02T11:00:00Z"
  }
}

5. Deletar Categoria

DELETE /categorias/{id}

Resposta (204 No Content): Sem corpo


Produtos

1. Criar Produto

POST /produtos
Content-Type: application/json

{
  "nome": "Catan",
  "descricao": "Jogo clássico de estratégia",
  "preco": 89.90,
  "estoque": 15,
  "categoriaId": "550e8400-e29b-41d4-a716-446655440000"
}

Resposta (201 Created):

{
  "success": true,
  "message": "Produto criado com sucesso",
  "data": {
    "id": "660e8400-e29b-41d4-a716-446655440001",
    "nome": "Catan",
    "descricao": "Jogo clássico de estratégia",
    "preco": 89.90,
    "estoque": 15,
    "dataCriacao": "2024-02-02T10:30:00Z",
    "dataAtualizacao": "2024-02-02T10:30:00Z",
    "categoria": {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "nome": "Jogos de Tabuleiro"
    },
    "categoriaId": "550e8400-e29b-41d4-a716-446655440000"
  }
}

2. Listar Todos os Produtos

GET /produtos

Resposta (200 OK):

{
  "success": true,
  "message": "Produtos encontrados",
  "total": 1,
  "data": [
    {
      "id": "660e8400-e29b-41d4-a716-446655440001",
      "nome": "Catan",
      "descricao": "Jogo clássico de estratégia",
      "preco": 89.90,
      "estoque": 15,
      "dataCriacao": "2024-02-02T10:30:00Z",
      "dataAtualizacao": "2024-02-02T10:30:00Z",
      "categoria": {
        "id": "550e8400-e29b-41d4-a716-446655440000",
        "nome": "Jogos de Tabuleiro"
      },
      "categoriaId": "550e8400-e29b-41d4-a716-446655440000"
    }
  ]
}

3. Obter Produto por ID

GET /produtos/{id}

Resposta (200 OK): Similar ao endpoint anterior

4. Listar Produtos por Categoria

GET /produtos/categoria/{categoriaId}

Resposta (200 OK): Lista de produtos da categoria

5. Atualizar Produto

PUT /produtos/{id}
Content-Type: application/json

{
  "preco": 99.90,
  "estoque": 20
}

Resposta (200 OK): Dados do produto atualizado

6. Deletar Produto

DELETE /produtos/{id}

Resposta (204 No Content): Sem corpo


✅ Validação de Dados

Categoria - Criação/Atualização

// nome: obrigatório, 3-255 caracteres
// descricao: opcional, até 1000 caracteres
// nome deve ser único

Erro de Validação (400 Bad Request):

{
  "success": false,
  "message": "Erro de validação",
  "errors": {
    "nome": ["O nome da categoria deve ter no mínimo 3 caracteres"]
  }
}

Produto - Criação/Atualização

// nome: obrigatório, 3-255 caracteres
// descricao: opcional, até 1000 caracteres
// preco: obrigatório, > 0, até 2 casas decimais
// estoque: obrigatório, >= 0, inteiro
// categoriaId: obrigatório (criação), UUID válido

⚠️ Tratamento de Erros

A API retorna erros estruturados com mensagens claras:

400 Bad Request

{
  "success": false,
  "message": "Erro de validação",
  "errors": { "campo": ["mensagem de erro"] }
}

404 Not Found

{
  "success": false,
  "message": "Categoria com ID xxx não encontrada"
}

409 Conflict

{
  "success": false,
  "message": "Uma categoria com este nome já existe"
}

500 Internal Server Error

{
  "success": false,
  "message": "Erro interno do servidor"
}

🎯 Princípios de Arquitetura Implementados

1. Separação de Responsabilidade

  • Controllers: Manipulam requisições/respostas HTTP
  • Services: Contêm a lógica de negócio
  • Entities: Definem a estrutura de dados
  • Routes: Mapeiam endpoints para controladores
  • Validadores: Garantem integridade de dados

2. DRY (Don't Repeat Yourself)

  • Validação centralizada com Zod
  • Tratamento de erros único e reutilizável
  • Esquemas de validação bem organizados

3. SOLID Principles

  • Single Responsibility: Cada classe/função tem um propósito único
  • Dependency Injection: Services usam repositórios injetados
  • Liskov Substitution: Padrões consistentes em toda a API
  • Interface Segregation: Schemas Zod definem contatos claros
  • Dependency Inversion: Services não dependem de implementações específicas

4. Clean Code

  • Nomes descritivos e convenções padronizadas
  • Funções pequenas e focadas
  • Comentários onde necessário
  • Código TypeScript com tipos explícitos

🧪 Exemplos de Uso

Com cURL

# Criar categoria
curl -X POST http://localhost:3000/api/categorias \
  -H "Content-Type: application/json" \
  -d '{
    "nome": "Action Figures",
    "descricao": "Miniaturas colecionáveis"
  }'

# Listar categorias
curl http://localhost:3000/api/categorias

# Obter categoria específica
curl http://localhost:3000/api/categorias/550e8400-e29b-41d4-a716-446655440000

# Criar produto
curl -X POST http://localhost:3000/api/produtos \
  -H "Content-Type: application/json" \
  -d '{
    "nome": "Batman Figure",
    "preco": 59.90,
    "estoque": 10,
    "categoriaId": "550e8400-e29b-41d4-a716-446655440000"
  }'

Com Postman

  1. Importe a coleção fornecida em postman-collection.json
  2. Configure a variável base_url como http://localhost:3000/api
  3. Teste todos os endpoints

📝 Notas de Implementação

TypeORM Configuration

  • Synchronize: Habilitado para desenvolvimento automático de schema
  • Logging: Desabilitado em produção
  • Relations: Configuradas com eager: true para Produtos (carrega categoria automaticamente)

Validação

  • Todas as validações usam Zod
  • Schemas separados para CREATE e UPDATE
  • Validação de UUID para IDs
  • Validação de unicidade de nome para categorias no serviço

Banco de Dados

  • Cascade Delete: Deletar categoria deleta automaticamente seus produtos
  • Auto-increment: IDs são UUIDs gerados automaticamente
  • Timestamps: dataCriacao e dataAtualizacao são automáticos

🚀 Próximos Passos para Produção

  1. Autenticação e Autorização

    • Implementar JWT
    • Adicionar roles de usuário
  2. Paginação

    • Adicionar parâmetros limit e offset
    • Implementar cursor-based pagination
  3. Filtros e Busca

    • Busca por nome
    • Filtros por preço
    • Filtros por estoque
  4. Logging

    • Implementar logger (Winston, Morgan)
    • Registrar todas as operações
  5. Testes

    • Testes unitários com Jest
    • Testes de integração
    • Cobertura de 80%+
  6. Deploy

    • Docker e Docker Compose
    • CI/CD com GitHub Actions
    • Migrations com TypeORM CLI
  7. Performance

    • Implementar cache (Redis)
    • Índices de banco de dados
    • Rate limiting

📞 Suporte

Para dúvidas ou problemas, verifique:

  • Configuração das variáveis de ambiente
  • Conexão com PostgreSQL
  • Logs da aplicação em NODE_ENV=development

Desenvolvido para a disciplina de Programação Web - Arquitetura e Banco de Dados

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors