Escopo e accessContext

req.accessContext carrega a identidade verificada; os helpers de escopo aplicam isolamento de tenant e usuário em consultas e mutações próprias.

Toda rota autenticada recebe req.accessContext, criado pelo backend depois de verificar o token no escopo do App, resolver tenant e acesso e aplicar o RBAC. É a única fonte de identidade para filtros e mutações.

Helpers de escopo

const { mergeScopedFilter } = require("@oondemand/oon-core-back");
const pessoa = require("../models/Pessoa");

// Dentro de um handler privado já autenticado/autorizado:
const filter = mergeScopedFilter(pessoa, { ativo: true }, req.accessContext);
const total = await pessoa.mongooseModel.countDocuments(filter);
Helper Assinatura Uso
scopeFilter (entryOrDefinition, accessContext) Filtro obrigatório de tenant/usuário
mergeScopedFilter (entryOrDefinition, filter, accessContext) Acrescenta escopo confiável a filtros de negócio
scopedIdFilter (entryOrDefinition, id, accessContext) Busca por ID dentro do escopo
scopeMutation (entryOrDefinition, data, accessContext) Impõe identidade confiável ao payload

Comportamento por scope da model:

  • tenant — contexto sem tenant é recusado.
  • user — filtra por tenant (quando o App tem tenant) e por usuário.
  • legacy/system — não produzem filtro de isolamento.

Os helpers não autenticam, não concedem permissão e não validam regras de domínio.

Boas práticas

  • Nunca repasse req.query ou operadores Mongo arbitrários para find.
  • Mutação direta pelo Mongoose não passa pelo pipeline de validação, processo e auditoria do CRUD. Prefira o CRUD ou reproduza as garantias necessárias.
  • createAccessContext estrutura uma identidade já verificada — não verifica token nem autentica um body. Prefira req.accessContext.
  • readRequestedTenantId(req) lê a seleção solicitada, sem autenticá-la.

Constantes

const { TENANT_HEADER, TENANCY_MODELS, DATA_SCOPES } = require("@oondemand/oon-core-back");
// TENANT_HEADER = "x-oon-tenant-id"
// TENANCY_MODELS = ["none", "single_tenant", "multi_tenant"]
// DATA_SCOPES = ["legacy", "system", "tenant", "user"]

Contexto de dados × autorização

Em Apps licenciados single-tenant, req.accessContext.tenantId é o tenant de dados; authorizationTenantId identifica a organização da concessão. Use apenas o accessContext confirmado para filtros e mutações. Veja Tipos de App e tenancy.