Pular para conteúdo

ADR-006 — Schema ams no PostgreSQL para Isolamento de Contexto de Módulos

Status: ✅ Aceito Data: 2026-06-12

Contexto

O AMia Core utiliza um único banco de dados PostgreSQL. Até o início do módulo AMS, todas as tabelas de domínio residiam no schema core (Coding: projetos, epics, features, work items, sprints, etc.) gerenciadas por um único AMiaDbContext.

Com a criação do módulo AMS (Sustentação), novas entidades serão adicionadas: Client, Attendant, Faq, FaqQualityEvaluation, Document, ChatSession. Foi necessário decidir como organizar essas tabelas no banco de dados.

Alternativas avaliadas

# Opção Descrição
A Mesmo schema core Adicionar todas as entidades AMS no schema core existente, sem separação física.
B Banco de dados separado Criar um banco PostgreSQL dedicado para o módulo AMS.
C Schema ams dedicado (escolhida) Criar o schema ams no mesmo banco, mantendo o DbContext único mas com mapeamento de schema por entidade.

Decisão

Criar o schema ams no PostgreSQL existente e mapear todas as entidades do módulo AMS nesse schema via Entity Framework Core (.ToTable("nome", "ams")).

Justificativa

Isolamento lógico sem complexidade operacional

Um schema PostgreSQL é uma unidade de isolamento lógico: permite GRANT/REVOKE por schema, backup seletivo (pg_dump --schema=ams), restauração parcial e auditoria de acesso por módulo — sem o overhead de provisionar e gerenciar um segundo banco (conexões, credenciais, monitoramento, custos de Azure Database).

Ausência de joins cross-módulo

As entidades AMS são autossuficientes: Client, Attendant, Faq e Document não possuem foreign keys para tabelas do schema core. A única referência cruzada é UserId, que aponta para o Object ID do Azure AD (string), não para uma FK de banco — portanto não há joins cross-schema em produção.

Suporte nativo no Entity Framework Core

O EF Core suporta multi-schema nativamente via .ToTable("tabela", "schema") nas IEntityTypeConfiguration<T>. A migration de criação usa migrationBuilder.EnsureSchema("ams"), que gera CREATE SCHEMA IF NOT EXISTS ams. Não é necessário segundo DbContext, segunda connection string ou qualquer biblioteca adicional.

Governança e evolução

À medida que o produto cresce, a separação por schema permite: - Row-Level Security diferenciada por schema para futuras integrações de terceiros - Replicação seletiva — replicar apenas o schema ams para ambientes de atendimento sem expor dados de engenharia (schema core) - Eventual extração — se o módulo AMS crescer o suficiente para justificar um banco próprio, as tabelas já estão logicamente agrupadas, simplificando a migração

Por que não banco separado

  • Aumenta o custo de infraestrutura Azure (segunda instância PostgreSQL Flexible Server)
  • Exige segunda connection string, segundo DbContext, possível segunda pipeline de migration
  • O volume de dados do AMS na v1 não justifica separação física
  • Sem joins cross-banco garante que a eventual separação futura seja uma decisão deliberada, não forçada por limitações técnicas

Consequências

Positivas: - Tabelas AMS claramente identificadas por prefixo de schema (ams.Client, ams.Faq, etc.) - AMiaDbContext permanece único — sem duplicação de infraestrutura de repositório - Backup e restauração seletiva do módulo AMS habilitados nativamente pelo PostgreSQL - GRANT de acesso ao schema ams pode ser concedido ao serviço amIA-Ingest sem expor o schema core

Negativas: - Desenvolvedores precisam especificar o schema em queries manuais e ferramentas de DB GUI - Migrations devem sempre incluir EnsureSchema("ams") para evitar falhas em ambientes novos

Convenções derivadas desta decisão: - Toda IEntityTypeConfiguration<T> de entidade AMS deve declarar .ToTable("NomeDaTabela", "ams") em Configure() - As entidades transversais (User, Role, Permission) permanecem sem schema explícito (EF Core usa o schema default public ou o schema definido pelo HasDefaultSchema do contexto) - O AMiaDbContext não deve receber um HasDefaultSchema("ams") global — apenas as entidades AMS recebem o schema individualmente, preservando o comportamento das entidades core existentes

Mapeamento de schemas

PostgreSQL Database: amia
├── schema: core          ← módulo Coding (existente)
│   ├── Project
│   ├── Epic
│   ├── Feature
│   ├── WorkItem
│   ├── Iteration
│   └── ...
├── schema: ams           ← módulo AMS (novo)
│   ├── Client
│   ├── Attendant
│   ├── Faq
│   ├── FaqQualityEvaluation
│   ├── Document
│   └── ChatSession
└── schema: public        ← entidades transversais
    ├── User
    ├── Role
    ├── Permission
    └── ...