Topologia de bancos
O conceito estrutural do produto. Cada organização tem dois bancos próprios, e existe um banco de plano de controle para toda a plataforma. Decisão em adr-001-banco-por-org.
| Banco | Cluster | Quantidade | Conteúdo |
|---|---|---|---|
appstock_core | db-app (5450) | 1 na plataforma | Plano de controle: ent-organizacao, ent-user-directory, org_databases, org_modules, ent-sync-token, provisioning_log. |
app_<slug> | db-app | 1 por organização | Portal: usuários, perfis, permissões, ofertas, links públicos, widgets, Dictionary Studio, contas de e-mail. 70 migrations Alembic. |
sync_<slug> | db-sync (5441) | 1 por organização | Espelho do ERP: 51 tabelas + 13 views do template db/sync_template.sql. Read-only para o app. |
Como o app chega no banco certo
org_databases guarda o DSN de cada banco (kind = app ou sync), com unicidade por
(org_id, kind). db/tenants.py lê essa tabela e mantém um registro de engines por
(org_id, kind), criadas sob demanda e cacheadas por processo.
get_db() entrega a sessão do app_<org> corrente; get_sync_db() entrega a do sync_<org>.
As assinaturas nunca mudaram — foi o que permitiu virar ~100 arquivos de rotas para multi-tenant
sem tocá-los.
Detalhe de isolamento: o pool do espelho tem pool_timeout=10 de propósito. Consulta pesada
esgota o pool daquela organização e falha rápido, em vez de enfileirar e contaminar as outras.
Regras
- Nenhuma query cross-org fora do plano de controle. Não existe caminho legítimo para uma organização enxergar dado de outra.
- O espelho é read-only para o app. Quem escreve nele é o mod-sync-ingest, com o token da organização. Exceção conhecida: o ajuste de campos da NF pela gestão, que grava direto — e é frágil por isso.
- O UUID da organização é o mesmo no core e no
app_<org>. Não há de-para.
Quem depende disto
| Nota | Tipo | Status |
|---|---|---|
| README | — | — |
| Um banco por organização, não um schema nem uma coluna | decisao | — |
| O ERP do cliente nunca é consultado ao vivo | decisao | — |
| Organização | entidade | — |
| Onboarding da organização | fluxo | Parcial |
| Primeira carga de dados | fluxo | Parcial |
| Resolução de tenant | fluxo | Parcial |
| Provisionamento de organização | modulo | Parcial |
| Ingestão do sincronizador | modulo | Parcial |
Buracos conhecidos
appstock_coresem migrations. Nasce porcreate_allno bootstrap. Ver mod-provision.org_modulesgravado e nunca lido. Ver mod-organizations.- 19 das 51 tabelas do espelho não são ingeríveis. Ver flx-primeira-carga.
- Sem backup por organização e sem observabilidade. Multi-tenant sem backup significa que a primeira perda de dado de cliente é descoberta pelo cliente.