Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

35 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🏥 HealthSync API

Sistema de Gestão Integrada para Farmácias e Distribuidoras

Java Spring Boot MySQL Status


🎯 Visão Geral

HealthSync é uma API REST robusta e escalável para gestão completa de farmácias e distribuidoras. Desenvolvida em Spring Boot 4.0.5, oferece solução integrada, documentada e pronta para produção.

(FrontEnd finalizado para a maioria dos Endpoints porém em desenvolvimento, para consultar informações sobre o Frontend checar no diretório Frontend que disponibiliza um readme.md específico dedicado ao momento do desenvolvimento).

Principais Funcionalidades

Módulo Capacidades
💰 Financeiro Contas a receber/pagar, fluxo de caixa, relatórios de vencimento
📦 Estoque Controle de lotes, data de validade, rastreamento de movimentações
👥 Clientes Cadastro com CPF validado, histórico de compras, análise
🏭 Fornecedores CNPJ validado, gestão de relacionamento e produtos
🛒 Vendas PDV integrado, múltiplos métodos de pagamento, cálculo automático
🔐 Segurança JWT + Spring Security, roles ADMIN e CAIXA, CORS configurável
📊 API OpenAPI 3.0, Swagger interativo, DTOs completos, validação robusta

🚀 Stack Tecnológico

Backend

Java 17                    Linguagem principal
Spring Boot 4.0.5          Framework Web
Spring Data JPA            ORM e persistência
Spring Security            Autenticação/Autorização
Spring Validation          Validação de dados

Banco de Dados & Migrações

MySQL 8.0+                 Banco de dados relacional
Flyway                     Versionamento de schema
Hibernate                  Mapeamento objeto-relacional

Segurança & Documentação

Auth0 JWT                  Tokens JWT
OpenAPI 3.0                Especificação de API
SpringDoc                  Swagger/OpenAPI integrado

Ferramentas

Maven 3.9+                 Build e dependências
Lombok                     Redução de boilerplate
JUnit 5                    Testes unitários

📋 Começando

Pré-requisitos

✅ Java 17 ou superior
✅ Maven 3.9 ou superior
✅ MySQL 8.0 ou superior
✅ Git

Instalação Rápida

1️⃣ Clone o Repositório

git clone https://github.com/limasantos/pharmacy-api.git
cd pharmacy-api

2️⃣ Configure o Banco de Dados

Crie o banco e usuário:

CREATE DATABASE pharmacy_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'pharmacy_user'@'localhost' IDENTIFIED BY 'SenhaSegura123!';
GRANT ALL PRIVILEGES ON pharmacy_db.* TO 'pharmacy_user'@'localhost';
FLUSH PRIVILEGES;

3️⃣ Configure as Credenciais

Edite src/main/resources/application.properties:

spring.datasource.url=jdbc:mysql://localhost:3306/pharmacy_db
spring.datasource.username=pharmacy_user
spring.datasource.password=SenhaSegura123!
api.security.token.secret=your_secret_jwt_key_here

4️⃣ Instale e Execute

# Instalar dependências
mvn clean install

# Executar aplicação
mvn spring-boot:run

Pronto! Acesse: http://localhost:8080


📚 Documentação da API

🔗 Swagger

Após iniciar, acesse:

http://localhost:8080/swagger-ui.html

Recursos disponíveis:

  • ✅ Testar endpoints em tempo real
  • ✅ Visualizar schemas completos
  • ✅ Autenticação JWT integrada
  • ✅ Documentação automática dos parâmetros

🔑 Endpoints Principais

Autenticação

POST   /api/auth/register          # Registrar novo usuário
POST   /api/auth/login             # Login e obter JWT
POST   /api/auth/refresh           # Renovar token expirado

Clientes

GET    /api/customers              # Listar todos (paginado)
GET    /api/customers/{id}         # Detalhes do cliente
POST   /api/customers              # Criar novo
PUT    /api/customers/{id}         # Atualizar
DELETE /api/customers/{id}         # Remover

