Dados · infrastructure/db
Adapter pronto para produçãoPrisma,
com guardrails.
O bug clássico de multi-tenancy é uma query que esquece o organizationId e serve em silêncio as linhas de outro cliente. A UseDeploy envolve o cliente do Prisma em um tenant guard que transforma esse erro em uma exceção em tempo de execução — não em um vazamento de dados em produção.
Dois clientes: guardado por padrão
Os repositórios recebem o cliente guardado. Qualquer leitura ou mutação em um modelo scoped por tenant cujo where não restrinja organizationId lança TenantScopeViolationError. Existe um cliente de sistema separado e nomeado de forma explícita para os caminhos legítimos entre tenants (workers, lookups de token, export GDPR), então todo bypass é grepável.
1 export const getPrismaClient = (): PrismaClient => {
2 if (!guardedClient) {
3 guardedClient = applyTenantGuard(getBaseClient());
4 }
5 return guardedClient;
6 };
7
8 // Unguarded, explicit, greppable — for workers / token lookups only:
9 export const getSystemPrismaClient = () => getBaseClient();
Por que importa
Falha alto, não em silêncio
Esquecer o scope de org em código novo lança na primeira execução em vez de vazar linhas entre tenants — o modo de falha que você quer.
Lista explícita de modelos
TENANT_SCOPED_MODELS enumera cada modelo pertencente a uma org. Adicionar um novo ao schema significa adicioná-lo aqui — um passo deliberado e revisável.
Um único connection pool
O cliente guardado e o de sistema compartilham o pool do cliente base, então o guard não custa conexões extras.
Amigável com poolers
DIRECT_URL é suportada para o pgbouncer do Supabase e poolers similares, onde as migrations precisam de uma conexão direta.
Referência de configuração
Variáveis de ambiente
DATABASE_URLobrigatóriaPostgres connection string
DIRECT_URLopcionaldirect connection when DATABASE_URL is a pooler
Onde ele vive
apps/server/src/infrastructure/db/prisma-client.tsapps/server/src/infrastructure/db/tenant-guard.ts
Dados multi-tenant que falham seguro.
Construa sobre um cliente do Prisma que transforma um scope de org esquecido em uma exceção, não em um vazamento.