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).
| 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 |
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
MySQL 8.0+ Banco de dados relacional
Flyway Versionamento de schema
Hibernate Mapeamento objeto-relacional
Auth0 JWT Tokens JWT
OpenAPI 3.0 Especificação de API
SpringDoc Swagger/OpenAPI integrado
Maven 3.9+ Build e dependências
Lombok Redução de boilerplate
JUnit 5 Testes unitários
✅ Java 17 ou superior
✅ Maven 3.9 ou superior
✅ MySQL 8.0 ou superior
✅ Gitgit clone https://github.com/limasantos/pharmacy-api.git
cd pharmacy-apiCrie 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;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# Instalar dependências
mvn clean install
# Executar aplicação
mvn spring-boot:runPronto! Acesse: http://localhost:8080
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
POST /api/auth/register # Registrar novo usuário
POST /api/auth/login # Login e obter JWT
POST /api/auth/refresh # Renovar token expiradoGET /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} # RemoverGET /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} # RemoverGET /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)GET /api/financials # Lançamentos (filtro: tipo, status)
POST /api/financials # Criar lançamento
PUT /api/financials/{id} # Atualizar
GET /api/financials/overdue # Contas vencidasGET /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 pagamentoGET /api/suppliers # Listar fornecedores
POST /api/suppliers # Cadastrar (validação CNPJ)
PUT /api/suppliers/{id} # Atualizar
DELETE /api/suppliers/{id} # RemoverGET /api/test/health # Verificar saúde da API
GET /api/test/greet/{name} # Saudação personalizada
POST /api/test/echo # Echo do payload1. 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
| Role | Permissões |
|---|---|
| ROLE_ADMIN | Acesso total, gerenciar usuários, relatórios |
| ROLE_CAIXA | Vendas, clientes, estoque (leitura), consultas |
✅ 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
Visualize em: dbdiagram.io
├── id (UUID, PK)
├── username (VARCHAR UNIQUE, NOT NULL)
├── password (VARCHAR, NOT NULL - bcrypt)
├── role (ENUM: ROLE_ADMIN, ROLE_CAIXA)
└── email (VARCHAR UNIQUE, NOT NULL)├── 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)├── id (BIGINT, PK)
├── name (VARCHAR, NOT NULL)
└── cpf (VARCHAR UNIQUE, validated)├── id (BIGINT, PK)
├── product_id (BIGINT, FK)
├── lotNumber (VARCHAR)
├── entryDate (DATE, auto-generated)
├── expirationDate (DATE)
└── quantity (INTEGER)├── 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)├── 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)├── 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){
"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"
}
}{
"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"
}
]
}{
"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
}
}# ==================== 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=86400000export 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"# Todos os testes
mvn test
# Teste específico
mvn test -Dtest=CustomerServiceTest
# Com cobertura de código
mvn test jacoco:report@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));
}
}As migrations rodam automaticamente ao iniciar a aplicação.
# Verificar se MySQL está rodando
mysql -u root -p
# Testar conexão
telnet localhost 3306# Verificar credenciais no application.properties
# Resetar permissões no MySQL
GRANT ALL PRIVILEGES ON pharmacy_db.* TO 'pharmacy_user'@'localhost';
FLUSH PRIVILEGES;Motivo: JWT_SECRET inválido
Solução: Usar string sem caracteres especiais ou base64 válido
# Finder qual processo usa a porta
lsof -i :8080
# Mudar porta no application.properties
server.port=8081pharmacy-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
MIT License © 2026 - Lucas Lima Santos
Este projeto não é um projeto OpenSource. Veja LICENSE para detalhes completos.
Guilherme Lima
- 💼 LinkedIn: linkedin.com/in/guilhermelima-dev
- 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 |