# Mapeamento da camada de dados — Parte 2

## Princípio adotado
A camada de dados do portal principal usa **diretamente o schema central aprovado**, sem criar modelo paralelo para clientes, usuários, catálogo, billing ou integração.

## Repositórios por agregado

### Clientes e conta
- `ClientRepository`
  - `clientes`
- `UserRepository`
  - `usuarios_plataforma`
- `MembershipRepository`
  - `clientes_usuarios`
- `InvitationRepository`
  - `convites_plataforma`
- `SessionRepository`
  - `sessoes_plataforma`
- `AuditRepository`
  - `logs_plataforma`

### Catálogo comercial
- `CatalogRepository`
  - `produtos`
  - `planos`
  - `plano_produto`
  - `precos_plano_produto`
  - `precos_plano_produto_gateways`
  - `gateways_pagamento`
  - `cupons_desconto`

### Assinaturas e billing
- `SubscriptionRepository`
  - `assinaturas`
  - `assinatura_itens`
  - `trials`
  - `cupom_usos`
- `BillingRepository`
  - `faturas`
  - `fatura_itens`
  - `pagamentos`

### Entitlement e instâncias
- `AccessRepository`
  - `acessos_produto`
  - `instancias_produto_cliente`

### Integração assíncrona e observabilidade
- `IntegrationRepository`
  - `jobs_provisionamento_produto`
  - `eventos_outbox_integracao`
  - `tentativas_webhook_saida`
  - `fila_dead_letter`
  - `logs_integracao`

### Operação da plataforma
- `AdminRepository`
  - leitura agregada sobre clientes, usuários, assinaturas, acessos, faturas, jobs, outbox e logs
- `HealthRepository`
  - valida presença das tabelas críticas da V2
- `ProductRepository`
  - leitura operacional usada pelo portal web atual para catálogo, dashboard, trials, acessos e instâncias do cliente

## Serviços transacionais implementados

### `CentralReadService`
Disponibiliza leitura consolidada de:
- clientes
- usuários da plataforma
- memberships
- convites
- produtos
- planos
- ofertas comerciais (`plano_produto`)
- preços
- gateways
- cupons
- assinaturas
- itens de assinatura
- trials
- faturas
- itens de fatura
- pagamentos
- acessos de produto
- instâncias de produto
- jobs de provisionamento
- outbox
- logs de integração
- dead letters
- logs de plataforma

### `AccountRegistrationService`
Fluxo de escrita para cadastro inicial de conta:
- cria `clientes`
- cria `usuarios_plataforma`
- cria `clientes_usuarios`
- audita em `logs_plataforma`

### `InvitationService`
Fluxo de convite:
- cria `convites_plataforma`
- aceita convite com vínculo em `clientes_usuarios`
- revoga/cancela convite
- audita em `logs_plataforma`

### `AccountManagementService`
Fluxo de gestão básica de conta:
- atualiza dados cadastrais em `clientes`
- atualiza dados de usuário em `usuarios_plataforma`
- faz transições de status em:
  - `clientes`
  - `usuarios_plataforma`
  - `clientes_usuarios`
  - `assinaturas`
  - `assinatura_itens`
  - `faturas`
  - `acessos_produto`
  - `instancias_produto_cliente`
  - `convites_plataforma`
- audita em `logs_plataforma`

### `SubscriptionLifecycleService`
Fluxo de contratação central:
- valida contexto comercial real do preço
- valida gateway/preço
- valida cupom, vigência e limites de uso
- cria `assinaturas`
- cria `assinatura_itens`
- cria `trials` quando aplicável
- cria `cupom_usos` quando aplicável
- cria `faturas`
- cria `fatura_itens`
- cria `acessos_produto` quando a contratação já gera entitlement
- cria `instancias_produto_cliente` quando aplicável
- cria `jobs_provisionamento_produto`
- cria `eventos_outbox_integracao`
- registra `logs_integracao`
- audita em `logs_plataforma`

## Tratamento de erro
- `AbstractCentralRepository` encapsula exceções de PDO em `DatabaseException`.
- O log de erro de integração com banco sai em `storage/logs/app.log` sem vazar DSN, usuário ou senha.
- `ErrorHandler` agora diferencia:
  - `ValidationException` → 422
  - `DomainException` → 409
  - `DatabaseException`/PDO → 503

## Observações importantes do schema usadas na implementação
- `assinatura_itens.permite_multiplas_ativas_snapshot` passou a ser preenchido pela camada de contratação.
- `instancias_produto_cliente.permite_multiplas_instancias_snapshot` é persistido a partir do snapshot do produto.
- `acessos_produto` continua sendo a base real de entitlement do portal principal.
- `eventos_outbox_integracao` é tratado como persistência confiável de integração, sem acoplamento imediato com workers nesta fase.
- `logs_plataforma` e `logs_integracao` foram mantidos separados, seguindo o desenho aprovado do banco.

## Escopo explícito das tabelas centrais ainda não consumidas integralmente

### `mfa_recovery_codes` — fora de escopo do portal por enquanto
- O portal principal não possui repositório, serviço ou UX para emissão, listagem, regeneração ou consumo de recovery codes.
- O MFA funcional desta fase usa `mfa_fatores` com suporte operacional a `email_otp`.
- A tabela foi mantida no checklist mínimo do `HealthRepository` por ser dependência estrutural do schema central aprovado, não por já existir suporte completo no portal.

### `plano_produto_modulos` — fora de escopo do portal por enquanto
- A contratação atual resolve catálogo e entitlement em `plano_produto`, `assinaturas`, `assinatura_itens`, `acessos_produto` e, quando aplicável, `instancias_produto_cliente`.
- O portal ainda não deriva direitos por matriz plano × módulo a partir de `plano_produto_modulos`.
- `modulos_produto` aparece hoje apenas em leitura operacional pontual, quando um acesso já possui `modulo_produto_id`; isso não configura consumo funcional de `plano_produto_modulos`.

### `segredos_plataforma` — suporte incremental mínimo
- O portal **não** lê o material secreto armazenado nessa tabela e não implementa CRUD, rotação ou descriptografia.
- O suporte atual é estrutural: readiness exige a presença da tabela e o portal preserva referências seguras usadas indiretamente por MFA e gateways.
- A gestão operacional do segredo permanece responsabilidade do banco central e das rotinas de infraestrutura.

### `segredos_plataforma_versoes` — suporte incremental mínimo
- O portal depende da integridade referencial dessa tabela para estruturas como gateways e fatores MFA que apontam para `segredo_versao_id`.
- Em contexto administrativo, o portal pode exibir o identificador da versão vinculada, mas não materializa o segredo e não cria novas versões.
- Essa decisão mantém compatibilidade com o schema central sem expandir o escopo do portal para cofre/secret manager.

### Resumo de decisão arquitetural
- `mfa_recovery_codes` → gap consciente, fora do escopo atual do portal.
- `plano_produto_modulos` → gap consciente, reservado para comercialização modular futura.
- `segredos_plataforma` → suporte incremental mínimo, sem leitura do valor secreto.
- `segredos_plataforma_versoes` → suporte incremental mínimo, com leitura apenas de referência segura.

## SQL complementar
Nenhum SQL complementar obrigatório foi adicionado nesta fase, porque o schema aprovado já contém as estruturas necessárias para a camada de dados pedida.

## Seed
Nenhum seed artificial foi imposto ao banco central aprovado.
Para operações locais, a criação de dados reais de teste pode ser feita pelos scripts CLI adicionados nesta fase.
