01 · Before and afterThe pattern
// service: writes
if (!isAdmin(acc) && (data.type ?? 'files') !== 'files') throw new ForbiddenError();
if (!isAdmin(acc) && await isAutomationFolder(data.parent)) throw new ForbiddenError();
// reads, plus every path that skips the service (counts, joins)
if (!isAdmin(acc)) query.filter = and(query.filter, { type: { not: 'automations' } });02 · Run it on your appThe check
If a table now holds rows for two features, can a user with access to one feature reach the other's rows through a join, a count, or a type change?
If the honest answer is no or not sure, this is worth a look before it reaches production.