🏗️ Arquitetura - ecosif-querys
📋 Visão Geral
ecosif-querys é um microserviço Spring Boot especializado em consultas otimizadas de dados contábeis. Diferente dos outros serviços, este foca exclusivamente em operações de leitura (queries), fornecendo endpoints otimizados para visualização e relatórios.
🎯 Objetivo do Serviço
- ✅ Consultas otimizadas de saldos e movimentações
- ✅ Performance para grandes volumes de dados
- ✅ Separar responsabilidades de escrita vs leitura
- ✅ Cache e otimizações específicas para queries
🏛️ Arquitetura em Camadas
┌─────────────────────────────────────────────────────────┐
│ Controllers (REST) │
│ • BalanceInquiryController │
│ - POST /balanceInquiryDetails │
│ - POST /generalLedgerQuery │
│ - GET /allChartOfAccount/{company}/{branch} │
└────────────────────┬────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Services (Lógica) │
│ • AccessValidationService │
│ • BalanceInquiryService (implícito) │
│ • ChartOfAccountsService │
└────────────────────┬────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Repositories (JPA) │
│ • AccountbalanceRepository │
│ • MonthlyAccountBalanceRepository │
│ • ChartOfAccountsRepository │
│ • InquiryRepository │
│ • ... (14 repositories) │
└────────────────────┬────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ ecosif-database (Biblioteca) │
│ • Accountbalance • MonthlyAccountBalance │
│ • ChartOfAccounts • CompanyOptions │
│ • ... (52+ entidades) │
└────────────────────┬────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ PostgreSQL Database │
│ • Tabelas contábeis │
│ • Índices otimizados para queries │
└─────────────────────────────────────────────────────────┘
📦 Estrutura de Pacotes
io.ecosif.querys
├── company/
│ ├── controller/ # 1 controller REST
│ │ └── BalanceInquiryController.java
│ ├── service/ # 13 services
│ │ ├── AccessValidationService.java
│ │ ├── BranchService.java
│ │ ├── CompanyService.java
│ │ ├── CompanyOptionsService.java
│ │ └── ... (9 mais)
│ ├── repository/ # 14 repositories JPA
│ │ ├── AccountbalanceRepository.java
│ │ ├── MonthlyAccountBalanceRepository.java
│ │ ├── ChartOfAccountsRepository.java
│ │ ├── InquiryRepository.java
│ │ └── ... (10 mais)
│ └── dto/ # 13 DTOs
│ ├── BalanceInquiryRequestDTO.java
│ ├── BalanceInquiryResponseDTO.java
│ ├── GeneralLedgerQueryRequestDTO.java
│ ├── GeneralLedgerQueryResponseDTO.java
│ └── ... (9 mais)
├── config/ # Configurações Spring
│ ├── OpenApiConfig.java
│ ├── WebSecurityConfig.java
│ └── ...
├── security/ # Segurança e autenticação
└── user/ # Usuários
🔄 Fluxos de Consulta
Fluxo 1: Consulta de Saldo
sequenceDiagram
participant Client as Cliente
participant Controller as BalanceInquiryController
participant AccessService as AccessValidationService
participant OptionsRepo as CompanyOptionsRepository
participant BalanceRepo as MonthlyAccountBalanceRepository
participant AccountRepo as AccountbalanceRepository
participant DB as PostgreSQL
Client->>Controller: POST /balanceInquiryDetails
Controller->>Controller: Valida entrada (@Valid)
Controller->>AccessService: validateUserAccess(user, empresa, filial)
AccessService->>AccessService: Verifica UserCompanyBranch
AccessService-->>Controller: Acesso válido
Controller->>OptionsRepo: findByCompanyAndBranch(empresa, filial)
OptionsRepo->>DB: SELECT * FROM ct_controle
DB-->>OptionsRepo: CompanyOptions
OptionsRepo-->>Controller: Options
Controller->>Controller: Calcula baseYearMonth
Controller->>BalanceRepo: findAccountBalanceByYearAndMonthRange(...)
BalanceRepo->>DB: SELECT * FROM ct_plano_saldo WHERE...
DB-->>BalanceRepo: List<MonthlyAccountBalance>
BalanceRepo-->>Controller: Balances
alt anomesini == baseYearMonth
Controller->>AccountRepo: findByCompanyAndBranchAndContaId(...)
AccountRepo->>DB: SELECT * FROM ct_plsaldos
AccountRepo-->>Controller: Accountbalance (saldo inicial)
else anomesini != baseYearMonth
Controller->>BalanceRepo: findInitialAccountBalanceByInitialYearMonth(...)
BalanceRepo->>DB: SELECT saldo acumulado anterior
BalanceRepo-->>Controller: Saldo anterior
end
Controller->>Controller: Monta resposta com saldos
Controller-->>Client: 200 OK (List<BalanceInquiryResponseDTO>)
Fluxo 2: Consulta de Razão Geral
sequenceDiagram
participant Client as Cliente
participant Controller as BalanceInquiryController
participant AccessService as AccessValidationService
participant InquiryRepo as InquiryRepository
participant DB as PostgreSQL
Client->>Controller: POST /generalLedgerQuery
Controller->>Controller: Valida entrada (@Valid)
Controller->>AccessService: validateUserAccess(user, empresa, filial)
AccessService-->>Controller: Acesso válido
Controller->>InquiryRepo: findAccountBalanceByYearAndMonthRange(...)
InquiryRepo->>DB: SELECT com JOIN entre ct_lancamento, ct_documentos, ct_lote, ct_plano
DB-->>InquiryRepo: ResultSet (dados agregados)
InquiryRepo-->>Controller: List<GeneralLedgerQueryResponseDTO>
Controller-->>Client: 200 OK
Fluxo 3: Listar Plano de Contas
sequenceDiagram
participant Client as Cliente
participant Controller as BalanceInquiryController
participant AccessService as AccessValidationService
participant OptionsRepo as CompanyOptionsRepository
participant ChartRepo as ChartOfAccountsRepository
participant Comparator as ChartOfAccountsComparator
participant DB as PostgreSQL
Client->>Controller: GET /allChartOfAccount/{company}/{branch}
Controller->>AccessService: validateUserAccess(user, company, branch)
AccessService-->>Controller: Acesso válido
Controller->>OptionsRepo: findByCompanyAndBranch(company, branch)
OptionsRepo->>DB: SELECT * FROM ct_controle
DB-->>OptionsRepo: CompanyOptions
OptionsRepo-->>Controller: Options (com chartOfAccount)
Controller->>ChartRepo: findByPlanOrderByCdAccountingAsc(plan)
ChartRepo->>DB: SELECT * FROM ct_plano WHERE tipo = ?
DB-->>ChartRepo: List<ChartOfAccounts>
ChartRepo-->>Controller: Charts
Controller->>Controller: Transforma em DTOs
Controller->>Comparator: Ordena numericamente
Comparator-->>Controller: List ordenada
Controller-->>Client: 200 OK (List<ChartOfAccountsDTO>)
🔧 Tecnologias e Dependências
Core
- Spring Boot 2.7.18 - Framework base
- Spring Data JPA - Persistência
- Hibernate - ORM
- PostgreSQL 15+ - Banco de dados
API e Documentação
- SpringDoc OpenAPI 3.0 - Documentação API
Segurança
- Spring Security - Autenticação/autorização
- JWT (JJWT 0.11.5) - Tokens JWT
Utilitários
- Lombok 1.18.30 - Redução de boilerplate
- ModelMapper 3.1.0 - Mapeamento DTO ↔ Entity
- Apache Commons Lang3 - Utilitários
Monitoramento
- Spring Actuator - Health checks e métricas
- Prometheus - Métricas
- Datadog APM - Application Performance Monitoring
Migrações
- Flyway - Migrações de banco de dados
📊 Componentes Principais
Controllers (1)
| Controller | Responsabilidade |
|---|---|
BalanceInquiryController |
Todos os endpoints de consulta |
Services (13)
Principais services:
AccessValidationService- Validação de acesso por empresa/filialBranchService- Operações com filiaisCompanyService- Operações com empresasCompanyOptionsService- Configurações da empresaGroupService- Grupos de usuáriosRoutineService- Rotinas do sistemaRoutineAccessService- Permissões de acessoUserCompanyBranchService- Permissões usuário x empresa x filialUserGroupService- Associação usuário x grupo
Repositories (14)
AccountbalanceRepository- Saldos de contasMonthlyAccountBalanceRepository- Saldos mensaisDailyAccountBalanceRepository- Saldos diáriosChartOfAccountsRepository- Plano de contasInquiryRepository- Queries customizadas para razão geralCompanyOptionsRepository- Opções da empresaCompanyRepository- EmpresasBranchRepository- Filiais- ... (6 mais)
🔐 Segurança
Autenticação JWT
- Token obtido via
ecosif-auth - Validação via
TokenAuthenticationFilter - Header:
Authorization: Bearer <token>
Validação de Acesso
AccessValidationService valida permissões:
- Verifica se usuário tem acesso direto (
UserCompanyBranch) - Verifica grupos do usuário (
UserGroup) - Verifica permissões herdadas de grupos
- Retorna
403 Forbiddense não tiver acesso
📈 Performance
Otimizações
- Queries customizadas em
InquiryRepositorycom JOINs otimizados - Índices no banco para campos frequentemente consultados
- Projeções específicas (DTOs) para reduzir overhead
- Sem transações pesadas (apenas leitura)
Cache (Futuro)
- Cache de
CompanyOptions(configurações raramente mudam) - Cache de plano de contas (dados relativamente estáticos)
🔄 Padrões Utilizados
- Repository Pattern - Abstração de acesso a dados
- Service Layer - Lógica de negócio isolada
- DTO Pattern - Separação entre entidades JPA e DTOs de API
- Access Control - Validação centralizada de permissões
📝 Design Decisions
Por que Serviço Separado para Consultas?
- ✅ Separação de responsabilidades - Escrita vs Leitura
- ✅ Otimizações específicas - Queries otimizadas sem overhead de escrita
- ✅ Escalabilidade - Pode escalar independentemente
- ✅ Cache específico - Estratégias de cache diferentes
Por que Validação de Acesso Centralizada?
- ✅ Reutilização - Todos os endpoints usam o mesmo serviço
- ✅ Consistência - Regras de acesso aplicadas uniformemente
- ✅ Manutenibilidade - Mudanças em um único lugar
Última Atualização: 2025-11-27