# 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](https://go.dev/) 1.26 ou superior instalado. ```bash go run ./cmd/cli ``` Para compilar um binário: ```bash 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 ``` - **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. - **Interfaces** — `InventoryRepository` 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 Go** — `cmd/` 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 strings** — `strings.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ída** — `fmt.Printf` com verbos como `%d`, `%s` e `%.2f`.