Produtos

GET    /api/products               # Listar com filtros
GET    /api/products/{id}          # Detalhes
POST   /api/products               # Criar (validação MS + CNPJ)
PUT    /api/products/{id}          # Atualizar
DELETE /api/products/{id}          # Remover

Estoque

GET    /api/inventory/lots         # Lotes em estoque
POST   /api/inventory/lots         # Registrar novo lote
GET    /api/inventory/movements    # Histórico de movimentações
POST   /api/inventory/movements    # Registrar movimentação (ENTRY, SALE, RETURN, DISPOSAL)

Financeiro

GET    /api/financials             # Lançamentos (filtro: tipo, status)
POST   /api/financials             # Criar lançamento
PUT    /api/financials/{id}        # Atualizar
GET    /api/financials/overdue     # Contas vencidas

Vendas

GET    /api/sales                  # Listar com filtros
POST   /api/sales                  # Nova venda (recalcula total automático)
GET    /api/sales/{id}             # Detalhes + itens
PUT    /api/sales/{id}/payment     # Processar pagamento

Fornecedores

GET    /api/suppliers              # Listar fornecedores
POST   /api/suppliers              # Cadastrar (validação CNPJ)
PUT    /api/suppliers/{id}         # Atualizar
DELETE /api/suppliers/{id}         # Remover

Testes

GET    /api/test/health            # Verificar saúde da API
GET    /api/test/greet/{name}      # Saudação personalizada
POST   /api/test/echo              # Echo do payload

🔐 Autenticação & Segurança

Fluxo de Autenticação

1. POST /api/auth/login
   {
     "username": "admin",
     "password": "senha123"
   }

2. Resposta com JWT Token
   {
     "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
     "expiresIn": 86400,
     "type": "Bearer"
   }

3. Usar em requisições
   Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

4. Servidor valida token via Spring Security

Roles e Permissões

Role Permissões
ROLE_ADMIN Acesso total, gerenciar usuários, relatórios
ROLE_CAIXA Vendas, clientes, estoque (leitura), consultas

Validações Integradas

CPF - Validação de dígito verificador e unicidade

CNPJ - Validação de formato e dígitos

Email - Formato RFC 5322 e unicidade

Registro MS - Exatamente 13 dígitos numéricos

Telefone - 10-11 dígitos

Valores - Precisão Decimal para operações financeiras


🗄️ Estrutura do Banco de Dados

Diagrama ER Completo

Visualize em: dbdiagram.io

Entidades Principais

TB_users

├── id (UUID, PK)
├── username (VARCHAR UNIQUE, NOT NULL)
├── password (VARCHAR, NOT NULL - bcrypt)
├── role (ENUM: ROLE_ADMIN, ROLE_CAIXA)
└── email (VARCHAR UNIQUE, NOT NULL)

TB_products

├── id (BIGINT, PK)
├── name (VARCHAR, NOT NULL)
├── description (TEXT)
├── priceCost (DECIMAL, ≥ 0)
├── priceSale (DECIMAL, ≥ 0)
├── controlled (BOOLEAN)
├── tarja (VARCHAR)
├── registerMS (VARCHAR UNIQUE, 13 dígitos)
├── productCategoryType (ENUM)
└── supplier_id (BIGINT, FK → TB_suppliers)

TB_customers

├── id (BIGINT, PK)
├── name (VARCHAR, NOT NULL)
└── cpf (VARCHAR UNIQUE, validated)

TB_inventory_lot

├── id (BIGINT, PK)
├── product_id (BIGINT, FK)
├── lotNumber (VARCHAR)
├── entryDate (DATE, auto-generated)
├── expirationDate (DATE)
└── quantity (INTEGER)

TB_inventory_movements

├── id (BIGINT, PK)
├── inventory_lot_id (BIGINT, FK)
├── movementType (ENUM: ENTRY, SALE, RETURN, DISPOSAL)
├── quantity (INTEGER)
├── movementDate (DATETIME, auto-generated)
└── reason (VARCHAR, obrigatório para DISPOSAL/ADJUSTMENT)

