Source code for src.share_kernel.domain.multitenant_value_objects
"""Shared value objects used across bounded contexts.
All value objects are immutable frozen dataclasses defined by their attributes,
without identity of their own.
"""
from __future__ import annotations
from dataclasses import dataclass
from enum import StrEnum
from uuid import UUID
[docs]
@dataclass(frozen=True, slots=True)
class TenantId:
"""Typed wrapper around a tenant UUID identifier."""
value: UUID
def __str__(self) -> str:
return str(self.value)
[docs]
@dataclass(frozen=True, slots=True)
class UserId:
"""Typed wrapper around a user UUID identifier."""
value: UUID
def __str__(self) -> str:
return str(self.value)
[docs]
@dataclass(frozen=True, slots=True)
class PolicyId:
"""Typed wrapper around a policy UUID identifier."""
value: UUID
def __str__(self) -> str:
return str(self.value)
[docs]
class PolicyEffect(StrEnum):
"""The effect of a policy when it matches."""
ALLOW = "allow"
DENY = "deny"
[docs]
class ActionType(StrEnum):
"""Standard ABAC actions mapped from DRF viewset actions."""
LIST = "list"
READ = "read"
CREATE = "create"
UPDATE = "update"
DELETE = "delete"
WILDCARD = "*"
[docs]
class TenantStatus(StrEnum):
"""Possible statuses for a tenant."""
ACTIVE = "active"
SUSPENDED = "suspended"
ARCHIVED = "archived"
[docs]
class MembershipStatus(StrEnum):
"""Possible statuses for a tenant membership."""
ACTIVE = "active"
INVITED = "invited"
SUSPENDED = "suspended"
[docs]
class ApprovalStatus(StrEnum):
"""Possible statuses for an approval request."""
PENDING = "pending"
APPROVED = "approved"
REJECTED = "rejected"
EXPIRED = "expired"
CANCELLED = "cancelled"
EXECUTION_FAILED = "execution_failed"
[docs]
class PolicyScope(StrEnum):
"""Where a policy is stored and applies."""
GLOBAL = "global"
TENANT = "tenant"
[docs]
class IsolationBackendType(StrEnum):
"""Available tenant isolation strategies."""
SCHEMA = "schema"
RLS = "rls"
SHARED_FK = "shared_fk"
class AsyncBackendMode(StrEnum):
"""Available async backend modes."""
CELERY = "celery"
SYNC = "sync"
AUTO = "auto"
# DRF action to ABAC action mapping
DRF_ACTION_MAPPING: dict[str, str] = {
"list": "list",
"retrieve": "read",
"create": "create",
"update": "update",
"partial_update": "update",
"destroy": "delete",
}