General
Organizations

Data Model

Learn how organizations are modeled in the monorepo.

Diagram

OrganizationidmembershipsPKMembershiporganizationIduserIdroleisOwnerFKFKUseridmembershipsPK10..n0..n1

Organization

The data model of an organization looks like the following (simplified):

packages/database/prisma/schema.prisma
model Organization {  id                  String       @id(map: "PK_Organization") @default(uuid()) @db.Uuid  slug                String       @unique @db.VarChar(255)  logo                String?      @db.VarChar(2048)  name                String       @db.VarChar(255)  memberships         Membership[]}

Notice the memberships field? We don't directly connect an organization to users, but use an intermediate table.

Membership

Memberships allow a user to join multiple organizations. A membership looks like the following:

packages/database/prisma/schema.prisma
model Membership {  id                String         @id(map: "PK_Membership") @default(uuid()) @db.Uuid  organizationId    String         @db.Uuid  userId            String         @db.Uuid  role              Role           @default(MEMBER)  isOwner           Boolean        @default(false)  user              User           @relation(fields: [userId], references: [id], onDelete: Cascade, onUpdate: Cascade)  organization      Organization   @relation(fields: [organizationId], references: [id], onDelete: Cascade, onUpdate: Cascade)  @@unique([organizationId, userId])}

Notice the role field? A user can be an admin in one organization and member in another one.

Roles

Roles are saved in the membership table. Following roles are available:

packages/database/prisma/schema.prisma
enum Role {  MEMBER @map("member")  ADMIN  @map("admin")}

You can of course define more roles, but we recommend to keep the amount of roles to a minimum.

Rename organizations

The starter kit uses "organizations" to represent a group of users, but this term may not align with your application's domain, even if the underlying data model is similar.

For instance, you might prefer to refer to them as "Teams" or "Workspaces." In this case, we recommend keeping "organization" as the technical term in your codebase (to avoid renaming every instance) and updating the labels in the UI. To implement this, simply update all instances of "Organization" to your preferred term.

Isolation level

All organizations are saved in the same database with organizationId as tenant separator. It's possible to create a database per organization with a global catalog database, but it requires some modification. In that case we can recommend multiple schemas instead of databases, since one database is always easier to maintain.