Files
xiaoxia-saas/apps/api/app/dependencies.py
T
Xiaoxia AI 0f94a76258
Deploy / Deploy Staging (push) Failing after 6s
Deploy / Deploy Production (push) Has been skipped
Tests / lint (push) Has been cancelled
Tests / test (push) Has been cancelled
feat(repository): add PostgreSQL WorkspaceInvitation repository
- Implement PostgresWorkspaceInvitationRepository with full CRUD
- Support find_by_token, find_by_email, find_pending_by_email
- Auto-select implementation based on USE_IN_MEMORY_DB config
- Update DependencyContainer to support both InMemory and PostgreSQL
- Complete all PostgreSQL repository implementations

Phase 4 Task 38/68 completed
2026-06-17 08:32:24 +08:00

254 lines
10 KiB
Python

"""
依赖注入容器
管理所有 Use Cases 和 Repositories 的生命周期
"""
from packages.adapters.in_memory.user_repository import InMemoryUserRepository
from packages.adapters.in_memory.workspace_repository import InMemoryWorkspaceRepository
from packages.adapters.in_memory.workspace_member_repository import InMemoryWorkspaceMemberRepository
from packages.adapters.in_memory.workspace_invitation_repository import InMemoryWorkspaceInvitationRepository
from packages.application.auth import (
RegisterUserUseCase,
LoginUseCase,
LogoutUseCase,
VerifyEmailUseCase,
RequestPasswordResetUseCase,
ResetPasswordUseCase,
)
from packages.application.workspace import (
CreateWorkspaceUseCase,
InviteMemberUseCase,
AcceptInvitationUseCase,
DeclineInvitationUseCase,
RemoveMemberUseCase,
LeaveWorkspaceUseCase,
UpdateMemberRoleUseCase,
ListWorkspacesUseCase,
GetWorkspaceDetailUseCase,
ListMembersUseCase,
UpgradeSubscriptionUseCase,
CancelSubscriptionUseCase,
)
from packages.domain.permissions import PermissionChecker
from packages.domain.quota import QuotaChecker
class DependencyContainer:
"""依赖注入容器"""
def __init__(self):
# Repositories (单例)
self._user_repository = None
self._workspace_repository = None
self._workspace_member_repository = None
self._workspace_invitation_repository = None
self._project_repository = None
# Services
self._permission_checker = None
self._quota_checker = None
# ==================== Repositories ====================
@property
def user_repository(self):
if self._user_repository is None:
from apps.api.app.config import settings
if settings.USE_IN_MEMORY_DB:
from packages.adapters.in_memory.user_repository import InMemoryUserRepository
self._user_repository = InMemoryUserRepository()
else:
from packages.adapters.postgres.user_repository import PostgresUserRepository
self._user_repository = PostgresUserRepository(settings.DATABASE_URL)
return self._user_repository
@property
def workspace_repository(self):
if self._workspace_repository is None:
from apps.api.app.config import settings
if settings.USE_IN_MEMORY_DB:
from packages.adapters.in_memory.workspace_repository import InMemoryWorkspaceRepository
self._workspace_repository = InMemoryWorkspaceRepository()
else:
from packages.adapters.postgres.workspace_repository import PostgresWorkspaceRepository
self._workspace_repository = PostgresWorkspaceRepository(settings.DATABASE_URL)
return self._workspace_repository
@property
def workspace_member_repository(self):
if self._workspace_member_repository is None:
from apps.api.app.config import settings
if settings.USE_IN_MEMORY_DB:
from packages.adapters.in_memory.workspace_member_repository import InMemoryWorkspaceMemberRepository
self._workspace_member_repository = InMemoryWorkspaceMemberRepository()
else:
from packages.adapters.postgres.workspace_member_repository import PostgresWorkspaceMemberRepository
self._workspace_member_repository = PostgresWorkspaceMemberRepository(settings.DATABASE_URL)
return self._workspace_member_repository
@property
def workspace_invitation_repository(self):
if self._workspace_invitation_repository is None:
from apps.api.app.config import settings
if settings.USE_IN_MEMORY_DB:
from packages.adapters.in_memory.workspace_invitation_repository import InMemoryWorkspaceInvitationRepository
self._workspace_invitation_repository = InMemoryWorkspaceInvitationRepository()
else:
from packages.adapters.postgres.workspace_invitation_repository import PostgresWorkspaceInvitationRepository
self._workspace_invitation_repository = PostgresWorkspaceInvitationRepository(settings.DATABASE_URL)
return self._workspace_invitation_repository
@property
def project_repository(self):
# TODO: 实现 InMemoryProjectRepository
if self._project_repository is None:
from unittest.mock import Mock
self._project_repository = Mock()
self._project_repository.count_by_workspace = Mock(return_value=0)
return self._project_repository
# ==================== Services ====================
@property
def permission_checker(self):
if self._permission_checker is None:
self._permission_checker = PermissionChecker(
workspace_member_repository=self.workspace_member_repository,
)
return self._permission_checker
@property
def quota_checker(self):
if self._quota_checker is None:
self._quota_checker = QuotaChecker(
workspace_repository=self.workspace_repository,
project_repository=self.project_repository,
)
return self._quota_checker
# ==================== Auth Use Cases ====================
def get_register_user_use_case(self) -> RegisterUserUseCase:
return RegisterUserUseCase(
user_repository=self.user_repository,
base_url="http://localhost:3000", # TODO: 从配置读取
)
def get_login_use_case(self) -> LoginUseCase:
return LoginUseCase(
user_repository=self.user_repository,
)
def get_logout_use_case(self) -> LogoutUseCase:
return LogoutUseCase()
def get_verify_email_use_case(self) -> VerifyEmailUseCase:
return VerifyEmailUseCase(
user_repository=self.user_repository,
)
def get_request_password_reset_use_case(self) -> RequestPasswordResetUseCase:
return RequestPasswordResetUseCase(
user_repository=self.user_repository,
base_url="http://localhost:3000",
)
def get_reset_password_use_case(self) -> ResetPasswordUseCase:
return ResetPasswordUseCase(
user_repository=self.user_repository,
)
# ==================== Workspace Use Cases ====================
def get_create_workspace_use_case(self) -> CreateWorkspaceUseCase:
return CreateWorkspaceUseCase(
workspace_repository=self.workspace_repository,
workspace_member_repository=self.workspace_member_repository,
user_repository=self.user_repository,
)
def get_invite_member_use_case(self) -> InviteMemberUseCase:
return InviteMemberUseCase(
workspace_repository=self.workspace_repository,
workspace_member_repository=self.workspace_member_repository,
workspace_invitation_repository=self.workspace_invitation_repository,
user_repository=self.user_repository,
base_url="http://localhost:3000",
)
def get_accept_invitation_use_case(self) -> AcceptInvitationUseCase:
return AcceptInvitationUseCase(
workspace_repository=self.workspace_repository,
workspace_member_repository=self.workspace_member_repository,
workspace_invitation_repository=self.workspace_invitation_repository,
user_repository=self.user_repository,
)
def get_decline_invitation_use_case(self) -> DeclineInvitationUseCase:
return DeclineInvitationUseCase(
workspace_invitation_repository=self.workspace_invitation_repository,
)
def get_remove_member_use_case(self) -> RemoveMemberUseCase:
return RemoveMemberUseCase(
workspace_repository=self.workspace_repository,
workspace_member_repository=self.workspace_member_repository,
)
def get_leave_workspace_use_case(self) -> LeaveWorkspaceUseCase:
return LeaveWorkspaceUseCase(
workspace_repository=self.workspace_repository,
workspace_member_repository=self.workspace_member_repository,
)
def get_update_member_role_use_case(self) -> UpdateMemberRoleUseCase:
return UpdateMemberRoleUseCase(
workspace_repository=self.workspace_repository,
workspace_member_repository=self.workspace_member_repository,
)
def get_list_workspaces_use_case(self) -> ListWorkspacesUseCase:
return ListWorkspacesUseCase(
workspace_repository=self.workspace_repository,
workspace_member_repository=self.workspace_member_repository,
)
def get_get_workspace_detail_use_case(self) -> GetWorkspaceDetailUseCase:
return GetWorkspaceDetailUseCase(
workspace_repository=self.workspace_repository,
workspace_member_repository=self.workspace_member_repository,
)
def get_list_members_use_case(self) -> ListMembersUseCase:
return ListMembersUseCase(
workspace_repository=self.workspace_repository,
workspace_member_repository=self.workspace_member_repository,
user_repository=self.user_repository,
)
def get_upgrade_subscription_use_case(self) -> UpgradeSubscriptionUseCase:
return UpgradeSubscriptionUseCase(
workspace_repository=self.workspace_repository,
workspace_member_repository=self.workspace_member_repository,
)
def get_cancel_subscription_use_case(self) -> CancelSubscriptionUseCase:
return CancelSubscriptionUseCase(
workspace_repository=self.workspace_repository,
workspace_member_repository=self.workspace_member_repository,
)
# 全局容器实例
_container = None
def get_container() -> DependencyContainer:
"""获取全局依赖容器"""
global _container
if _container is None:
_container = DependencyContainer()
return _container