For Quality
What to test
Core behavior
- As an owner (
DO_ALLpermission), log in on two devices/browsers with two
different staff accounts in the same company, both with push notification registration (or a mocked pushNotifications array populated in the DB for test purposes, since real Expo tokens require a physical/registered device).
- From one session, trigger Logout All Users (Settings → Security tab,
or mobile More menu) and confirm.
- Verify:
- Both sessions are immediately invalidated (any subsequent authenticated
request fails / redirects to login).
- Both users'
User.pushNotificationsarrays are now empty in the
database.
- The corresponding
UserSessionrows for both users are deleted.
Regression checks (make sure this didn't change unrelated behavior)
- Individual logout (
logoutmutation) still only removes the specific
device's token (via args.pushNotification), not the whole array, and still only affects the logging-out device/session.
- Patients are untouched: trigger
logoutOutAllUsersfor a company and
confirm Patient.pushNotifications for that company's patients is unchanged.
- Cross-company isolation: trigger
logoutOutAllUsersfor Company A and
confirm Company B's users' pushNotifications arrays are untouched (the where: { company: { id } } filter should scope correctly).
- Permission gate: confirm a non-
DO_ALLuser cannot call
logoutOutAllUsers at all (existing permission rule, not changed by this PR, but worth re-confirming alongside this change).
Where the edges are
- Users with an empty
pushNotificationsarray already.set: []on an
already-empty array should be a no-op, not an error — worth a quick check since Prisma's updateMany with set: [] on a String[] should handle this safely, but confirm no exception is thrown for companies with zero push-registered users.
- Large companies.
updateManyruns once for the whole company
regardless of user count, so this shouldn't introduce a performance concern, but it's worth confirming timing on a company with a large staff roster (the sandbox seed uses seed=rich, which is a reasonable stand-in).
- Ordering with session deletion. The push-token clear happens before
userSession.deleteMany in the mutation. If a future edit reorders these or wraps them in a transaction, make sure a failure partway through doesn't leave sessions dead but tokens still populated (or vice versa) — currently these are sequential, non-transactional awaits, so a failure between steps is possible in theory (e.g. DB blip after the push-token clear but before session-row deletion). Worth flagging if strict atomicity is expected here, since the PR doesn't wrap these calls in prisma.$transaction, unlike some other mutations in the same file (e.g. updateAuthDetails, confirm2FAToken).
Manual sandbox notes
The "Logout All Users" button and its confirmation popover are visible at Settings → Account → Security tab for the owner seed user (see Walkthrough for screenshots). Confirming it in the sandbox will actually terminate every session for that sandbox company — coordinate before doing this in a shared sandbox, since it will also sign out anyone else currently testing there.