Pular para conteúdo

🏗️ 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/filial
  • BranchService - Operações com filiais
  • CompanyService - Operações com empresas
  • CompanyOptionsService - Configurações da empresa
  • GroupService - Grupos de usuários
  • RoutineService - Rotinas do sistema
  • RoutineAccessService - Permissões de acesso
  • UserCompanyBranchService - Permissões usuário x empresa x filial
  • UserGroupService - Associação usuário x grupo

Repositories (14)

  • AccountbalanceRepository - Saldos de contas
  • MonthlyAccountBalanceRepository - Saldos mensais
  • DailyAccountBalanceRepository - Saldos diários
  • ChartOfAccountsRepository - Plano de contas
  • InquiryRepository - Queries customizadas para razão geral
  • CompanyOptionsRepository - Opções da empresa
  • CompanyRepository - Empresas
  • BranchRepository - 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:

  1. Verifica se usuário tem acesso direto (UserCompanyBranch)
  2. Verifica grupos do usuário (UserGroup)
  3. Verifica permissões herdadas de grupos
  4. Retorna 403 Forbidden se não tiver acesso

📈 Performance

Otimizações

  • Queries customizadas em InquiryRepository com 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

  1. Repository Pattern - Abstração de acesso a dados
  2. Service Layer - Lógica de negócio isolada
  3. DTO Pattern - Separação entre entidades JPA e DTOs de API
  4. 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