zazzy
Features

Organizations

Org-scoped tenancy — memberships, roles, and invites.

Organizations add multi-tenancy on top of auth via Better Auth's organization plugin. Every user belongs to one or more orgs; the app's data is scoped to the session's active organization, and members carry a role (owner / member). The UI ships an org switcher, an org settings surface (general, members, invites, danger zone), and an invitation-accept flow.

Core feature

Orgs is a core feature (core: true, requires: ["auth"]). It is never pruned: the app is org-scoped by construction, and most optional features hang their data off an Organization.

What it does

  • TenancySession.activeOrganizationId scopes requests; orgProcedure reads it server-side. A session defaults to the user's personal org.
  • Memberships & roles — an owner plus members (Membership.role), surfaced in OrgSettings → members table.
  • Invites — email invitations (Invite) with pending/accepted status and an expiry; the row id is the credential (acceptInvitation({ invitationId })).
  • SwitchingOrgSwitcher changes the active org on the session.
  • Danger zone — rename, and org deletion with the usual guards.

Models it adds

Better Auth's organization plugin models, with modelName overrides keeping the friendlier names (prisma/schema.prisma):

ModelPurpose
OrganizationThe tenant: name, unique slug, logo, metadata.
MembershipUser ↔ org link carrying role.
InvitePending email invitation (email, role, status, expiry, inviter).

Session.activeOrganizationId (a bare column, not a relation) tracks the scoped org. Organization is also the anchor for optional features' data — subscription, flagOverrides, usageEvents, apiKeys, files, auditLogs are all marker-wrapped relations that prune with their features.

Env it needs

None.

Composition

  • requires: ["auth"] — memberships and invites reference User.
  • Dependents — nearly every optional feature requires orgs, directly or transitively: billing, api-keys, files, audit-log, admin (directly), and flags, usage, marketing (through billing).
  • billing hooks membership changes: the orgs add/remove-member mutations call enqueueSeatsSync behind @feature:billing markers to reconcile Stripe seat quantity.
  • email renders the org-invite template through enqueueEmail at a marked call site (console fallback when email is pruned).

What pruning removes

Nothing — orgs is core and cannot be deselected. What does prune is the set of @feature-marked cross-relations other features attach to Organization; each disappears with its own feature, leaving Organization/Membership/Invite intact.

On this page