TB_sales

├── id (BIGINT, PK)
├── customer_id (BIGINT, FK, nullable)
├── saleDate (DATETIME, auto-generated)
├── totalAmount (DECIMAL, recalculado automático)
├── paymentMethod (ENUM: DINHEIRO, CARTAO, PIX, CHEQUE)
└── items (OneToMany → TB_sale_items)

TB_financials

├── id (BIGINT, PK)
├── type (ENUM: CONTA_A_RECEBER, CONTA_A_PAGAR)
├── description (VARCHAR, NOT NULL)
├── amount (DECIMAL, Positive)
├── issueDate (DATETIME, auto-generated)
├── dueDate (DATE)
├── paymentDate (DATE, nullable)
├── status (ENUM: PENDING, PARTIALLY_PAID, PAID, OVERDUE, CANCELED)
├── paymentMethod (ENUM, nullable)
├── customer_id (BIGINT, FK, nullable)
├── supplier_id (BIGINT, FK, nullable)
├── notes (TEXT)
├── createdAt (DATETIME)
└── updatedAt (DATETIME)

📊 Padrão de Response

✅ Sucesso

{
  "success": true,
  "message": "Operação realizada com sucesso",
  "code": "SUCCESS",
  "timestamp": "2026-04-23T10:30:00",
  "path": "/api/customers",
  "data": {
    "id": 1,
    "name": "João Silva",
    "cpf": "123.456.789-00"
  }
}

❌ Erro de Validação

{
  "success": false,
  "message": "Erro ao validar entrada",
  "code": "VALIDATION_ERROR",
  "timestamp": "2026-04-23T10:30:00",
  "path": "/api/customers",
  "errors": [
    {
      "field": "cpf",
      "message": "CPF inválido",
      "rejectedValue": "000.000.000-00"
    },
    {
      "field": "email",
      "message": "Email deve ser válido",
      "rejectedValue": "invalid-email"
    }
  ]
}

📋 Listagem com Paginação

{
  "success": true,
  "message": "Clientes listados",
  "code": "SUCCESS",
  "timestamp": "2026-04-23T10:30:00",
  "data": [
    { "id": 1, "name": "Cliente 1", "cpf": "123.456.789-00" },
    { "id": 2, "name": "Cliente 2", "cpf": "987.654.321-00" }
  ],
  "pagination": {
    "totalElements": 150,
    "totalPages": 15,
    "currentPage": 0,
    "pageSize": 10
  }
}

⚙️ Configuração

arquivo application.properties

# ==================== APPLICATION ====================
spring.application.name=pharmacy.api
server.port=8080

# ==================== DATABASE ====================
spring.datasource.url=jdbc:mysql://localhost:3306/pharmacy_db
spring.datasource.username=pharmacy_user
spring.datasource.password=SenhaSegura123!

# ==================== JPA ====================
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true

# ==================== FLYWAY ====================
spring.flyway.enabled=true

# ==================== LOGGING ====================
logging.level.com.limasantos.pharmacy=DEBUG
logging.level.org.springframework.web=DEBUG

# ==================== SWAGGER ====================
springdoc.api-docs.path=/v3/api-docs
springdoc.swagger-ui.path=/swagger-ui.html

api.docs.title=HealthSync API
api.docs.version=1.0.0

# ==================== CORS ====================
api.cors.allowed-origins=http://localhost:3000,http://localhost:5173

# ==================== JWT ====================
api.security.token.secret=your_secret_key_here
api.security.token.expiration=86400000

Variáveis de Ambiente (Produção)

export JWT_SECRET="sua_chave_segura_aqui"
export DB_URL="jdbc:mysql://db.prod.com:3306/pharmacy_db"
export DB_USERNAME="pharmacy_prod"
export DB_PASSWORD="senha_muito_segura"

🧪 Testes & Validação

Executar Testes

# Todos os testes
mvn test

# Teste específico
mvn test -Dtest=CustomerServiceTest

