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
└── ...