fix(access): honor finance sections and team-member data scope

Role treasury keys now open the first allowed finance page, and team-member ownership limits lists, dashboard, and reports instead of the whole organization.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-11-09 11:20:20 +03:30
co-authored by Cursor
parent 3c9b906bd6
commit 0e1bc4a1fe
15 changed files with 243 additions and 64 deletions
+12 -6
View File
@@ -21,6 +21,7 @@ import type {
import { canManageSettings, canViewAllRecords } from '@/lib/roles';
import {
canOpenPath,
firstAllowedFinancePath,
hasSectionPermission,
sectionPermissionForPath,
} from '@/lib/section-permissions';
@@ -204,12 +205,11 @@ function cardAllowedForNav(card: {
}) {
if (card.ownerOnly && auth.user?.role !== 'owner') return false;
const perms = auth.user?.permissions ?? [];
const canTreasury = auth.user?.role === 'owner'
|| auth.user?.role === 'admin'
|| perms.includes('treasury')
|| perms.some((key) => key.startsWith('treasury_'));
if (card.to?.startsWith('/finance')) {
return moduleAllowed(card.module ?? 'treasury') && canTreasury;
return (
moduleAllowed(card.module ?? 'treasury')
&& Boolean(firstAllowedFinancePath(auth.user?.role, perms))
);
}
const section = card.to ? sectionPermissionForPath(card.to) : null;
const hasSection = section
@@ -246,7 +246,13 @@ const openHub = computed<NavHubDef | null>(() => {
if (!openHubKey.value) return null;
const hub = NAV_HUBS.find((item) => item.key === openHubKey.value);
if (!hub) return null;
const cards = hub.cards.filter((card) => cardAllowedForNav(card));
const financeTo = firstAllowedFinancePath(auth.user?.role, auth.user?.permissions);
const cards = hub.cards
.filter((card) => cardAllowedForNav(card))
.map((card) => {
if (!financeTo || !card.to.startsWith('/finance') || card.to === financeTo) return card;
return { ...card, to: financeTo };
});
if (
hub.key === 'customers' &&
isMobileNav.value &&