# Com cobertura de código
mvn test jacoco:report

Exemplo de Teste Unitário

@SpringBootTest
class CustomerServiceTest {

    @Autowired
    private CustomerService customerService;

    @Test
    void shouldCreateCustomerWithValidData() {
        Customer customer = new Customer();
        customer.setName("João Silva");
        customer.setCpf("123.456.789-00");

        Customer saved = customerService.save(customer);

        assertNotNull(saved.getId());
        assertEquals("João Silva", saved.getName());
    }

    @Test
    void shouldThrowExceptionForDuplicateCpf() {
        // Arrange: Criar primeiro cliente
        Customer first = new Customer();
        first.setName("Cliente 1");
        first.setCpf("123.456.789-00");
        customerService.save(first);

        // Act & Assert: Tentar criar com CPF duplicado
        Customer duplicate = new Customer();
        duplicate.setName("Cliente 2");
        duplicate.setCpf("123.456.789-00");

        assertThrows(DataIntegrityViolationException.class,
            () -> customerService.save(duplicate));
    }
}

🔄 Migrations com Flyway

As migrations rodam automaticamente ao iniciar a aplicação.


🛠️ Solução de Problemas Na Conexão com o MySQL

Erro: "Can't connect to MySQL server"

# Verificar se MySQL está rodando
mysql -u root -p

# Testar conexão
telnet localhost 3306

Erro: "Access denied for user"

# Verificar credenciais no application.properties
# Resetar permissões no MySQL
GRANT ALL PRIVILEGES ON pharmacy_db.* TO 'pharmacy_user'@'localhost';
FLUSH PRIVILEGES;

Erro: "Illegal base64 character"

Motivo: JWT_SECRET inválido
Solução: Usar string sem caracteres especiais ou base64 válido

Porta 8080 já em uso

# Finder qual processo usa a porta
lsof -i :8080

# Mudar porta no application.properties
server.port=8081

📖 Estrutura de Projeto

pharmacy-api/
├── src/main/java/com/limasantos/pharmacy/api/
│   ├── customer/              # 👥 Módulo de Clientes
│   │   ├── controller/
│   │   ├── service/
│   │   ├── repository/
│   │   ├── entity/
│   │   └── dto/
│   ├── product/               # 📦 Módulo de Produtos
│   ├── supplier/              # 🏭 Módulo de Fornecedores
│   ├── inventory/             # 📊 Módulo de Estoque
│   │   ├── entity/
│   │   ├── enums/
│   │   └── service/
│   ├── sales/                 # 🛒 Módulo de Vendas
│   ├── financial/             # 💰 Módulo Financeiro
│   ├── user/                  # 🔐 Módulo de Usuários
│   ├── test/                  # 🧪 Endpoints de Teste
│   ├── shared/                # 🔄 Recursos Compartilhados
│   │   ├── dto/
│   │   ├── enums/
│   │   ├── exception/
│   │   ├── filter/
│   │   └── security/
│   └── config/                # ⚙️ Configurações
│       ├── security/
│       └── swagger/
├── src/main/resources/
│   ├── application.properties
│   ├── application-dev.properties
│   └── db/migration/          # 🗄️ Scripts Flyway
├── src/test/java/             # 🧪 Testes Unitários
├── pom.xml
└── README.md

📄 Licença

MIT License © 2026 - Lucas Lima Santos

Este projeto não é um projeto OpenSource. Veja LICENSE para detalhes completos.


👨‍💻 Autor

Guilherme Lima


Version

✅ v1.0.0 (Atual)

  • CRUD completo de clientes, produtos, fornecedores
  • Gestão de estoque com lotes e validade
  • Vendas integradas
  • Gestão financeira básica
  • Autenticação JWT com roles

Versão: 1.0.0 | Atualizado: 23 de Abril de 2026 |

About

Pharmacy API RESTful with a Spring Boot backend and React frontend, allowing control of customers, products, inventory, sales, and financial management of accounts payable and receivable.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages