Fair Supply LogoFair Supply - Docs

Accounts Domain

The Accounts domain handles multi-tenancy, user management, and authentication through Auth0 integration.

Entity Hierarchy

Key Concepts

EntityDescription
AccountTop-level tenant container (like a company). All data is scoped to an account.
UserIndividual person. Can belong to multiple accounts with different roles.
SessionTracks which account a user currently has selected (stored in Redis).
Auth0 OrganisationExternal SSO tenant in Auth0, linked 1:1 with Account.

Multi-Tenancy Model

Users can belong to multiple accounts, each with a specific role:

RolePermissions
adminFull access, can manage members
memberStandard access, can view and edit
viewerRead-only access

Account Selection Flow

  • Session stores selectedAccountId - all queries scope to this account
  • Switching accounts updates the session, not the user record
  • Sessions are stored in Redis with TTL-based expiration

Business Rules

  1. Users must belong to at least one account
  2. Users with multiple accounts must select one before proceeding
  3. Admins can manage members; members can view only
  4. New users must complete registration before accessing features
  5. Account names should stay in sync with Auth0 org names
  6. Sessions expire after inactivity (TTL-based)

Common Operations

Getting Current User Session

import { getSession } from '@repo/core';

const session = await getSession();
// session.userId - current user
// session.selectedAccountId - active account

Creating a New Account

import { CreateAccount } from '@repo/core';

const useCase = new CreateAccount();
const account = await useCase.execute({
  name: 'Acme Corp',
  adminEmail: 'admin@acme.com',
});

Adding a User to an Account

import { AddUserToAccount } from '@repo/core';

const useCase = new AddUserToAccount();
await useCase.execute({
  accountId: 'account-123',
  email: 'user@example.com',
  role: 'member',
});

Switching Accounts

import { SwitchAccount } from '@repo/core';

const useCase = new SwitchAccount();
await useCase.execute({
  accountId: 'account-456',
});
// Session now scoped to new account

Auth0 Integration

Account creation and user management sync with Auth0:

Platform ActionAuth0 Action
Create accountCreate Auth0 Organisation
Add userInvite to Auth0 Organisation
Remove userRemove from Auth0 Organisation
Update account nameUpdate Auth0 Organisation name

Important Considerations

  • Auth0 API calls cannot be rolled back in transactions
  • If Neo4j write succeeds but Auth0 fails, handle orphaned records
  • Use background jobs for Auth0 sync when possible
TypeLocation
GraphQL Schemapackages/core/src/infrastructure/neo4j/schemas/account.graphql
Repositorypackages/core/src/infrastructure/repositories/account-repository.ts
Use Casespackages/core/src/application/use-cases/account/
Auth0 Integrationpackages/core/src/infrastructure/auth0/
Session Managementpackages/core/src/infrastructure/redis/session.ts