Skip to content

Organizations Backend Implementation

Backend implementation for multi-tenant organization functionality using Better Auth.

Architecture

Organizations are managed by Better Auth's organization plugin, integrated with AdonisJS and PostgreSQL.

Client Request → Better Auth → PostgreSQL → Response

                   Redis (Session Cache)

Data Models

The organization feature uses the following models:

  • Organization - Multi-tenant workspaces with owner, slug for URL routing, and optional metadata
  • Member - Organization membership records with role-based access (owner, admin, member)
  • Team - Sub-groups within organizations for grouping members
  • Invitation - Pending organization invitations with expiry and status tracking

For complete schema details, field definitions, database structure, and relationships, see:

Better Auth Configuration

Organizations are configured in apps/server/app/lib/auth.ts:

typescript
import { organization } from 'better-auth/plugins'

export const auth = betterAuth({
  // ... other config
  plugins: [
    organization({
      // Organization plugin configuration
      allowUserToCreateOrganization: true,
      organizationRole: ['owner', 'admin', 'member'],
      creatorRole: 'owner',
      invitationExpiryTime: 60 * 60 * 24 * 7, // 7 days
    }),
  ],
})

Session Context

Active Organization

Sessions track the active organization for workspace context:

typescript
class Session {
  // ... other fields
  activeOrganizationId: string | null // Current workspace
}

This allows:

  • Automatic organization scoping for queries
  • Quick workspace switching without re-authentication
  • Organization-specific permissions checking

API Endpoints

All organization endpoints are handled by Better Auth through the /auth/organization/* routes:

Organization Management

  • POST /auth/organization/create - Create new organization
  • PATCH /auth/organization/update - Update organization details
  • DELETE /auth/organization/delete - Delete organization (owner only)
  • GET /auth/organization/list - List user's organizations
  • POST /auth/organization/set-active - Switch active organization

Member Management

  • POST /auth/organization/invite - Send invitation
  • POST /auth/organization/accept-invitation - Accept invitation
  • POST /auth/organization/remove-member - Remove member
  • PATCH /auth/organization/update-member-role - Change member role
  • GET /auth/organization/members - List organization members

Team Management

  • POST /auth/organization/create-team - Create team
  • PATCH /auth/organization/update-team - Update team
  • DELETE /auth/organization/delete-team - Delete team
  • POST /auth/organization/add-team-member - Add member to team

Resources (Future)

All resources will include organizationId for multi-tenant isolation.

Best Practices

  1. Always check organization context in protected routes
  2. Validate permissions before sensitive operations
  3. Use Better Auth's built-in methods rather than custom implementation when possible
  4. Cache organization list on frontend for quick switching

Built with ❤️ by the Jubiloop team