Files
controle-de-estoque-cli/README.md
T
2026-07-16 11:53:59 -03:00

4.5 KiB

Controle de Estoque CLI

Aplicação de linha de comando (CLI) em Go para gerenciar um estoque de produtos. Projeto de estudo focado em organização de código em camadas e no uso de estruturas de dados nativas do Go.

Funcionalidades

  • Adicionar produtos ao estoque (nome, categoria, preço e quantidade)
  • Listar todos os produtos cadastrados
  • Atualizar um campo específico de um produto pelo ID
  • Deletar um produto pelo ID

Como executar

Requer Go 1.26 ou superior instalado.

go run ./cmd/cli

Para compilar um binário:

go build -o controle-de-estoque ./cmd/cli
./controle-de-estoque

Uso

Ao iniciar, o programa exibe um menu. Escolha uma opção pelo número ou pelo nome:

1 / adicionar - Adiciona o produto no estoque
2 / listar    - Lista todos os produtos do estoque
3 / atualizar - Atualiza um produto do estoque
4 / deletar   - Deleta um produto do estoque
0 / sair      - Sair do programa

Ao atualizar, informe o ID do produto e o campo desejado (nome, categoria, preco ou quantidade), seguido do novo valor.

Estrutura do projeto

O código é organizado em camadas, cada uma dependendo apenas da camada mais interna:

.
├── cmd/
│   └── cli/
│       └── main.go                     # Ponto de entrada: monta as dependências e inicia a CLI
└── internal/
    ├── cli/
    │   ├── app.go                      # Loop do menu: lê a opção e chama o handler
    │   ├── handlers.go                 # Entrada e saída no terminal de cada operação
    │   └── menu.go                     # Exibição do menu
    ├── service/
    │   └── inventory_service.go        # Regras de negócio (validações, atualização por campo)
    ├── repository/
    │   ├── inventory_repository.go     # Interface: o contrato de persistência
    │   └── in_memory/
    │       └── inventory_repository.go # Implementação em memória (map)
    └── model/
        └── product.go                  # Domínio: Product e ProductInput
  • model — define Product e ProductInput, sem lógica nem dependências.
  • repository — declara a interface InventoryRepository (o contrato). A pasta in_memory traz uma implementação que guarda tudo em um map[int]*Product.
  • service — concentra as regras de negócio (nome obrigatório, quantidade não negativa, conversão do campo a atualizar). Depende apenas da interface do repository, nunca de uma implementação concreta.
  • cli — responsável por toda interação com o terminal. Lê a opção do usuário e chama o service correspondente.
  • cmd/cli/main.go — o único lugar que conhece todas as camadas: cria o repository, injeta no service, injeta no app e roda.

Como o service depende só da interface, trocar a persistência (Postgres, arquivo JSON, etc.) exige apenas uma nova implementação de InventoryRepository e a troca de uma linha no main.go — nenhuma outra camada muda.

Os dados são mantidos apenas em memória: ao encerrar o programa, o estoque é perdido.

Conceitos aprendidos

  • Arquitetura em camadas — separação de responsabilidades entre model, repository, service e cli, mantendo cada parte independente.
  • InterfacesInventoryRepository define um contrato que qualquer implementação pode satisfazer, permitindo trocar a persistência sem tocar no resto do código.
  • Injeção de dependência — cada camada recebe suas dependências prontas (NewInventoryService(repo), NewApp(svc)), em vez de criá-las por conta própria.
  • Layout de projeto em Gocmd/ para os executáveis e internal/ para o código privado do módulo.
  • Structs e métodos — modelagem de dados com Product e métodos com receiver (func (s *InventorySevice) ...).
  • Maps — armazenamento em map[int]*Product para busca, atualização e remoção, o padrão comma-ok (v, ok := m[k]) e a função embutida delete(m, chave).
  • Leitura de entrada — uso de bufio.Scanner para ler linha a linha do terminal.
  • Tratamento de stringsstrings.TrimSpace para limpar os espaços e quebras de linhas da entrada e strconv (Atoi, ParseFloat) para converter texto em tipos numéricos.
  • Tratamento de erros — múltiplos retornos (valor, error), verificação com if err != nil e erros nomeados (ErrNotFound).
  • Formatação de saídafmt.Printf com verbos como %d, %s e %.2f.