diff --git a/src/auth/roles.test.ts b/src/auth/roles.test.ts new file mode 100644 index 0000000..95131d1 --- /dev/null +++ b/src/auth/roles.test.ts @@ -0,0 +1,58 @@ +/** + * Which workspace a roleid lands in — and the one that has been mislabelled on + * every shop since the platform started. + * + * `app_roles` calls roleid 1 "Super admin", and tenant onboarding wrote 1 for a + * merchant's own administrator. So every shop's Users & access screen listed + * its owner as a platform operator. It never WAS one — platform access is + * `app_users.issuperadmin`, a separate column checked first — but the label is + * the sort of thing somebody eventually acts on. + * + * New tenants get roleid 3 ("Admin"). Existing ones keep 1, and must keep + * working: nine shops were provisioned with it. + */ +import assert from 'node:assert/strict'; +import { test } from 'node:test'; +import { resolveRole } from './roles'; + +test('platform access comes from issuperadmin, never from a roleid', () => { + assert.equal(resolveRole({ roleid: 0, issuperadmin: true }), 'nearle-admin'); + // The point of the whole fix: roleid 1 is a merchant, not a platform operator. + assert.equal(resolveRole({ roleid: 1, issuperadmin: false }), 'store-admin'); +}); + +test('a merchant administrator reaches the Store Admin workspace', () => { + // 3 is what new tenants get; 1 is what every existing tenant has. + assert.equal(resolveRole({ roleid: 3, issuperadmin: false }), 'store-admin'); + assert.equal(resolveRole({ roleid: 1, issuperadmin: false }), 'store-admin'); +}); + +/* +Existing merchants must not be locked out. Nine shops were provisioned with +roleid 1 before this changed, and dropping it from the store-admin set would +shut every one of their owners out of their own console. +*/ +test('roleid 1 keeps working, so no existing merchant is locked out', () => { + assert.notEqual(resolveRole({ roleid: 1, issuperadmin: false }), 'store-manager'); +}); + +test('a manager is pinned to one shop', () => { + // 4 is "Manager" in app_roles, and what the old console gave rmartuser. + assert.equal(resolveRole({ roleid: 4, issuperadmin: false }), 'store-manager'); +}); + +// The auto-spawned branch login carries roleid 0 — Go's zero value, and the +// branch-user role. It must land in the shop workspace, not the merchant's. +test('the branch login lands in the store workspace', () => { + assert.equal(resolveRole({ roleid: 0, issuperadmin: false }), 'store-manager'); +}); + +/* +Till accounts must never reach a back-office workspace. They are excluded in the +backend's queries too — a cashier is "not found" rather than "refused" — but a +roleid arriving from anywhere else must not resolve upward. +*/ +test('till roles never resolve to a merchant workspace', () => { + assert.equal(resolveRole({ roleid: 7, issuperadmin: false }), 'store-manager'); + assert.equal(resolveRole({ roleid: 8, issuperadmin: false }), 'store-manager'); +}); diff --git a/src/features/store-admin/PeopleDrawers.tsx b/src/features/store-admin/PeopleDrawers.tsx index 687d33f..b2907d4 100644 --- a/src/features/store-admin/PeopleDrawers.tsx +++ b/src/features/store-admin/PeopleDrawers.tsx @@ -182,7 +182,6 @@ function Problem({ message }: { message: string }) { const STAFF_ROLES = [ { id: 3, label: 'Administrator — runs the whole business' }, { id: 4, label: 'Manager — one shop' }, - { id: 5, label: 'Staff — one shop' }, ]; export function PersonDrawer({