Skip to content

Accounts

leadr.accounts

Modules:

leadr.accounts.adapters

Modules:

  • orm – Account and User ORM models.
leadr.accounts.adapters.orm

Account and User ORM models.

Classes:

leadr.accounts.adapters.orm.AccountORM

Bases: Base

Account ORM model.

Represents an organization or team in the database. Maps to the accounts table with unique name and slug constraints.

Attributes:

# leadr.accounts.adapters.orm.AccountORM.created_at
created_at: Mapped[timestamp]
# leadr.accounts.adapters.orm.AccountORM.deleted_at
deleted_at: Mapped[nullable_timestamp]
# leadr.accounts.adapters.orm.AccountORM.id
id: Mapped[uuid_pk]
# leadr.accounts.adapters.orm.AccountORM.name
name: Mapped[str] = mapped_column(String, nullable=False, unique=True, index=True)
# leadr.accounts.adapters.orm.AccountORM.slug
slug: Mapped[str] = mapped_column(String, nullable=False, unique=True, index=True)
# leadr.accounts.adapters.orm.AccountORM.status
status: Mapped[AccountStatusEnum] = mapped_column(Enum(AccountStatusEnum, name='account_status', native_enum=True, values_callable=(lambda x: [(e.value) for e in x])), nullable=False, default=(AccountStatusEnum.ACTIVE), server_default='active')
# leadr.accounts.adapters.orm.AccountORM.updated_at
updated_at: Mapped[timestamp] = mapped_column(onupdate=(func.now()))
# leadr.accounts.adapters.orm.AccountORM.users
users: Mapped[list[UserORM]] = relationship(back_populates='account', cascade='all, delete-orphan')
leadr.accounts.adapters.orm.AccountStatusEnum

Bases: str, Enum

Account status enum for database.

Attributes:

# leadr.accounts.adapters.orm.AccountStatusEnum.ACTIVE
ACTIVE = 'active'
# leadr.accounts.adapters.orm.AccountStatusEnum.SUSPENDED
SUSPENDED = 'suspended'
leadr.accounts.adapters.orm.UserORM

Bases: Base

User ORM model.

Represents a user within an account in the database. Maps to the users table with foreign key to accounts.

Attributes:

# leadr.accounts.adapters.orm.UserORM.account
account: Mapped[AccountORM] = relationship(back_populates='users')
# leadr.accounts.adapters.orm.UserORM.account_id
account_id: Mapped[UUID] = mapped_column(ForeignKey('accounts.id', ondelete='CASCADE'), nullable=False, index=True)
# leadr.accounts.adapters.orm.UserORM.created_at
created_at: Mapped[timestamp]
# leadr.accounts.adapters.orm.UserORM.deleted_at
deleted_at: Mapped[nullable_timestamp]
# leadr.accounts.adapters.orm.UserORM.display_name
display_name: Mapped[str] = mapped_column(String, nullable=False)
# leadr.accounts.adapters.orm.UserORM.email
email: Mapped[str] = mapped_column(String, nullable=False, unique=True, index=True)
# leadr.accounts.adapters.orm.UserORM.id
id: Mapped[uuid_pk]
# leadr.accounts.adapters.orm.UserORM.super_admin
super_admin: Mapped[bool] = mapped_column(nullable=False, default=False, server_default='false')
# leadr.accounts.adapters.orm.UserORM.updated_at
updated_at: Mapped[timestamp] = mapped_column(onupdate=(func.now()))

leadr.accounts.api

Modules:

leadr.accounts.api.account_routes

Account API routes.

Functions:

Attributes:

leadr.accounts.api.account_routes.create_account
create_account(request, service, auth)

Create a new account.

Only superadmins can create accounts.

Parameters:

Returns:

  • AccountResponse – AccountResponse with the created account including auto-generated ID and timestamps.

Raises:

  • 403 – User does not have permission to create accounts.
leadr.accounts.api.account_routes.get_account
get_account(account_id, service, auth)

Get an account by ID.

Parameters:

Returns:

Raises:

  • 403 – User does not have access to this account.
  • 404 – Account not found.
leadr.accounts.api.account_routes.list_accounts
list_accounts(service, auth, pagination, slug=None)

List accounts with pagination and optional filtering.

Superadmins see all accounts (paginated). Regular users see only their own account.

Filtering:

  • Use ?slug={slug} to find a specific account by its slug

Pagination:

  • Default: 20 items per page, sorted by created_at:desc,id:asc
  • Custom sort: Use ?sort=name:asc,created_at:desc
  • Valid sort fields: id, name, slug, created_at, updated_at
  • Navigation: Use next_cursor/prev_cursor from response
