Roles & Access

Who can do what on Brainiac. Kept in sync with src/lib/roles/taxonomy.ts (runtime source of truth used by admin-side UI).

After role-model-v2 (2026-04-22) Brainiac has three public roles — Brainiac Admin, Investor, and Expert — plus an adminScope sub-field on admins that encodes what used to be the standalone staff and compliance roles.

Platform roles

Brainiac Admin

Brainiac platform operations, trust-safety, and compliance review. Cross-organization authority. Lives in the separate /admin/* surface, isolated from investor and expert bundles.

  • Manage all users, roles, and suspensions
  • View every case, call, and expert across orgs
  • Configure platform settings, fee schedules, and connectors
  • Approve expert applications and review compliance queue

Admin sub-scopes (users.adminScope):

ScopeWhat it replacesWhat the admin can do
fullthe original admin roleeverything the admin surface allows
readonlythe former staff roleobserve metrics and support logs, no mutations
compliancethe former compliance roleact on compliance surfaces, not platform-wide config

Sub-scope is enforced at the page / API layer via hasAdminScope() in src/lib/permissions.ts. The admin route group (/admin/*) admits any role=admin user; per-page gating narrows further.

Investor

Primary buyer. Always attached to an organization — auto-assigned on first sign-in:

  • Work-domain email (@acme.io) → auto-joins the org whose domains list includes that domain, or auto-creates one named for the domain.
  • Generic-domain email (Gmail, Outlook, iCloud, …) → auto-creates a personal workspace. Accepting an org invite later converts it to a team.

Capabilities:

  • Run expert searches and book calls
  • Create, share, and manage cases
  • Invite teammates to your organization (Org Admins only)
  • Send "Invite to Brainiac" magic links to off-platform experts found via the search agent

Expert

Standalone advisor. Fully isolated from the investor surface — cannot enter /cases, /experts, or /calls. Has its own portal with a messages inbox so investors can reach out without exposing case context.

  • Edit your expert profile, rate, and availability
  • See and complete call bookings
  • Reply to investor messages at /expert/inbox
  • Track earnings and payout status via Stripe Connect

Two onboarding paths:

  1. Investor-initiated invite — investor sends a magic link from an expert profile; acceptance at /i/expert/<token> flips role to expert and skips the admin approval queue (the investor's vouch is the trust signal).
  2. Self-registration — user picks "Expert" at /signup/pick-role without an accepted invite. An expert_applications row is created with status="pending_approval"; they wait at /expert/pending until a Brainiac Admin approves at /admin/expert-applications.

Organization roles

Every investor belongs to exactly one primary organization. Within an org, a user has one of two visible roles (mapped from a 4-value DB enum):

Visible roleDB org_role valuesCan
Org Adminowner, managerInvite new members, manage org settings, see every org case
Membermember, viewerCreate and work on cases; see cases shared to them

The Organization page lists members; the invite form is visible only to Org Admins.

Payment stays per-user regardless of org membership (billing is not scoped to the org).

Case-level roles

Individual cases have their own ACL, independent of org membership:

  • Owner — created the case; can share, revoke, and delete.
  • Collaborator — was shared in; can read and edit.
  • Viewer — was shared in read-only.
  • External — outside the org; access mediated by the compliance share request flow.

Where role / scope is stored

  • users.role — one of "admin" | "investor" | "expert".
  • users.adminScope"full" | "readonly" | "compliance" | null for admins; null for investor/expert.
  • users.investorType — investor sub-persona (private / public / search fund / consultant), only meaningful when role=investor.
  • org_members — links users to orgs with a 4-value orgRole + isPrimary unique constraint.
  • expert_applications — self-reg approval state (separate from invite-accepted experts).
  • expert_invites / org_invites — token-based magic links for both invite paths.
  • role_change_log — append-only audit of every role flip (self-switch, admin patch, expert onboard, etc.).