Workspace Invitations

Learn about the invitation system for managing workspace members and collaboration.

Invitation Schema

Database

The invitation system uses a PostgreSQL table with the following structure:

Schema Definition

Database schema for invitations:

export const invitations = pgTable("invitation", {
  // Primary identifier
  id: text("id").primaryKey().$defaultFn(() => crypto.randomUUID()),
  
  // Invitation details
  email: text("email").notNull(),
  invitedBy: text("invited_by").notNull(),
  invitedByProfileImage: text("invited_by_profile_image").notNull(),
  
  // Workspace reference
  workspaceId: text("workspace_id")
    .notNull()
    .references(() => workspaces.id, { onDelete: "cascade" }),
  
  // Role assignment
  role: text("role")
    .notNull()
    .$type<RoleTypesType>()
    .default("member"),
  
  // Status flags
  pending: boolean("pending").notNull().default(true),
  expired: boolean("expired").notNull().default(false),
  
  // Security
  token: text("token").notNull(),
  
  // Timestamps
  acceptedAt: timestamp("accepted_at"),
  expiresAt: timestamp("expires_at").notNull(),
  createdAt: timestamp("created_at").notNull().defaultNow(),
  updatedAt: timestamp("updated_at").defaultNow(),
})

Invitation Flow

1

Send Invitation

Workspace admin sends invitation with specified role

2

Email Delivery

Invitation email sent with secure token

3

Accept Invitation

Recipient accepts via email link before expiration

4

Member Creation

New workspace member created with assigned role

Key Features

Security

Secure tokens and expiration for invitations

Role Assignment

Specify member roles during invitation

Cascade Deletion

Automatic cleanup with workspace deletion

Status Tracking

Monitor pending and expired invitations

Invitation States

Pending

Invitation sent but not yet accepted

pending: trueexpired: falseacceptedAt: null

Accepted

Successfully accepted invitation

pending: falseexpired: falseacceptedAt: timestamp

Expired

Invitation past expiration date

pending: trueexpired: trueacceptedAt: null

Completed

Member added to workspace

pending: falseexpired: falseacceptedAt: timestamp