Example GET /v1/accounts?slug=acme-corp GET /v1/accounts?limit=50&sort=name:asc

Parameters:

Returns:

Raises:

  • 400 – Invalid cursor, sort field, or cursor state mismatch.
  • 404 – Account not found when filtering by slug.
leadr.accounts.api.account_routes.router
router = APIRouter()
leadr.accounts.api.account_routes.update_account
update_account(account_id, request, service, auth)

Update an account.

Supports updating name, slug, status, or soft-deleting the account. Status changes (active/suspended) are handled through dedicated service methods.

Parameters:

Returns:

Raises:

  • 403 – User does not have access to this account.
  • 404 – Account not found.
leadr.accounts.api.account_schemas

API request and response models for accounts.

Classes:

leadr.accounts.api.account_schemas.AccountCreateRequest

Bases: BaseModel

Request model for creating an account.

Attributes:

# leadr.accounts.api.account_schemas.AccountCreateRequest.name
name: str = Field(description='Account name (2-100 characters)')
# leadr.accounts.api.account_schemas.AccountCreateRequest.slug
slug: str | None = Field(default=None, description='Optional URL-friendly slug (globally unique). If not provided, will be auto-generated from name')
leadr.accounts.api.account_schemas.AccountResponse

Bases: BaseModel

Response model for an account.

Functions:

  • from_domain – Convert domain entity to response model.

Attributes:

# leadr.accounts.api.account_schemas.AccountResponse.created_at
created_at: datetime = Field(description='Timestamp when the account was created (UTC)')
# leadr.accounts.api.account_schemas.AccountResponse.from_domain
from_domain(account)

Convert domain entity to response model.

Parameters:

  • account (Account) – The domain Account entity to convert.

Returns:

  • AccountResponse – AccountResponse with all fields populated from the domain entity.
# leadr.accounts.api.account_schemas.AccountResponse.id
id: AccountID = Field(description='Unique identifier for the account')
# leadr.accounts.api.account_schemas.AccountResponse.name
name: str = Field(description='Account name')
# leadr.accounts.api.account_schemas.AccountResponse.slug
slug: str = Field(description='URL-friendly identifier')
# leadr.accounts.api.account_schemas.AccountResponse.status
status: AccountStatus = Field(description='Current account status')
# leadr.accounts.api.account_schemas.AccountResponse.updated_at
updated_at: datetime = Field(description='Timestamp of last update (UTC)')
leadr.accounts.api.account_schemas.AccountUpdateRequest

Bases: BaseModel

Request model for updating an account.

Attributes:

# leadr.accounts.api.account_schemas.AccountUpdateRequest.deleted
deleted: bool | None = Field(default=None, description='Set to true to soft delete the account')
# leadr.accounts.api.account_schemas.AccountUpdateRequest.name
name: str | None = Field(default=None, description='Updated account name')
# leadr.accounts.api.account_schemas.AccountUpdateRequest.slug
slug: str | None = Field(default=None, description='Updated URL-friendly identifier')
# leadr.accounts.api.account_schemas.AccountUpdateRequest.status
status: AccountStatus | None = Field(default=None, description='Account status (active, suspended, deleted)')
leadr.accounts.api.user_routes

User API routes.

Functions:

Attributes:

leadr.accounts.api.user_routes.create_user
create_user(request, service, auth)

Create a new user.

Creates a new user associated with an existing account.

For regular users, account_id must match their API key's account. For superadmins, any account_id is accepted.

Parameters:

Returns:

  • UserResponse – UserResponse with the created user including auto-generated ID and timestamps.

Raises:

  • 403 – User does not have access to the specified account.
  • 404 – Account not found.
leadr.accounts.api.user_routes.get_user
get_user(user_id, service, auth)

Get a user by ID.

Parameters:

Returns:

Raises:

  • 403 – User does not have access to this user's account.
  • 404 – User not found.
leadr.accounts.api.user_routes.list_users
list_users(auth, service, pagination, account_id=None)

List users for an account with pagination.

For regular users, account_id is automatically derived from their API key. For superadmins, account_id is optional - if omitted, returns users from all accounts.

Pagination:

  • Default: 20 items per page, sorted by created_at:desc,id:asc
  • Custom sort: Use ?sort=email:asc,created_at:desc
  • Valid sort fields: id, email, display_name, created_at, updated_at
  • Navigation: Use next_cursor/prev_cursor from response
Example GET /v1/users?account_id=acc_123&limit=50&sort=email:asc

Parameters:

Returns:

