Solavel Solavel Docs

Account types — Company vs Independent

docs/solavel/account-types.md

Who can use this: Workspace owners (deciding) + anyone curious (reading) URL / Route: chosen at invitation time on /portal/users/create Plan / feature gate: Always on

The two-type model

Every team member in your workspace belongs to one of exactly two account types. The type decides who owns their global account, what workspace-wide capabilities they can ever have, and how much of their profile you can edit.

Type Owner of the account Workspace-wide capabilities Per-org role Typical example
🏢 Company Your workspace Optional Workspace builder Yes An employee at name@acme.com
🤝 Independent The user themselves Never Yes A contractor at name@gmail.com, an external accountant at name@theirfirm.com

There is no third type. The old "Customer / Vendor / Employee" trichotomy has been retired. Everything reduces to: do you own their account, or do they?

When to choose Company

Pick Company when:

  • The user has a @your-company-domain email address
  • They're an employee (W-2 / on payroll / part of your org chart)
  • You want them able to receive Workspace builder rights
  • You want their account to live entirely inside your workspace

Effects of Company:

  • They show up in your workspace's Team page as a Company employee
  • Workspace owners can grant them the Workspace builder toggle (see Workspace builder)
  • Their global Spatie role is set to the highest org role you grant them — so making them a per-org Owner makes them client_owner globally
  • You can manage their company-side fields (display name, etc.) from the workspace

When to choose Independent

Pick Independent when:

  • The user has their own email at their own domain
  • They're a contractor, accountant, freelancer, partner, or external consultant
  • They might be working with other workspaces too — their account shouldn't be tied to yours

Effects of Independent:

  • They show up in your workspace's Team page as Independent
  • You cannot grant them Workspace builder or any other workspace-wide capability
  • Their global Spatie role is preserved when you change their per-org role — making them Owner in one of your orgs does NOT promote them to client_owner globally
  • They can leave your workspace and join another without losing their account

What stays the same

Regardless of type, both share the same per-org capabilities:

  • Per-org role (Owner / Manager / Member / Viewer) — same options
  • Per-org rules (Manage team, Manage settings, Manage billing) — driven by role, identical for both
  • Project access inside organizations — controlled per-project, same rules

So if you just want someone to "use Solabooks in Org A as a Member", the type barely matters. Pick Company if you own their email, Independent if you don't.

How the type is set

  1. At invitation time. When you create a new invitation at /portal/users/create, the form selects the type based on the invitee's email domain matching clients.company_domains. You can override before sending.
  2. It's locked after acceptance. Once the user accepts and creates their account, the type is the type. You don't toggle it later.
  3. For existing users who got migrated. Solavel migrated all pre-Phase-6 users into Company by default for the original workspace they were attached to.

Permissions you can manage

You can manage on a Company user You can manage on an Independent user
Workspace builder toggle (Workspace builder is never available)
Per-org role in any org you own Per-org role in any org you own
Per-project access in any org you own Per-project access in any org you own
Display name (workspace-side)

You can never manage an Independent user's:

  • Email or password (it's their account)
  • Display name on their personal account
  • Membership in other workspaces

Database / code

  • Account type lives on users.account_type (company / independent)
  • Defaulted at signup based on email-domain match against the workspace's clients.company_domains
  • Enforced by EmployeePortalControlsService::isCompanyAccount() and isIndependentAccount()
  • Independent-user role preservation lives in ClientUserController — when changing org role, the global Spatie role sync is skipped for Independent users

See also

Source: docs/solavel/account-types.md ← All documentation