Organization / workspace membership
Users belong to teams, and permissions live on the membership rather than the person. One login, different roles in different workspaces.
See it
What it is
Membership is a join between a user and an organization, and the role lives on that join, not on the user. Ana is an owner of Acme and a viewer of Beta with the same login. The moment you put 'role' as a column on the users table, you have quietly built a single-team product.
Reach for it the first time someone asks to invite a colleague. The usual shape: an organizations table, a memberships table (user_id, org_id, role, status), invites that exist before the user does, and an 'active organization' stored on the session so every query and every page knows which tenant it is serving. Slack, Notion, Linear, and Stripe all expose this as a workspace switcher.
Gotcha: authorization has to ask two questions, not one. 'Is this person logged in and an admin?' is not enough; it must be 'is this person an admin of the org that owns this record?' Miss the second half and any customer admin can edit any other customer's data. Also decide early what happens when the last owner leaves, because someone will try it.
Ask AI for it
Model multi-tenant team accounts: add organizations, memberships (user_id, org_id, role of owner/admin/member, status), and invites keyed by email so a person can be invited before they have an account. Store the active organization on the session, scope every query by org_id, and write the permission check as 'is this user a member of the org that owns this record, with a sufficient role'. Add a workspace switcher in the header and block removal of the last owner.