Raises:

  • 400 – Invalid cursor, sort field, or cursor state mismatch.
  • 403 – User does not have access to the specified account.
leadr.accounts.api.user_routes.router
router = APIRouter()
leadr.accounts.api.user_routes.update_user
update_user(user_id, request, service, auth)

Update a user.

Supports updating email, display name, or soft-deleting the user.

Parameters:

Returns:

  • UserResponse – UserResponse with the updated user details.

Raises:

  • 403 – User does not have access to this user's account.
  • 404 – User not found.
leadr.accounts.api.user_schemas

API request and response models for users.

Classes:

leadr.accounts.api.user_schemas.UserCreateRequest

Bases: BaseModel

Request model for creating a user.

Attributes:

# leadr.accounts.api.user_schemas.UserCreateRequest.account_id
account_id: AccountID = Field(description='ID of the account this user belongs to')
# leadr.accounts.api.user_schemas.UserCreateRequest.display_name
display_name: str = Field(description="User's display name (2-100 characters)")
# leadr.accounts.api.user_schemas.UserCreateRequest.email
email: EmailStr = Field(description="User's email address (must be valid email format)")
leadr.accounts.api.user_schemas.UserResponse

Bases: BaseModel

Response model for a user.

Functions:

  • from_domain – Convert domain entity to response model.

Attributes:

# leadr.accounts.api.user_schemas.UserResponse.account_id
account_id: AccountID = Field(description='ID of the account this user belongs to')
# leadr.accounts.api.user_schemas.UserResponse.created_at
created_at: datetime = Field(description='Timestamp when the user was created (UTC)')
# leadr.accounts.api.user_schemas.UserResponse.display_name
display_name: str = Field(description="User's display name")
# leadr.accounts.api.user_schemas.UserResponse.email
email: str = Field(description="User's email address")
# leadr.accounts.api.user_schemas.UserResponse.from_domain
from_domain(user)

Convert domain entity to response model.

Parameters:

  • user (User) – The domain User entity to convert.

Returns:

  • UserResponse – UserResponse with all fields populated from the domain entity.
# leadr.accounts.api.user_schemas.UserResponse.id
id: UserID = Field(description='Unique identifier for the user')
# leadr.accounts.api.user_schemas.UserResponse.super_admin
super_admin: bool = Field(description='Whether this user has superadmin privileges')
# leadr.accounts.api.user_schemas.UserResponse.updated_at
updated_at: datetime = Field(description='Timestamp of last update (UTC)')
leadr.accounts.api.user_schemas.UserUpdateRequest

Bases: BaseModel

Request model for updating a user.

Attributes:

# leadr.accounts.api.user_schemas.UserUpdateRequest.deleted
deleted: bool | None = Field(default=None, description='Set to true to soft delete the user')
# leadr.accounts.api.user_schemas.UserUpdateRequest.display_name
display_name: str | None = Field(default=None, description='Updated display name')
# leadr.accounts.api.user_schemas.UserUpdateRequest.email
email: EmailStr | None = Field(default=None, description='Updated email address')
# leadr.accounts.api.user_schemas.UserUpdateRequest.super_admin
super_admin: bool | None = Field(default=None, description='Set superadmin privileges (true/false)')

leadr.accounts.domain

Modules:

  • account – Account domain model.
  • user – User domain model.
leadr.accounts.domain.account

Account domain model.

Classes:

leadr.accounts.domain.account.Account

Bases: Entity

Account domain entity.

Represents an organization or team that owns games and manages users. Accounts have a unique name and URL-friendly slug, and can be active or suspended.

Functions:

  • activate – Activate the account, allowing access.
  • restore – Restore a soft-deleted entity.
  • soft_delete – Mark entity as soft-deleted.
  • suspend – Suspend the account, preventing access.
  • validate_name – Validate account name length and format.
  • validate_slug – Validate slug format (lowercase alphanumeric with hyphens).

Attributes:

# leadr.accounts.domain.account.Account.activate
activate()

Activate the account, allowing access.

# leadr.accounts.domain.account.Account.created_at
created_at: datetime = Field(default_factory=(lambda: datetime.now(UTC)), description='Timestamp when entity was created (UTC)')
# leadr.accounts.domain.account.Account.deleted_at
deleted_at: datetime | None = Field(default=None, description='Timestamp when entity was soft-deleted (UTC), or null if active')
# leadr.accounts.domain.account.Account.id
id: AccountID = Field(frozen=True, default_factory=AccountID, description='Unique account identifier')
# leadr.accounts.domain.account.Account.is_deleted
is_deleted: bool

Check if entity is soft-deleted.

Returns:

  • bool – True if the entity has a deleted_at timestamp, False otherwise.
# leadr.accounts.domain.account.Account.model_config
model_config = ConfigDict(validate_assignment=True)
# leadr.accounts.domain.account.Account.name
name: str
# leadr.accounts.domain.account.Account.restore
restore()

Restore a soft-deleted entity.

Clears the deleted_at timestamp, making the entity active again.

Example > > > account.soft_delete() > > > account.restore() > > > assert account.is_deleted is False
# leadr.accounts.domain.account.Account.slug
slug: str
# leadr.accounts.domain.account.Account.soft_delete
soft_delete()

Mark entity as soft-deleted.

Sets the deleted_at timestamp to the current UTC time. Entities that are already deleted are not affected (deleted_at remains at original deletion time).

Example > > > account = Account(name="Test", slug="test") > > > account.soft_delete() > > > assert account.is_deleted is True
# leadr.accounts.domain.account.Account.status
status: AccountStatus = AccountStatus.ACTIVE
# leadr.accounts.domain.account.Account.suspend
suspend()

Suspend the account, preventing access.

# leadr.accounts.domain.account.Account.updated_at
updated_at: datetime = Field(default_factory=(lambda: datetime.now(UTC)), description='Timestamp of last update (UTC)')
# leadr.accounts.domain.account.Account.validate_name
validate_name(value)

Validate account name length and format.

# leadr.accounts.domain.account.Account.validate_slug
validate_slug(value)

Validate slug format (lowercase alphanumeric with hyphens).

leadr.accounts.domain.account.AccountStatus

Bases: Enum

Account status enumeration.

Attributes:

# leadr.accounts.domain.account.AccountStatus.ACTIVE
ACTIVE = 'active'
# leadr.accounts.domain.account.AccountStatus.SUSPENDED
SUSPENDED = 'suspended'
leadr.accounts.domain.user

User domain model.

Classes:

  • User – User domain entity.
leadr.accounts.domain.user.User

Bases: Entity

User domain entity.

Represents a user within an account (organization/team). Users are scoped to a specific account and have an email address and display name.

Each user belongs to exactly one account, and users cannot be transferred between accounts. The email must be unique within an account.

Superadmin users have elevated privileges and can access resources across all accounts in the system.

Functions:

Attributes:

# leadr.accounts.domain.user.User.account_id
account_id: AccountID = Field(frozen=True, description='ID of the account this user belongs to (immutable)')
# leadr.accounts.domain.user.User.created_at
created_at: datetime = Field(default_factory=(lambda: datetime.now(UTC)), description='Timestamp when entity was created (UTC)')
# leadr.accounts.domain.user.User.deleted_at
deleted_at: datetime | None = Field(default=None, description='Timestamp when entity was soft-deleted (UTC), or null if active')
# leadr.accounts.domain.user.User.display_name
display_name: str = Field(description="User's display name (2-100 characters)")
# leadr.accounts.domain.user.User.email
email: EmailStr = Field(description="User's email address (validated format)")
# leadr.accounts.domain.user.User.id
id: UserID = Field(frozen=True, default_factory=UserID, description='Unique user identifier')
# leadr.accounts.domain.user.User.is_deleted
is_deleted: bool

Check if entity is soft-deleted.

Returns:

  • bool – True if the entity has a deleted_at timestamp, False otherwise.
# leadr.accounts.domain.user.User.model_config
model_config = ConfigDict(validate_assignment=True)
# leadr.accounts.domain.user.User.restore
restore()

Restore a soft-deleted entity.

Clears the deleted_at timestamp, making the entity active again.

Example > > > account.soft_delete() > > > account.restore() > > > assert account.is_deleted is False
# leadr.accounts.domain.user.User.soft_delete
soft_delete()

Mark entity as soft-deleted.

Sets the deleted_at timestamp to the current UTC time. Entities that are already deleted are not affected (deleted_at remains at original deletion time).

Example > > > account = Account(name="Test", slug="test") > > > account.soft_delete() > > > assert account.is_deleted is True
# leadr.accounts.domain.user.User.super_admin
super_admin: bool = Field(default=False, description='Whether this user has superadmin privileges')
# leadr.accounts.domain.user.User.updated_at
updated_at: datetime = Field(default_factory=(lambda: datetime.now(UTC)), description='Timestamp of last update (UTC)')
# leadr.accounts.domain.user.User.validate_display_name
validate_display_name(value)

Validate display name length and format.

Parameters:

  • value (str) – The display name to validate.

Returns:

  • str – The validated and trimmed display name.

Raises:

  • ValueError – If display name is empty, too short, or too long.